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 


Invoking a function from NTDLL

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
iPromise
Grandmaster Cheater
Reputation: -1

Joined: 27 Jun 2009
Posts: 529
Location: Canada

PostPosted: Sun Nov 11, 2012 10:34 pm    Post subject: Invoking a function from NTDLL Reply with quote

So basically i've grabbed the address of ZwProtectVirtualMemory in my usermode application and now i'm going to use it. It compiles fine however on execution it fails to edit the addresses protection constant.

This is how I declare ZwProtectVirtualMemory.

Code:

void *lpAddr = (void*) GetProcAddress ( GetModuleHandle ( "ntdll.dll" ), "ZwProtectVirtualMemory" );

typedef NTSTATUS (__stdcall *ZWPROTECTMEM ) ( IN HANDLE ProcessHandle,
    IN PVOID *  BaseAddress,
    IN SIZE_T *     NumberOfBytesToProtect,
    IN ULONG    NewAccessProtection,
    OUT PULONG  OldAccessProtection
);

ZWPROTECTMEM ZwProtectVirtualMemory = (ZWPROTECTMEM) lpAddr;


And this is the code that I use to test it out:

Code:

int main ()
{
   DWORD changeme = 4;
   ULONG size  = 4;
   LPVOID addr  = &changeme;
   
   // Protect the memory
   ULONG uOld;
   ULONG uDummy;

   // Try to restore original constant
   ZwProtectVirtualMemory ( (HANDLE) GetCurrentProcess (), &addr, &size, PAGE_NOACCESS, &uOld );
   ZwProtectVirtualMemory ( (HANDLE) GetCurrentProcess (), &addr, &size, PAGE_EXECUTE_READWRITE, &uDummy );

   cout << (void*) dwNew << endl;

   // Try to write without hitting an exception
   changeme = 5;
   cout << changeme << endl;

   cin.get ();
   return 0;
}



However I keep hitting an exception.

Thanks for your help[/code]
Back to top
View user's profile Send private message MSN Messenger
Dark Byte
Site Admin
Reputation: 471

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

PostPosted: Mon Nov 12, 2012 1:07 am    Post subject: Reply with quote

changeme is located on the stack
You're making 4096 to 8192 bytes around there NOACCESS (depending on if it overlaps a page boundary, of course, seeing it's stack and an int, I doubt it's 8192)
That means that any instruction that accesses the stack nearby will raise an exception. E.g Function returns, calling functions, calculations where a variable is pushed on the stack, etc...

_________________
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
iPromise
Grandmaster Cheater
Reputation: -1

Joined: 27 Jun 2009
Posts: 529
Location: Canada

PostPosted: Mon Nov 12, 2012 7:42 am    Post subject: Reply with quote

How come 4096 bytes are being protected with NOACCESS, I specified 5 bytes with my variable?
Back to top
View user's profile Send private message MSN Messenger
Dark Byte
Site Admin
Reputation: 471

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

PostPosted: Mon Nov 12, 2012 7:59 am    Post subject: Reply with quote

That is the way the cpu works. You can only protect whole pages(4096), and not individual bytes. (For that you need to set debugregisters and then capture the int1 exception)
The size and base address are just to detect if more than one page is protected or not

What you could do (but requires a LOT of work) is make the page no access, and then when the page is accessed freeze ALL the threads in the process.
Then check if it is the protected address or not and handle it accordingly
Then set the TF (trap flag) in the eflags register and make the page normally accessible and continue just this one thread.
It will raise a breakpoint exception, now set the page to noaccess again and continue executing all threads of the target

Note though that this can slow down the target process so it can look like it's completly frozen

And keep in mind that multiple exceptions may happen at the same time. (thread 1 raises an exception, but before your code has suspended all other threads thread 2 has raised one as well. Solution: Critical sections)

_________________
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
iPromise
Grandmaster Cheater
Reputation: -1

Joined: 27 Jun 2009
Posts: 529
Location: Canada

PostPosted: Mon Nov 12, 2012 9:45 am    Post subject: Reply with quote

Alright I understand it now.

However,

the following code still won't protect the region that my address is in into PAGE_EXECUTE_READWRITE:

Code:

myAddress = lpTarget;

ntSuccess = ZwProtectVirtualMemory ( NtCurrentProcess (), &myAddress, &szToProtect, PAGE_EXECUTE_READWRITE, &OldProtection );


ntSuccess keeps returning zero (BTW I put it in my driver now). I think that its probably because of the address that I redirect ZwProtectVirtualMemory to. I have three of lines of code that are well-commented below:

Code:

PVOID findZwProtect ()
{

// The function after ZwProtectVirtualMemory is ZwPulseEvent
// ZwPulseEvent is supported by the DDK
// So i'm going to get the address to ZwPulseEvent here
RtlInitUnicodeString ( &pText, L"ZwPulseEvent" );
PVOID pZwPulseEvent = MmGetSystemRoutineAddress ( &pText );

// Since every function in the ntdll has a similiar ASM structure and exact length of 20 bytes, its safe to say that the entry point of ZwPulseEvent - 20 = the entry point of ZwProtectVirtualMemory. Example:

//CreateFile:

/*
804FF558 - B8 25000000        - mov eax,00000025
804FF55D - 8D 54 24 04        - lea edx,[esp+04]
804FF561 - 9C                      - pushfd
804FF562 - 6A 08                  - push 08
804FF564 - E8 68110400        - call 805406D1
804FF569 - C2 2C00              - ret 002C
*/

//ZwProtectVirtualMemory:

/*
804FFD28 - B8 89000000          - mov eax,00000089
804FFD2D - 8D 54 24 04           - lea edx,[esp+04]
804FFD31 - 9C                         - pushfd
804FFD32 - 6A 08                     - push 08
804FFD34 - E8 98090400           - call 8054D3D4
804FFD39 - C2 1400                  - ret 0014
*/

// You notice that its just different call numbers, different functions being called and a different return number, but it always sums up to 20 bytes of length

return (PVOID) ( (DWORD) pZwPulseEvent - 0x20 );
}
Back to top
View user's profile Send private message MSN Messenger
Dark Byte
Site Admin
Reputation: 471

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

PostPosted: Mon Nov 12, 2012 10:11 am    Post subject: Reply with quote

I don't have much time right now, but i don't think this is correct. The call should go to the same dispatcher as CreateFile

Also, ntstatus of 0 means success

_________________
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
iPromise
Grandmaster Cheater
Reputation: -1

Joined: 27 Jun 2009
Posts: 529
Location: Canada

PostPosted: Tue Nov 13, 2012 9:43 am    Post subject: Reply with quote

Dark Byte wrote:
You're making 4096 to 8192 bytes around there NOACCESS (depending on if it overlaps a page boundary, of course, seeing it's stack and an int, I doubt it's 8192)
That means that any instruction that accesses the stack nearby will raise an exception. E.g Function returns, calling functions, calculations where a variable is pushed on the stack, etc...


So if I ever protect an address with PAGE_NOACCESS, I can never make it PAGE_EXECUTE_READWRITE without getting an exception.

This is inside my testing application (usermode):

Code:

void *lpAddr = (void*) GetProcAddress ( GetModuleHandle ( "ntdll.dll" ), "ZwProtectVirtualMemory" );

typedef NTSTATUS (__stdcall *ZWPROTECTMEM ) ( IN HANDLE ProcessHandle,
    IN PVOID *  BaseAddress,
    IN SIZE_T *     NumberOfBytesToProtect,
    IN ULONG    NewAccessProtection,
    OUT PULONG  OldAccessProtection
);

ZWPROTECTMEM ZwProtectVirtualMemory = (ZWPROTECTMEM) lpAddr;

//
void main ()
{
   DWORD tester = 4;
   ULONG size  = 4;
   LPVOID addr  = &tester;
   
   // Protect the memory
   ULONG dwOld;
   ULONG dwNew;

   /* Test ZwProtectVirtualMemory */

   // Try to protect it with PAGE_NOACCESS
   ZwProtectVirtualMemory ( GetCurrentProcess (), &addr, &size, PAGE_NOACCESS, &dwNew );

   // Try to restore it
   ZwProtectVirtualMemory ( GetCurrentProcess (), &addr, &size, PAGE_EXECUTE_READWRITE, &dwNew );

   // Try to write without hitting an exception
   tester = 5;
   cout << tester << endl;

   system ( "PAUSE" );
}
//
Back to top
View user's profile Send private message MSN Messenger
Dark Byte
Site Admin
Reputation: 471

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

PostPosted: Tue Nov 13, 2012 10:26 am    Post subject: Reply with quote

Quote:

So if I ever protect an address with PAGE_NOACCESS, I can never make it PAGE_EXECUTE_READWRITE without getting an exception.

Yes you can, you just have to make sure that the page you're setting to page_noaccess isn't of vital importance to your code.

In your example the variable named tester is located in the stack, and that is of vital importance to be able to return from ZwProtectVirtualMemory and to call the next ZwProtectVirtualMemory

Now if the address of tester was at a location your code doesn't need then it should work fine

_________________
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
iPromise
Grandmaster Cheater
Reputation: -1

Joined: 27 Jun 2009
Posts: 529
Location: Canada

PostPosted: Tue Nov 13, 2012 3:19 pm    Post subject: Reply with quote

Thanks a bunch man. I'll tell you how it goes.
Back to top
View user's profile Send private message MSN Messenger
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