0

Ok so ive tried to start a programming a Code Injection program for windows written in C (in Visual Studio) and ive been having trouble when getting instructions to execute cause of something to do with windows weird execution environment. So anyways ive narrowed my project down to just getting custom code to execute.

Here is a simple function I took and compiled in both Windows Vis Studio and Mac OS Xcode

int addNumbers(int a1,int a2) {
    return a1+a2;
}

Now Xcode on Mac OS Compiled this nice and simply as this (disassembled with Hopper v4)

push rbp
mov  rbp, rsp
mov  dword [rbp+var_4],edi
mov  dword [rbp+var_8],esi
mov  esi, dword [rbp+var_4]
add  esi, dword [rbp+var_8]
mov eax, esi
pop rbp
ret
// 55 48 89 E5 89 7D FC 89 75 F8 8B 75 FC 03 75 F8 89 F0 5D C3

But then compiling on windows gives all this bloat (disassembled with IDA Pro 7.0)

mov     [rsp-8+arg_8], edx
mov     [rsp-8+arg_0], ecx
push    rbp
push    rdi
sub     rsp, 0E8h
lea     rbp, [rsp+20h]
mov     rdi, rsp
mov     ecx, 3Ah
mov     eax, 0CCCCCCCCh
rep stosd
mov     ecx, [rsp+0F0h+arg_8]
lea     rcx, unk_140025022
call    sub_140011442         // This calls some random function that returns the result of GetCurrentThreadId();
mov     eax, [rbp+0D0h+arg_8]
mov     ecx, [rbp+0D0h+arg_0]
add     ecx, eax
mov     eax, ecx
lea     rsp, [rbp+0C8h]
pop     rdi
pop     rbp
retn
// 89 54 24 10 89 4C 24 08 55 57 48 81 EC E8 00 00 00 48 8D 6C 24 20 48 8B FC B9 3A 00 00 00 B8 CC CC CC CC F3 AB 8B 8C 24 08 01 00 00 48 8D 0D BF 28 01 00 E8 DA EC FF FF 8B 85 E8 00 00 00 8B 8D E0 00 00 00 03 C8 8B C1 48 8D A5 C8 00 00 00 5F 5D C3

So I went and used the simple Mac OS Compiled Instructions in my test execution function (due to the problem that with the windows one for some reason has a call instruction in it and I cant have it calling external addresses at the moment)

char funcIS[] = { 0x55, 0x48, 0x89, 0xE5, 0x89, 0x7D, 0xFC, 0x89, 0x75, 0xF8, 0x8B, 0x75, 0xFC, 0x03, 0x75, 0xF8, 0x89, 0xF0, 0x5D, 0xC3 }; // Function Instruction Set

char *executableMemory = VirtualAlloc(0,sizeof(funcIS),MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(executableMemory,funcIS,sizeof(funcIS));

int (_stdcall *func)(int arg1,int arg2) = (void*)executableMemory;
log("Calling Function at 0x%p",func);
log("Result = %d",func(1,5));

Anyways when calling func() I dont get a crash thankfully but it also returns some random nonsense number everytime like -193820424 or 42345892. Now my guess is it has something to do with the way window compiler handles passing arguments and return values between functions which I did try adding _stdcall to the function but that didn't change anything.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
YeaTheMans
  • 1,005
  • 8
  • 19
  • Seems like you compiled a Debug configuration in windows, thus the bloated code. Try a Release build. – nevilad Feb 20 '21 at 10:37
  • Ok thanks ill give it a shot – YeaTheMans Feb 20 '21 at 10:38
  • Your MacOS code seems to read arguments in edi and esi registers. But stdcall used rcx and rdx for the first two integer args. – nevilad Feb 20 '21 at 10:44
  • @nevilad: Windows x64 calls its calling convention "fastcall", if anything, not stdcall. But yes, it's different from x86-64 System V (which every other OS uses), RCX, RDX, R8, R9 instead of RDI, RSI, RDX, RCX, R8, R9, among other differences. And of course both asm versions are laughably verbose, not the `lea eax, [rdi + rsi]` / `ret` (or RCX+RDX on Windows) you'd get with optimization enabled. – Peter Cordes Feb 20 '21 at 10:47
  • For this to work with that machine code, you'd need GNU C `__attribute__((sysv_abi))` which MSVC doesn't support or AFAIK have any equivalent for. – Peter Cordes Feb 20 '21 at 10:54
  • ok well ill look into tryna rewrite the instructions and registers to suite the windows standards – YeaTheMans Feb 20 '21 at 11:05

0 Answers0