Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Why does my dll print me wrong address?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
rain-13
Expert Cheater
Reputation: 0

Joined: 18 Mar 2009
Posts: 110

PostPosted: Wed Jul 01, 2015 5:31 am    Post subject: Why does my dll print me wrong address? Reply with quote

Hello.


I have question about dll. I am trying to hook x64 application.

Here's my DLL source:
Code:
#include <windows.h>
#include <stdio.h>

#define SIZE 16

typedef int (WINAPI *pMessageBoxW)(HWND, LPCWSTR, LPCWSTR, UINT);
int WINAPI MyMessageBoxW(HWND, LPCWSTR, LPCWSTR, UINT);

void BeginRedirect(LPVOID);

pMessageBoxW pOrigMBAddress = NULL;
BYTE oldBytes[SIZE] = {0};
BYTE JMP[SIZE] = {0};
DWORD oldProtect, myProtect = PAGE_EXECUTE_READWRITE;

INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
    switch(Reason)
    {
    case DLL_PROCESS_ATTACH:
      printf("attached\n");
        pOrigMBAddress = (pMessageBoxW)
            GetProcAddress(GetModuleHandle(L"user32.dll"),
                           "MessageBoxW");
        if(pOrigMBAddress != NULL){
            BeginRedirect(MyMessageBoxW);   
         printf("Address: %llX %llX\n",MyMessageBoxW, &MyMessageBoxW);
      }
        break;
    case DLL_PROCESS_DETACH:
      printf("de-attached\n");
        memcpy(pOrigMBAddress, oldBytes, SIZE);
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

void BeginRedirect(LPVOID newFunction)
{
   BYTE tempJMP[SIZE] = {0x50, 0x48, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x48, 0x87, 0x04, 0x24, 0xC3};
    memcpy(JMP, tempJMP, SIZE);
    //DWORD JMPSize = ((DWORD)newFunction - (DWORD)pOrigMBAddress - 5);
    VirtualProtect((LPVOID)pOrigMBAddress, SIZE,
                    PAGE_EXECUTE_READWRITE, &oldProtect);
    memcpy(oldBytes, pOrigMBAddress, SIZE);
    memcpy(&JMP[3], newFunction, 8);
    memcpy(pOrigMBAddress, JMP, SIZE);
    VirtualProtect((LPVOID)pOrigMBAddress, SIZE, oldProtect, NULL);
}

int  WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uiType)
{
    VirtualProtect((LPVOID)pOrigMBAddress, SIZE, myProtect, NULL);
    memcpy(pOrigMBAddress, oldBytes, SIZE);
    int retValue = MessageBoxW(hWnd, lpText, lpCaption, uiType);
    memcpy(pOrigMBAddress, JMP, SIZE);
    VirtualProtect((LPVOID)pOrigMBAddress, SIZE, oldProtect, NULL);
    return retValue;
}


And when I inject it, this is what I get:


Any ideas how to fix it? CE's address is right, but mine is wrong.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 471

Joined: 09 May 2003
Posts: 25818
Location: The netherlands

PostPosted: Wed Jul 01, 2015 5:36 am    Post subject: Reply with quote

look at both addresses in the disassembler. Perhaps one of them is a jmp (try building in release mode without debugging or extra security checks)
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
rain-13
Expert Cheater
Reputation: 0

Joined: 18 Mar 2009
Posts: 110

PostPosted: Wed Jul 01, 2015 7:11 am    Post subject: Reply with quote

Quote:
look at both addresses in the disassembler.

How do I look these? Isnt CE already disassembler? Do I need to look these in somewhere else than CE?

Here's address that I see from console:


And here's address that CE gives me:


Any ideas what's first one? And why I see this address from console window?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 471

Joined: 09 May 2003
Posts: 25818
Location: The netherlands

PostPosted: Wed Jul 01, 2015 8:06 am    Post subject: Reply with quote

those jmp's are used by visual studie for hotpatching so you can edit a function without restarting

anyhow, it won't effect the result of your hook

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
rain-13
Expert Cheater
Reputation: 0

Joined: 18 Mar 2009
Posts: 110

PostPosted: Wed Jul 01, 2015 12:22 pm    Post subject: Reply with quote

I figured that when I compiled it in release mode, it pointed to "right" address.

Quote:
anyhow, it won't effect the result of your hook

Do you mean that both addresses would work?

Btw do you know why does my app that I hook crash when it calls hooked function:

Code:
#include <windows.h>
#include <stdio.h>

#define SIZE 16

typedef int (WINAPI *pMessageBoxW)(HWND, LPCWSTR, LPCWSTR, UINT);
int WINAPI MyMessageBoxW(HWND, LPCWSTR, LPCWSTR, UINT);

void BeginRedirect(LPVOID);

pMessageBoxW pOrigMBAddress = NULL;
BYTE oldBytes[SIZE] = {0};
BYTE JMP[SIZE] = {0};
DWORD oldProtect, myProtect = PAGE_EXECUTE_READWRITE;

INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
    switch(Reason)
    {
    case DLL_PROCESS_ATTACH:
      printf("attached\n");
        pOrigMBAddress = (pMessageBoxW)
            GetProcAddress(GetModuleHandle(L"user32.dll"),
                           "MessageBoxW");
        if(pOrigMBAddress != NULL){
            BeginRedirect(MyMessageBoxW);   
         printf("Address: %llX %llX\n",MyMessageBoxW, &MyMessageBoxW);
      }
        break;
    case DLL_PROCESS_DETACH:
      printf("de-attached\n");
        memcpy(pOrigMBAddress, oldBytes, SIZE);
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

void BeginRedirect(LPVOID newFunction)
{
   BYTE tempJMP[SIZE] = {0x50, 0x48, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFF, 0xE0, 0x90, 0x90, 0xC3};
    memcpy(JMP, tempJMP, SIZE);
    //DWORD JMPSize = ((DWORD)newFunction - (DWORD)pOrigMBAddress - 5);
    VirtualProtect((LPVOID)pOrigMBAddress, SIZE,
                    PAGE_EXECUTE_READWRITE, &oldProtect);
    memcpy(oldBytes, pOrigMBAddress, SIZE);

    memcpy(&JMP[3], &newFunction, 8);
    memcpy(pOrigMBAddress, JMP, SIZE);
    VirtualProtect((LPVOID)pOrigMBAddress, SIZE, oldProtect, NULL);
}

int  WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uiType)
{
    VirtualProtect((LPVOID)pOrigMBAddress, SIZE, myProtect, NULL);
    memcpy(pOrigMBAddress, oldBytes, SIZE);
   printf("calling MBW from hook");
    int retValue = MessageBoxW(hWnd, L"Hooked", lpCaption, uiType);
   printf("called MBW from hook");
    memcpy(pOrigMBAddress, JMP, SIZE);
    VirtualProtect((LPVOID)pOrigMBAddress, SIZE, oldProtect, NULL);
    return retValue;
}


The first printf prints and then when calling MBW, it crashes. I think, it has something to do with fact that I overwrite rax, but I dont know how to restore it since inside the hook this code un-hooks it before calling mbw, so wouldnt any rax restoring opcodes be useless?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 471

Joined: 09 May 2003
Posts: 25818
Location: The netherlands

PostPosted: Thu Jul 02, 2015 4:52 pm    Post subject: Reply with quote

your jump code does a push rax followed by jumping to that value.
By pushing such a value you'll cause the stack to be unaligned which will cause issues for certain instructions.
Also, because you don't seem to pop it off the stack, you'll have stack corruption

try this as code jumper instead:
0xff,0x25,0x00,0x00,0x00,0x00, 0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc
and place the destination address at index 6 (memcpy(&JMP[6], &newFunction, 8); )


Also, this hooking method will not work well when used with multiple threads

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
rain-13
Expert Cheater
Reputation: 0

Joined: 18 Mar 2009
Posts: 110

PostPosted: Fri Jul 03, 2015 2:50 pm    Post subject: Tnx Reply with quote

Thank you for that asm code. It worked. Could you tell me the meaning and idea of it?

Whats those 0x00s about? And does CE mistaken this address to code? because right after jmp it has some asm that I dont understand.



Other question is that why does command olne window show me 7FEF... but CE shows completely different bytes?

And how to understand this:
qword ptr [User32.MessageBoxW+6] ?
And how does CE know to write APIHook.MyMes... as a comment? with previous code , it would have written APIHook.MyMessageBoxW in green.

I am very thankful for your code, I just want to learn to know how it works.

And finally, what what would I have to to if I want to hook it in multi threaded programs? Would it work with functions that doesnt wait for user input? For example, if I would hook printf which returns almost immediately, would I have problems? Because it would be unlikely that an other thread is going to call it while my hook is still doing it's work.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 471

Joined: 09 May 2003
Posts: 25818
Location: The netherlands

PostPosted: Fri Jul 03, 2015 3:53 pm    Post subject: Reply with quote

0xff,0x25,0x00,0x00,0x00,0x00 is JMP [RIP+0]

it takes the value of the instruction at RIP and jumps to there. (RIP is the value after the instruction is executed, which is why it's RIP+0 and not RIP+6)

Quote:

qword ptr [User32.MessageBoxW+6]

That's just how CE interprets the bytes.
The instruction is at USER32.MessageBoxW+0000, and RIP+0 is at User32.MessageBoxW+0006

Quote:

And finally, what what would I have to to if I want to hook it in multi threaded programs? Would it work with functions that doesnt wait for user input? For example, if I would hook printf which returns almost immediately, would I have problems? Because it would be unlikely that an other thread is going to call it while my hook is still doing it's work.

It depends on the function. If there are multiple threads that call that function there is a possibility that thread 1 will try to execute the code after the original code has been put back, making you miss the call

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
rain-13
Expert Cheater
Reputation: 0

Joined: 18 Mar 2009
Posts: 110

PostPosted: Sat Jul 04, 2015 12:56 pm    Post subject: Reply with quote

Thanks, is there any easy way to make it thread safe or would attempting it be too difficult?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 471

Joined: 09 May 2003
Posts: 25818
Location: The netherlands

PostPosted: Sat Jul 04, 2015 2:03 pm    Post subject: Reply with quote

write a stub that you can call to call the original function.
It will involve dissembling the code you're replacing and adjusting offsets where necessary

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
rain-13
Expert Cheater
Reputation: 0

Joined: 18 Mar 2009
Posts: 110

PostPosted: Sun Jul 05, 2015 7:42 am    Post subject: Reply with quote

Tnx.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites