5

well i want to create a detour to my custom injected function so a code like that works

void *DetourCreate(BYTE *src, const BYTE *dst)
{
    int len = 5;
    BYTE* jmp = (BYTE*)malloc(len + 5);
    DWORD dwBack;
    VirtualProtect(src, len, PAGE_EXECUTE_READWRITE, &dwBack);
    memcpy(jmp, src, len);
    jmp += len;
    jmp[0] = 0xE9;
    *(DWORD*)(jmp + 1) = (DWORD)(src + len - jmp) - 5;
    src[0] = 0xE9;
    *(DWORD*)(src + 1) = (DWORD)(dst - src) - 5;
    VirtualProtect(src, len, dwBack, &dwBack);
    return(jmp - len);
}

but i find it irritating to use opcodes so is there a way to use __asm instead ? like this pseudo code for instance

void DetourCreate(byte *src, const byte *dst)
{
    DWORD dwBack;
    VirtualProtect(src, sizeof(*dst), PAGE_EXECUTE_READWRITE, &dwBack);
    *src = __asm{
        call dst
    };
    VirtualProtect(src, sizeof(*dst), dwBack, &dwBack);
}
Daniel Eugen
  • 2,712
  • 8
  • 33
  • 56
  • In VS, maybe a (sort-of) function with `__declspec naked` will help you. – deviantfan Jan 29 '15 at 01:43
  • @deviantfan The [GCC equivalent](https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html) is `__attribute__(naked)`. My guess is that it should be the same in **clang** which is mostly compatible with GCC attributes, if I'm not mistaken. See [this FreeRTOS link](http://www.freertos.org/implementation/a00013.html) for an embedded programmers view of why you need this attribute. – nonsensickle Jan 29 '15 at 01:53
  • @nonsensickle; Does NOT always work in GCC.. I know because I asked a question before on this: http://stackoverflow.com/questions/19577809/gcc-inlined-assembly-jmp-address-naked-functions GCC `ignores` the "naked" attribute. Personally I use this: https://defuse.ca/online-x86-assembler.htm to convert ASM to bytes.. – Brandon Jan 29 '15 at 01:58
  • Well, non of this actually helps guys... – Daniel Eugen Jan 29 '15 at 02:39
  • https://msdn.microsoft.com/en-us/library/bf1dw62z.aspx .. might that help? – txtechhelp Jan 29 '15 at 04:09
  • @DanielEugen Why not, exactly? – deviantfan Jan 29 '15 at 13:46
  • I want to convert the inline assembly into a byte in order to replace a memory address with the instruction in it. (instead of using opcodes) – Daniel Eugen Jan 29 '15 at 16:50
  • @Brandon I assure you that they do work. I have posted an additional answer to your question which will hopefully clear up any confusion. You shouldn't use the `__declspec(naked)` syntax in GCC, I have always used `__attribute__((naked))` at the end of a function and it works. Also, the links I provided prove that it does work, whilst your comment merely proves you did not read what I linked. – nonsensickle Feb 04 '15 at 00:00
  • @nonsensickle I can't tell if you're joking or not.. http://i.imgur.com/IfZsecR.png and http://i.imgur.com/hIzpIsW.png Do you see that? GCC 4.9.2 – Brandon Feb 09 '15 at 23:33
  • 1
    @Brandon I retract that statement. They work but [not on x86](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25967). I use them a lot on embedded ARM and hence the confusion. Bah, stupid GCC... [Maybe clang will work](http://clang-developers.42468.n3.nabble.com/naked-attribute-td4031883.html)? – nonsensickle Feb 10 '15 at 00:41

1 Answers1

0

To convert inline assembly to the corresponding bytes, you can write your assembly inside of a __declspec(naked) function and use WriteProcessMemory to write data into the external process, using the inline assembly function as the source.

Here is an example that Writes from the assembly into a local buffer:

__declspec(naked) int assembly()
{
    __asm
    {
        push eax;   // \x50
        mov eax, 1; // \xB8 \x01\x00\x00\x00
        pop eax;    // \x58
    }
}

int main()
{
    unsigned char buffer[7] = { 0 };

    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, NULL, GetCurrentProcessId());
    WriteProcessMemory(hProc, &buffer, &assembly, 7, NULL);

    for (auto c : buffer)
    {
        printf("0x%hhX ", c);
    }

    std::getchar();

    return 0;
}

We use declspec to make sure no function prologue/epilogue gets in our way. The output is just for this proof of concept and will read: 0x50 0xB8 0x1 0x0 0x0 0x0 0x58

Should be simple enough to Write to a target process using this technique.

Using the Capstone disassembler is the ultimate solution if you find yourself doing this often, it's very easy to use.

GuidedHacking
  • 3,628
  • 1
  • 9
  • 59