Jump to content
Tuts 4 You

[C++] CreateRemoteThread & WriteProcessMemory


deepzero

Recommended Posts

Hi,

I wanted to inject some code into another process & execute it as a separate thread. This is my code so far:

DWORD PID = 0; //PID goes here!
HANDLE hProcess = 0; hProcess = ::OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
FALSE, PID);
cout << hProcess;void *p = 0;
const DWORD MAXINJECTSIZE = 4096;
p = VirtualAllocEx( hProcess, 0, MAXINJECTSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE );DWORD bem = 90909090; if ( ! WriteProcessMemory(hProcess, p, &bem, MAXINJECTSIZE, 0 ) )
{
cout << "WPM() failed, gle = " << GetLastError();
return 0;
}::CreateRemoteThread(hProcess,NULL,0,(DWORD (__stdcall *)( void *))p,NULL,0,NULL);

There are three problems:

1) how do i get the adress of the code i want to write to another rocess? As you can see, i filled the bem DWORD with dummy data (while adjusting it when debugging in olly).

2) It works, but could someone explain to me what "(DWORD (__stdcall *)( void *))" actually does? Isnt vallcoex supposed to just return the plain address?

3) forgot, one sec... :S

thx,

dp0 :)

Link to comment

Heya. ;)

1. You should know what code to inject? Write a function that does what you want and inject it? Sorry if I misunderstood you.

2. VirtualAllocEx returns the void pointer. CreateRemoteThread expects a function pointer, the typedef is (L)PTHREAD_START_ROUTINE (the L is optional as there are two typedefs actually). That weird cast simply casts to the appropriate function pointer and can be replaced with a cast to PTHREAD_START_ROUTINE.

3. Okay. :)

May I ask for which purpose you're injecting the code? I experienced that injecting a DLL (manually in Olly) is easier to debug and easier to write of course (as I don't have to care about position-dependence of my code).

Link to comment

Hi,

I wanted to inject some code into another process & execute it as a separate thread. This is my code so far:

DWORD PID = 0; //PID goes here!
HANDLE hProcess = 0; hProcess = ::OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
FALSE, PID);
cout << hProcess;void *p = 0;
const DWORD MAXINJECTSIZE = 4096;
p = VirtualAllocEx( hProcess, 0, MAXINJECTSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE );DWORD bem = 90909090; if ( ! WriteProcessMemory(hProcess, p, &bem, MAXINJECTSIZE, 0 ) )
{
cout << "WPM() failed, gle = " << GetLastError();
return 0;
}::CreateRemoteThread(hProcess,NULL,0,(DWORD (__stdcall *)( void *))p,NULL,0,NULL);

There are three problems:

1) how do i get the adress of the code i want to write to another rocess? As you can see, i filled the bem DWORD with dummy data (while adjusting it when debugging in olly).

2) It works, but could someone explain to me what "(DWORD (__stdcall *)( void *))" actually does? Isnt vallcoex supposed to just return the plain address?

3) forgot, one sec... :S

thx,

dp0 :)

1. Debug the application to locate the address you need to write to. If it's a static address you should be fine to use the address taken from OllyDbg. However, if the address is located within a modules address space, or part of something such as an allocated memory chunk, you will need to take different measures to get the address such as using a simple code shifting method. Lets say there is an address inside of a dlls memory space. You need to create an 'offset' for that, which to do that you would do:

Address - Modules Base Address = Offset

Then when you load and want to obtain the address to write to, you would locate the dlls base address and add the offset to it such as:

Modules Base Address + Offset = Address

2. It is typecasting the pointer to a function definition. If you want that to look cleaner you can use (LPTHREAD_START_ROUTINE) instead, which is the same thing.

3. ---

Also keep in mind with your code, you should add some checks before going through with each step. There's no reason to output the handle as well, if you are doing that to check if it was obtained, just use a check.

Also with:

DWORD bem = 90909090;

You can't write values like that. If you wish to write nops like that you would need to:


BYTE btNops[] = { 0x90, 0x90, 0x90, 0x90 };
WriteProcessMemory( hProcess, p, &btNops, sizeof( btNops ), 0 );
Link to comment

As you can see, i filled the bem DWORD with dummy data (while adjusting it when debugging in olly).

I'm not sure that he's confused on that part though atom0s, cos he said that he fills that with the address when debugging.

HR,

Ghandi

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...