HELP: X64 HOOK ERROR(call 64bits address)

Started by enoloo, July 30, 2007, 08:39:08 AM

Previous topic - Next topic

enoloo

I want to hook some function; such as calling 'myFunction' would calling 'myFarFarFunction' first and then 'myFunction'. But my trouble is that the program crashed after leaving the function 'myFarFarFunction'.

My program contains 2 projects, one is dll(include 'myFunction'), the other test_call(include 'myFarFarFunction').

The dll project codes blow:
__declspec(dllexport) int myFunction(int param)
{
   cout << "myFunction with param " << param << endl;
   return param;
}

// trampoline buffer
BYTE bytesTrampoline[128];

__declspec(dllexport) LPVOID TrampolineAddr()
{
   return bytesTrampoline;
}

enoloo

#1
Test_call project codes blow:

// jmp instruction (with 32 bites address)
BYTE bytesJmp[] = { 0xE9 };
// call instruction (with 64 bits address)
BYTE bytesCall[] = { 0xFF, 0x15, 0x00, 0x00, 0x00, 0x00};

typedef int (* myFunction)(int param);
typedef PVOID (* TrampolineAddr)();

__declspec(noinline) int myFarFarFunction(int param)
{
   cout << "myFarFarFunction with param " << param << endl;
   return param;
}

int _tmain(int argc, _TCHAR* argv[])
{
   LONG_PTR addrFarFarFunction = (LONG_PTR)myFarFarFunction;

   LONG_PTR addrMyFunction = 0;
   TrampolineAddr addrTrampolineAddr = NULL;
   PBYTE bytesTrampoline = NULL;

   HMODULE hMod = LoadLibraryW(L"dll.dll"); // load target dll to hook myFunction
   
   if (hMod)
   {
      addrMyFunction = (LONG_PTR)GetProcAddress(hMod, "myFunction");
      addrTrampolineAddr = (TrampolineAddr)GetProcAddress(hMod, "TrampolineAddr");
      if (addrTrampolineAddr)
         bytesTrampoline = (PBYTE)(addrTrampolineAddr());
   }

   if (!addrMyFunction || !bytesTrampoline)
   {
      cout << "load target dll error." << endl;
      return 0x1ff;
   }

   ((myFunction)addrMyFunction)(5); // output the result before hooked.

   DWORD dwProtect, dwOffset, dwTmp;
   BOOL bSuccess = FALSE;
   LONG lTmp;

   // jmp to the trampoline in the entry of myFuntion.
   bSuccess = VirtualProtect((LPVOID)addrMyFunction, 5, PAGE_READWRITE, &dwProtect);
   dwOffset = 0;
   memcpy((LPVOID)(addrMyFunction+dwOffset), bytesJmp, sizeof(bytesJmp));
   dwOffset += sizeof(bytesJmp);
   lTmp = (LONG)((LONG_PTR)bytesTrampoline-(addrMyFunction+dwOffset+4));
   memcpy((PVOID)(addrMyFunction+dwOffset), &lTmp, 4);
   bSuccess = VirtualProtect((LPVOID)addrMyFunction, 5, dwProtect, &dwTmp);

   // make a trampoline for myFunction & myFarFarFunction
   dwOffset = 0;
   memcpy(bytesTrampoline+dwOffset, bytesCall, sizeof(bytesCall)); // call myFarFarFunction
   dwOffset += sizeof(bytesCall);
   memcpy(bytesTrampoline+dwOffset, &addrFarFarFunction, sizeof(addrFarFarFunction));
   dwOffset += sizeof(addrFarFarFunction);
   memcpy(bytesTrampoline+dwOffset, (PVOID)addrMyFunction, 5); // myFunction's first 5 byte instructions
   dwOffset += 5;
   memcpy(bytesTrampoline+dwOffset, bytesJmp, sizeof(bytesJmp)); // jmp myFunction
   dwOffset += sizeof(bytesJmp);
   lTmp = (LONG)(addrMyFunction - (LONG_PTR)(bytesTrampoline+dwOffset) - 4);
   memcpy(bytesTrampoline+dwOffset, &lTmp, 4);
   bSuccess = VirtualProtect((LPVOID)bytesTrampoline, 128, PAGE_EXECUTE, &dwProtect);

   // active the hook
   ((myFunction)addrMyFunction)(5); //output the result after hooked. --> crashed after myFarFarFunction!!

   // do something else
   for (int i = 0; i < 2; i++)
      cout << "do somethings else." << endl;
   
   return 0;
}


enoloo

#2
00000000100045C0 FF 15 00 00 00 00 call        qword ptr [100045C6h]  ; ERROR here call 64bits address, but RIP offset only 32 bits!00000000100045C6 10 1F            adc         byte ptr [rdi],bl
00000000100045C8 40 00 00         add         byte ptr [rax],al
00000000100045CB 00 00            add         byte ptr [rax],al
00000000100045CD 00 E9            add         cl,ch
00000000100045CF 5B               pop         rbx 
00000000100045D0 25 00 00 E9 88   and         eax,88E90000h

Is the call-instruction for 64bits error?

Thank you.

evlncrn8

it might be right calling, however its going to ret into crap...

00000000100045C0 FF 15 00 00 00 00 call        qword ptr [100045C6h] ; ptr should be right, it should contain 8 byte rva , and its going to ret to 100045C8
00000000100045C8 40 00 00         add         byte ptr [rax],al
00000000100045CB 00 00            add         byte ptr [rax],al
00000000100045CD 00 E9            add         cl,ch
00000000100045CF 5B               pop         rbx
00000000100045D0 25 00 00 E9 88   and         eax,88E90000h

so i think the problem might be where its returning to.....

enoloo

#4
Thanks. It looks like that RIP points to the increct instruction position after call(ff/2). How to use the call-instruction (ff/2) for 64bits address?

The calling Frame blow:

myFunction: 0xe9[Trampoline(32bits)] -->
Trampoline: 0xff1500000000[myFarFarFunction(64bits)] -->
Trampoline: the head 5 bytes of myFunction --> (Crashed!!)
Trampoline: 0xe9[myFunction(offset 5 bytes)] -->
myFunction: 5 bytes offset the myFunction

Note that on the crashed point:
00000000100045C0 FF 15 00 00 00 00 call        qword ptr [100045C6h]  ; ERROR here call 64bits address, but RIP offset only 32 bits!00000000100045C6 10 1F            adc         byte ptr [rdi],bl
00000000100045C8 40 00 00         add         byte ptr [rax],al
00000000100045CB 00 00            add         byte ptr [rax],al
00000000100045CD 00 E9            add         cl,ch
00000000100045CF 5B               pop         rbx 
00000000100045D0 25 00 00 E9 88   and         eax,88E90000h

But the meaning I want is:
00000000100045C0 FF 15 00 00 00 00 10 1F 40 00 00 00 00 00 call  0x101f400000000000   
00000000100045CE E9 5B 25 00 00 jmp ...


enoloo

Here is my program in the accessory.

[attachment deleted by admin]

P1

enoloo,

Welcome   :U

Obvious statement:  This is 64bit C program, and not a 64 bit assembler program.

M$ has pretty much, made 64 bit assembler program brain dead for us to use.

With that said, why are you not on a C programming website getting help for this there?

I ask this because, AFAIK, there are no assembler resources to effect change for your code, to get a working program.

The last question is:  This has the feel of homework to it, if it is, you have resources through your school to get help.

I googled several hits(151,000) for Visual C Hooks for x64.  Start with a working example and complete your coding project that way.

Regards,  P1   :8)