Support for Windows 8

c++ / delphi package - dll injection and api hooking
Davita
Posts: 163
Joined: Tue Sep 13, 2005 7:31 pm

Re: Support for Windows 8

Post by Davita »

No, unfortunately I don't have source code :(. BTW, doesn't madCodeHook compiles with express edition? If not, I'll be happy to recompile using my VS 2012 if you provide me with source codes.
immer000
Posts: 22
Joined: Tue Sep 04, 2012 12:05 am

Re: Support for Windows 8

Post by immer000 »

I tried rebuilding from source with VS2012.

First there were some compile errors as the following structures are now exposed in winnt.h :

struct _EXCEPTION_REGISTRATION_RECORD
struct _WOW64_FLOATING_SAVE_AREA
struct _WOW64_CONTEXT
and #define WOW64_CONTEXT_SEGMENTS

The structures do match (thankfully !) so I just commented out the definitions from ProcessTypes.h and FunctionTypes.h. It then compiled fine in both 32 and 64 bit flavors.

That is the MainTest.exe output on 32 bit (OS is 64 bit) :

Code: Select all

TestAllocEx: Testing AllocMemEx(), FreeMemEx()
  SUCCESS

TestProtect: Testing ProtectMemory(), UnprotectMemory(), IsMemoryProtected()
  SUCCESS

TestCopyFunction: Testing CopyFunction()
  SUCCESS

TestHandleLiveForever: Testing HandleLiveForever()
  FAILURE - HandleLiveForever()

TestHandleLiveForeverCode: Testing HandleLiveForever()
  FAILURE - GetSmssProcessHandle()

  FAILURE - Unable to Create map file within 100 interations

TestHandleLiveForeverWithProcess: Testing HandleLiveForever(), ProcessHandleToId()
  FAILURE - GetSmssProcessHandle()

TestRemoteExecute: Testing RemoteExecute()
  FAILURE - RemoteExecute()

TestHooking: Testing HookAPI(0) and Unhook()
  SUCCESS

TestSafeHooking: Testing HookAPI(SAFE_HOOKING) and Unhook()
  SUCCESS

TestNoSafeUnhooking: Testing HookAPI(NO_SAFE_UNHOOKING) and Unhook()
  SUCCESS

TestMixtureModeHooking: Testing HookAPI(MIXTURE_MODE) and Unhook()
  SUCCESS

TestImportExportTablePatching: Testing Import/Export Table Patching
  SUCCESS

TestInUse: Testing Hooking and InUse protection
  SUCCESS

TestInjection: Testing Injection (on our own process)
  FAILURE - injection failed

TestIpc: Testing IPC functions
NtCreatePort succeeded
LpcPortThread: Got message from client
LpcPortThread: Accepting connection request
LpcPortThread: Completing connection request
SendIpcMessage: NtConnectPort complete
LpcPortThread: Got message from client
SendIpcMessage: *** LpcPortThread did not fill in the process ID
*** SendIpcMessage: ProcessID was not filled in by server
InitIpcAnswer: Creating Answer file mapping.  name=IpcTestAnswerBuf21$1060
LpcPortThread: Got message from client
LpcPortThread: Accepting connection request
LpcPortThread: Completing connection request
InitIpcAnswer: Opening existing answer file mapping.  name=IpcTestAnswerBuf21$1060
SendIpcMessage: NtConnectPort complete
LpcPortThread: Got message from client
LpcPortThread: Got message from client
LpcPortThread: Rejecting connection request because queue is shutting down
*** NtConnectPort failed with return code C0000041.  Error is "The NtConnectPort request is refused." (STATUS_PORT_CONNECTION_REFUSED)
NtCreatePort succeeded
LpcPortThread: Got message from client
LpcPortThread: Accepting connection request
LpcPortThread: Completing connection request
SendIpcMessage: NtConnectPort complete
LpcPortThread: Got message from client
SendIpcMessage: *** LpcPortThread did not fill in the process ID
*** SendIpcMessage: ProcessID was not filled in by server
InitIpcAnswer: Creating Answer file mapping.  name=IpcTestAnswerBuf23$1060
LpcPortThread: Got message from client
LpcPortThread: Accepting connection request
LpcPortThread: Completing connection request
InitIpcAnswer: Opening existing answer file mapping.  name=IpcTestAnswerBuf23$1060
SendIpcMessage: NtConnectPort complete
LpcPortThread: Got message from client
InitIpcAnswer: Creating Answer file mapping.  name=IpcTestAnswerBuf24$1060
LpcPortThread: Got message from client
LpcPortThread: Accepting connection request
LpcPortThread: Completing connection request
InitIpcAnswer: Opening existing answer file mapping.  name=IpcTestAnswerBuf24$1060
SendIpcMessage: NtConnectPort complete
LpcPortThread: Got message from client
InitIpcAnswer: Creating Answer file mapping.  name=IpcTestAnswerBuf25$1060
LpcPortThread: Got message from client
LpcPortThread: Accepting connection request
LpcPortThread: Completing connection request
SendIpcMessage: NtConnectPort complete
InitIpcAnswer: Opening existing answer file mapping.  name=IpcTestAnswerBuf25$1060
LpcPortThread: Got message from client
LpcPortThread: Got message from client
LpcPortThread: Rejecting connection request because queue is shutting down
*** NtConnectPort failed with return code C0000041.  Error is "The NtConnectPort request is refused." (STATUS_PORT_CONNECTION_REFUSED)
  SUCCESS
The 64 bit one deadlocks on the IPC tests :

Code: Select all

TestAllocEx: Testing AllocMemEx(), FreeMemEx()
  SUCCESS

TestProtect: Testing ProtectMemory(), UnprotectMemory(), IsMemoryProtected()
  SUCCESS

TestCopyFunction: Testing CopyFunction()
  SUCCESS

TestHandleLiveForever: Testing HandleLiveForever()
  FAILURE - HandleLiveForever()

TestHandleLiveForeverCode: Testing HandleLiveForever()
  FAILURE - GetSmssProcessHandle()

  FAILURE - Unable to Create map file within 100 interations

TestHandleLiveForeverWithProcess: Testing HandleLiveForever(), ProcessHandleToId()
  FAILURE - GetSmssProcessHandle()

TestRemoteExecute: Testing RemoteExecute()
  SUCCESS

TestHooking: Testing HookAPI(0) and Unhook()
  SUCCESS

TestSafeHooking: Testing HookAPI(SAFE_HOOKING) and Unhook()
  SUCCESS

TestNoSafeUnhooking: Testing HookAPI(NO_SAFE_UNHOOKING) and Unhook()
  SUCCESS

TestMixtureModeHooking: Testing HookAPI(MIXTURE_MODE) and Unhook()
  SUCCESS

TestImportExportTablePatching: Testing Import/Export Table Patching
  SUCCESS

TestInUse: Testing Hooking and InUse protection
  SUCCESS

TestInjection: Testing Injection (on our own process)
  FAILURE - injection failed

TestIpc: Testing IPC functions
NtCreatePort succeeded
LpcPortThread: Got message from client
LpcPortThread: Accepting connection request
LpcPortThread: Completing connection request
SendIpcMessage: NtConnectPort complete
SendIpcMessage: *** LpcPortThread did not fill in the process ID
*** SendIpcMessage: ProcessID was not filled in by server
InitIpcAnswer: Creating Answer file mapping.  name=IpcTestAnswerBuf21$538
LpcPortThread: Got message from client
LpcPortThread: Got message from client
LpcPortThread: Accepting connection request
*** NtAcceptConnectPort failed with return code C0000005.  Error is "An Access Violation occured." (STATUS_ACCESS_VIOLATION)
LpcPortThread: Rejecting connection request because accepting it failed
*** NtAcceptConnectPort failed with return code C0000005.  Error is "An Access Violation occured." (STATUS_ACCESS_VIOLATION)
I ran your IpcTest utility on the resulting libs... the 32 bit build is ok, albeit the error upon quitting. The 64 bit build also locks up in NtConnectPort. I can press enter once on the master, and it spits out one more chunk before not accepting commands anymore.

http://imgur.com/a/kZQ4p#0
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: Support for Windows 8

Post by madshi »

Thanks for testing this, I appreciate it. I'll try with the express edition. From what I can see, VS2012 express edition does support 64bit compiling, so it should be possible to reproduce this problem with the express edition.

I'll come back to you with results, but it might take a couple of days. Hope you can live with using VS2010 until then...
class101
Posts: 1
Joined: Fri Dec 14, 2012 6:43 pm

Re: Support for Windows 8

Post by class101 »

I suggest you to enroll in BizSpark madshi, with a small computer company its easy to get an account equivalent to MSDN Ultimate for free ~3 years (costs 10000$+)
Apply with your company domain and also mention your company sells since 3 years not much, I believe you are like a startup that deserves Ms for free.

I did it for my boss, we are selling since 5 years but I cheated the date because we are young, just 5 employees
immer000
Posts: 22
Joined: Tue Sep 04, 2012 12:05 am

Re: Support for Windows 8

Post by immer000 »

Also, Microsoft offers a 90 days trial of the non-express editions here : http://www.microsoft.com/visualstudio/e ... 2-editions
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: Support for Windows 8

Post by madshi »

Found the problem: Basically my definition of the native Windows LPC APIs I'm using wasn't fully correct. I was using ULONG (4 byte in x64) while some of them should have been 8 byte in x64 (e.g. ULONG_PTR). I guess that the VS2010 compiler zeroes out the other 4 bytes when sending the parameters to the LPC APIs while VS2012 doesn't bother to do so, resulting in random data for the upper 4 bytes. Anyway, changing the parameter types from ULONG to ULONG_PTR seems to have fixed the issue. Here's a new beta build:

http://madshi.net/madCollectionBeta.exe (2.7.4.6)
immer000
Posts: 22
Joined: Tue Sep 04, 2012 12:05 am

Re: Support for Windows 8

Post by immer000 »

Thank you for investigating this ! I downloaded the beta and tried building the test suite with VS2012 and I get the similar results as before. As a 64-bit process on Windows 8 x64 the IPC locks up in NtConnectPort on the first call (before it would on the second call onwards), the same MainTest.exe on Windows 7 x64 is fine.
Attachments
madTest_Win8.png
madTest_Win8.png (159.6 KiB) Viewed 13021 times
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: Support for Windows 8

Post by madshi »

I've tested again, and it definitely works for me now. I'm still using the last win8 RC for testing, though, maybe that makes a difference. In any case, I could reproduce problems with the current official madCodeHook release, which are totally gone with 2.7.4.6. Could you please double check whether you really got 2.7.4.6 (or newer) from my server? Maybe your browser cache gave you an old file? Make sure the definition of PFN_NTACCEPTCONNECTPORT looks like this now:

Code: Select all

typedef NTSTATUS (WINAPI * PFN_NTACCEPTCONNECTPORT)
(
  PHANDLE PortHandle,
  ULONG_PTR Unknown,              // Pass 0
  P_LPC_MESSAGE pLpcMessage,
  ULONG_PTR Unknown1,             // 1
  ULONG_PTR Unknown3,             // 0
  P_LPC_SECTION_MAP_INFO pSectionMapInfo
);
Also please make sure you compile and test the correct build. While investigating this problem myself, at one time I compiled the debug build and then tested the release build (or vica versa) and wondered why my changes didn't show any effect. Something like that can happen, so could you please double check again to make sure the problem *really* still occurs for you with the latest madCodeHook build?

Thanks!
immer000
Posts: 22
Joined: Tue Sep 04, 2012 12:05 am

Re: Support for Windows 8

Post by immer000 »

Ha, it might explain the different results we get... In my testing, while i did not find many differences between Win8 RC and RTM, you cannot install Visual Studio 2012 RTM on Windows 8 RC, so I guess you are using VS2012 RC too ?
There are been lots of changes to VS2012 since the RC, .lib made with the RC don't even link properly in the RTM, major changes made to the CRT (I know you are not using the CRT but other libraries may have significantly changed too). With VS2012 RTM I cannot compile madCodeHook as is, I have to strip out some structure definitions that are now exposed in winnt.h (see previous post)... they are still defined in 2.7.4.6.
I did get 2.7.4.6 with the changes to the Nt* functions definitions.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: Support for Windows 8

Post by madshi »

So did you retest / double check?

I've been compiling with VS2012 final edition on win7, then moving the exe to win8 VM. Yes, I've had to comment out some structure definitions, too, to make it compile.
immer000
Posts: 22
Joined: Tue Sep 04, 2012 12:05 am

Re: Support for Windows 8

Post by immer000 »

I just double checked again, and found something very strange. If I launch the MainTest.exe from Visual Studio it fails... regardless of whether I attach a debugger to it or not (ie Ctrl+f5). If I just run the same exe from explorer or a command prompt, then the IPC tests are fine.
Definitely a step in the right direction.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: Support for Windows 8

Post by madshi »

Thanks for double checking. Would you mind also checking the same thing with MSVC++ 2010? Does this weird effect also apply to MSVC++ 2010, or only to MSVC++ 2012? What about x64 vs x86? Does the problem in the debugger only apply to x64 or also to x86?

I'm wondering what the problem could be and how difficult it could be for me to fix. This *might* be a bug in MSVC++ 2012. But I've no idea.
immer000
Posts: 22
Joined: Tue Sep 04, 2012 12:05 am

Re: Support for Windows 8

Post by immer000 »

It keeps getting stanger...

Compiling from source with VS2010 also requires some FunctionTypes.h trimming, and in ProcessTools.cpp the function Wow64GetThreadContext is always exposed conflicting with your dynamic binding. (in the windows sdk 8.0 used by vs2012 it is wrapped by a #if (_WIN32_WINNT >= 0x0600) and you #define _WIN32_WINNT=0x0400)
After fixing that up, here are the results...

On Win7 x64 host :
VS 2010 / Win32 / inside debugger : ok
VS 2010 / x64 / inside debugger : ok
VS 2010 / Win32 / outside debugger : ok
VS 2010 / x64 / outside debugger : ok
VS 2012 / Win32 / inside debugger : ok
VS 2012 / x64 / inside debugger : ok
VS 2012 / Win32 / outside debugger : ok
VS 2012 / x64 / outside debugger : ok

On Win8 x64 host :
VS 2010 / Win32 / inside debugger : ok
VS 2010 / x64 / inside debugger : boom
VS 2010 / Win32 / outside debugger : ok
VS 2010 / x64 / outside debugger : ok
VS 2012 / Win32 / inside debugger : ok
VS 2012 / x64 / inside debugger : boom
VS 2012 / Win32 / outside debugger : ok
VS 2012 / x64 / outside debugger : ok

This is on physical installs (no virtual machines), VS installed on the PC itself and used locally.
I also tried with the pre-built .lib (madCHook64.lib, copied and renamed, then I force rebuilding only MainTest.exe), and I get the same results.

So it looks like we can rule out the compiler for now. Problem is only on x64, with a debugger attached.

Note that this is only about the IPC functionnality. I also get failures on some other tests, also on Win7, as per Dec 13 post, with the self-compiled binaries.

Does not seem to be anything to do with the way the function is called as the generated code is pretty much identical. Here's the call itself (vs2010-generated code) :

Code: Select all

      if (pNtConnectPort(&port, &uniStr, &securityQos, pLpcSectionInfo, pLpcSectionMapInfo, NULL, &lpcMessagePrv, &bufLen) == 0)
000007F75DC7380A  lea         rax,[bufLen]  
000007F75DC73812  mov         qword ptr [rsp+38h],rax  
000007F75DC73817  lea         rax,[lpcMessagePrv]  
000007F75DC7381F  mov         qword ptr [rsp+30h],rax  
000007F75DC73824  mov         qword ptr [rsp+28h],0  
000007F75DC7382D  mov         rax,qword ptr [pLpcSectionMapInfo]  
000007F75DC73835  mov         qword ptr [rsp+20h],rax  
000007F75DC7383A  mov         r9,qword ptr [pLpcSectionInfo]  
000007F75DC73842  lea         r8,[securityQos]  
000007F75DC7384A  lea         rdx,[uniStr]  
000007F75DC73852  lea         rcx,[port]  
000007F75DC7385A  call        qword ptr [pNtConnectPort (7F75DD39138h)]  
000007F75DC73860  test        eax,eax  
000007F75DC73862  jne         SendIpcMessage+332h (7F75DC73872h)  
...
and the VS2012 one... absolute addresses are different and local variables symbols are missing for some unknown reason, but otherwise the code is the same :

Code: Select all

      if (pNtConnectPort(&port, &uniStr, &securityQos, pLpcSectionInfo, pLpcSectionMapInfo, NULL, &lpcMessagePrv, &bufLen) == 0)
000007F6B6BA3733  lea         rax,[rsp+58h]  
000007F6B6BA3738  mov         qword ptr [rsp+38h],rax  
000007F6B6BA373D  lea         rax,[rsp+280h]  
000007F6B6BA3745  mov         qword ptr [rsp+30h],rax  
000007F6B6BA374A  mov         qword ptr [rsp+28h],0  
000007F6B6BA3753  mov         rax,qword ptr [rsp+68h]  
000007F6B6BA3758  mov         qword ptr [rsp+20h],rax  
000007F6B6BA375D  mov         r9,qword ptr [rsp+70h]  
000007F6B6BA3762  lea         r8,[rsp+0E8h]  
000007F6B6BA376A  lea         rdx,[rsp+0C0h]  
000007F6B6BA3772  lea         rcx,[rsp+80h]  
000007F6B6BA377A  call        qword ptr [pNtConnectPort (07F6B6C751F0h)]  
000007F6B6BA3780  test        eax,eax  
000007F6B6BA3782  jne         SendIpcMessage+312h (07F6B6BA3792h)
...
... and that's using your precompiled madCHook64.lib :

Code: Select all

000007F6A2CE301A  lea         rax,[rsp+310h]  
000007F6A2CE3022  mov         qword ptr [rsp+38h],rax  
000007F6A2CE3027  lea         rax,[rsp+1E0h]  
000007F6A2CE302F  mov         qword ptr [rsp+30h],rax  
000007F6A2CE3034  mov         qword ptr [rsp+28h],0  
000007F6A2CE303D  mov         rax,qword ptr [rsp+378h]  
000007F6A2CE3045  mov         qword ptr [rsp+20h],rax  
000007F6A2CE304A  mov         r9,qword ptr [rsp+340h]  
000007F6A2CE3052  lea         r8,[rsp+2F0h]  
000007F6A2CE305A  lea         rdx,[rsp+330h]  
000007F6A2CE3062  lea         rcx,[rsp+308h]  
000007F6A2CE306A  call        qword ptr [Lld32+3Ch (07F6A2DB2218h)]  
000007F6A2CE3070  test        eax,eax  
000007F6A2CE3072  jne         SendIpcMessage+332h (07F6A2CE3082h)  
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: Support for Windows 8

Post by madshi »

> I also get failures on some other tests, also on Win7, as per
> Dec 13 post, with the self-compiled binaries

Some of the tests need admin rights. They fail if you don't run the exe with "run as admin". The DLL injection test fails even with "run as admin" if the dll needed for injection can't be found.

I'm not sure why there's still a problem with the IPC inside of the debugger. It's really weird. I'll put this on my to do list to check out. But I guess it's not so very important, anymore, so I can put it on lower priority?
immer000
Posts: 22
Joined: Tue Sep 04, 2012 12:05 am

Re: Support for Windows 8

Post by immer000 »

Makes sense. (Tip : /level='requireAdministrator' /uiAccess='false' added to the linker flags may prevent confusion in the future)

The debugger issue is not really important indeed, as the normal scenario is fine - it can sure go into the low priority bucket.
Post Reply