Trying to create callgate syscall function for windows 8

I have a callgate function for Windows 7 that I use to directly call NT functions:

//Windows 7 syscall __declspec(naked) NTSTATUS __fastcall wow64 ( DWORD ecxId, char *edxArgs ) { __asm { mov eax, ecx; mov ecx, m_param; call DWORD ptr fs:[0xc0]; add esp, 0x4; retn; }; } NTSTATUS callGate ( DWORD id, ... ) { va_list valist; va_start(valist,id); return wow64(id,valist); } //Example NTClose function NTSTATUS closeHandle ( void *object ) { m_param = 0; return callGate ( 0xc, object ); } 

I am trying to do the same for Windows 8.1. I updated all function call indices; however, I noticed that the actual callgate function is completely different in Windows 8.1:

This is what the actual call column (located in ntdll.dll) looks like for the ZwCreateThreadEx function

 mov eax, 0xA5 //the call index xor ecx, ecx //(m_param) lea edx, dword ptr ss:[esp + 0x4] //this causes an sp-analysis failure in IDA call dword ptr fs:[0xC0] add esp, 0x4 retn 0x2C 

Now here is the EXACT same NT function (ZwCreateThreadEx) on windows 8.1

 mov eax, 0xB0 //the call index call dword ptr fs:[0xC0] retn 0x2C //2c/4 = 11 parameters 

I tried all kinds of things to get this working on Windows 8.1, but to no avail. I can’t explain what the problem is or what is happening, all I know is that I am doing it right in Windows 7.

From the looks of the W8.1 function, I tried to come up with this single function (doesn't work):

 DWORD dwebp,dwret,dwparams; //for saving stuff NTSTATUS __cdecl callGate ( DWORD id, DWORD numparams, ... ) { _asm { pop dwebp; //save ebp off stack pop dwret; //save return address pop eax; //save id pop dwparams; //save param count push dwret; //push return addy back onto stack cuz thats how windows has it JMP DWORD ptr fs:[0xc0]; //call with correct stackframe (i think) mov ecx, numparams; //store num params imul ecx, 4; //multiply numparams by sizeof(int) add esp, ecx; //add to esp ret; }; } 

Any help would be greatly appreciated.

+6
source share
1 answer

Your new callGate function will not configure the stack stack you need, the return address at the top of the stack is the callGate return address, not the command after the call.

Here's what the stack looks like after the CALL statement is executed in your ZwCreateThreadEx example from Windows 8.1:

  • return address ( retn 0x2c instruction)
  • return address (calling object ZwCreateThreadEx)
  • arguments (11 DWORDs)

Here is what the column looks like after executing the JMP command in your new callGate function:

  • return address (calling callGate)
  • arguments

There are other problems with your new callGate function. It stores values ​​in global variables, which means that you are not thread safe. Two threads cannot call callBack at the same time without unloading these stored values. It uses a built-in assembly that makes your code more complex than it should be, and makes it dependent on undocumented behavior: how the compiler will configure the stack for this function.

Here, as I write your version of Windows 8.0 for callGate in MASM:

 _text SEGMENT MAXARGS = 16 do_call MACRO argcount @@call&argcount: call DWORD PTR fs:[0C0h] ret argcount * 4 ENDM call_table_entry MACRO argcount DD OFFSET @@call&argcount ENDM _callGate PROC pop edx ; return address pop eax ; id pop ecx ; numparams push edx ; return address cmp ecx, MAXARGS jg @@fail jmp [@@call_table + ecx * 4] @@args = 0 REPT MAXARGS + 1 do_call %@@args @@args = @@args + 1 ENDM @@fail: ; add better error handling int 3 jmp @@fail @@call_table: @@args = 0 REPT MAXARGS + 1 call_table_entry %@@args @@args = @@args + 1 ENDM _callGate ENDP _TEXT ENDS END 

This implementation is limited to MAXARGS arguments (change the value if any Windows system call takes more than 16 arguments). It uses macros to generate a CALL / RET code block table to avoid having to store the number of arguments somewhere within the call. I have a version that supports any number of arguments, but it's harder and fair bit slower. This implementation has not been tested, I do not have Windows 8.1.

+2
source

Source: https://habr.com/ru/post/985864/


All Articles