-
Notifications
You must be signed in to change notification settings - Fork 86
Assembly Attribute
Aman Priyadarshi edited this page Dec 23, 2016
·
7 revisions
An Attribute which declares a method to emit literal assembly code.
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public class AssemblyAttribute : Attribute> { public readonly bool CalliHeader; public AssemblyAttribute(bool requiredCallingHeader = false) { ... } }
- CalliHeader
- Tells Compiler to emit calli assembly stubs.
- Follows
__stdcall
calling convention.- Default Value: false
- Declaration
using Atomixilc.Machine; using Atomixilc.Attributes; using Atomixilc.Machine.x86; ... [Assembly] internal static int Random() { // Do Something }
- To Enable
__stdcall
calli stubs use[Assembly(true)]
.- Method Body
- Assembly Methods are directly invoked by the Compiler.
- Directly invocation causes no direct link to non-Assembly stuffs.
- Like It is impossible to refer parameters/fields/functions directly.
- Assembly Instruction can be added by creating an instance of required instruction.
- Example - (CalliHeader = false)
- C# code
void Test()
[Assembly] internal static int Test() { new Cli(); // clear interrupts // push ESP register onto the stack new Push { DestinationReg = Register.ESP }; new Sti(); // store interrupts }
- Generated code
cli push dword ESP sti
- Example - (CalliHeader = true)
- C# code
[Assembly(true)] internal static int Test() { new Cli(); // clear interrupts // push ESP register onto the stack new Push { DestinationReg = Register.ESP }; new Sti(); // store interrupts }
- Generated code
push dword EBP mov dword EBP, ESP cli push dword ESP sti xor dword ECX, ECX leave ret 0x0
- CalliHeader = false
- Return value should be saved in
EAX
register.- Make sure you clear
ECX
register before exiting. (Read: Exceptions)- You can use NoException Attribute if does not want to clear
ECX
register.- Last Argument:
[ESP + 0x4]
(ESP: Initial Stack Position)- Second Last Argument:
[ESP + 0x4 + sizeof(Last Argument)]
and so on
- CalliHeader = true
- Return value should be pushed onto the stack.
- Last Argument:
[EBP + 0x8]
- Second Last Argument:
[EBP + 0x8 + sizeof(Last Argument)]
and so on
- DestinationSourceSize
Mnemonic
SIZE
DES
,SRC
- SIZE (bytes) = {
BYTE (8)
,WORD (16)
,DWORD (32 default)
,QWORD (64)
}- DES/SRC = {
Register Reference
,Memory Reference
} + {Displacement
,Indirect
}
- DestinationSource
Mnemonic
DES
,SRC
- DestinationOnly
Mnemonic
DES
- OnlySize
Mnemonic
SIZE
- Return Sum of Two Numbers
[Assembly(true)] internal static int Sum(int A, int B) { // mov eax, [ebp+0x8] ; mov eax, B new Mov { DestinationReg = Register.EAX, SourceReg = Register.EBP, SourceDisplacement = 0x8, SourceIndirect = true }; // mov ebx, [ebp+0xc] ; mov ebx, A new Mov { DestinationReg = Register.EBX, SourceReg = Register.EBP, SourceDisplacement = 0xC, SourceIndirect = true }; // add eax, ebx new Add { DestinationReg = Register.EAX, SourceReg = Register.EBX }; new Push { DestinationReg = Register.EAX }; }