Create threads in other processes

Source: Internet
Author: User

Transferred fromSmileBlog http://blog.csdn.net/pankun/

This method is not applicable to 9x systems.
We know that the operating system of NT and above provides a function virtualallocex. With this function, we can apply for a piece of memory in other processes. Its definition is as follows:
Function virtualallocex (hprocess: thandle; lpaddress: pointer; dwsize, flallocationtype: DWORD; flprotect: DWORD): pointer; stdcall;
Hprocess is the handle of the process to which the memory is applied. You can use the following method to obtain the process handle of the process to which the specified window belongs.
Function getprocesshandle: thandle;
VaR
Wndhandle, PID: thandle;
Begin
Wndhandle: = findwindow (nil, 'window name ');
{Obtain the process and thread ID}
Getwindowthreadprocessid (wndhandle, pid );
{Open Process Handle with full access permission}
Result: = OpenProcess (process_all_access, false, pid );
End;

Lpaddress is the address pointer pointing to the starting address of the page within a certain address range to be allocated. It can be set to nil, and the system determines the address for space allocation. dwsize is the size of the allocated memory area. flallocationtype is the allocation type. Here we set it to mem_commit.flprotect as the access protection type for the newly allocated memory, which can be set to page_execute_readwrite to define it as executable read/write.
After the function is successfully executed, the base address of the allocated page is returned.

After successfully applying for memory, we can use the writeprocessmemory function to write the code of the thread function in our process to the target process, and then call the createremotethread function to create a remote thread. its definition and parameter type are similar to createthread.

Now it seems that everything is okay. In fact, there is another troublesome problem. If you call an API function in a remote thread, a call error will occur, because when you call an API, the compiler does not generate a command to directly call the API. Instead, it writes the address of the corresponding API to the call address when the process is loaded. The call command then calls the real API function based on the address, however, the corresponding API addresses in each process are different. Therefore, we need to find the actual API addresses (using loadlibrary and getprocaddress) and write them to the target process. however, this is not very easy, because if a new variable is defined in the thread function, it is very troublesome to relocate the variable to the base address of the function. after studying the CPU window of Delphi, I finally found a method that is easy to expand. is to use the structure variable.

Let's take a look at the example below.
Unit unit1;

Interface

Uses
Windows, messages, sysutils, variants, classes, graphics, controls, forms,
Dialogs, stdctrls;

Const
Wm_hooked = wm_user + 3221; {hook installation successful message}

Type
Tthreadprovarlist = record {Variable list}
Sendmessage: DWORD;
Exitprocess: DWORD;
Exitthread: DWORD; {used to save the real API address above}
Wndhandle: DWORD;
End;

Tform1 = Class (tform)
Button1: tbutton;
Button2: tbutton;
Procedure button1click (Sender: tobject );
Procedure button2click (Sender: tobject );
Private
{Memory Address requested in the target process}
Threadadd: pointer;
PID, phandle: DWORD; {target window process ID, handle, and thread ID}
Threadhandle, threadid: thandle; {ID and handle of the new remote thread}
Procedure wmhooked (var msg: tmessage); message wm_hooked;
Public
{Public declarations}
End;

VaR
Form1: tform1;

Implementation

{$ R *. DFM}

Procedure threadpro;
VaR
Varlist: tthreadprovarlist;
Begin
ASM
MoV eax, $ ffffffff {to $ ffffffff offset is 7}
MoV varlist. sendmessage, eax
MoV eax, $ ffffffff {This $ ffffffff is added with 8 at the previous offset}
MoV varlist. wndhandle, eax
MoV eax, $ ffffffff
MoV varlist. exitprocess, eax
MoV eax, $ ffffffff
MoV varlist. exitthread, eax
Push 0
Push 0
Push 4245 {4245 is the custom wm_hooked}
Push varlist. wndhandle
Call varlist. sendmessage
Push 0
Call varlist. exitthread
End;
End;

Procedure tform1.button1click (Sender: tobject );
VaR
{The Window handle to be injected into the thread and the temporarily stored handle}
Wndhandle, tmphandle: thandle;
Dllmodule, sendpro, writecount: DWORD;
Exitpro, exittpro: DWORD;
Begin
{Find the window to be injected with a remote thread first}
Wndhandle: = findwindow (nil, 'notepad ');
{Obtain the process and thread ID}
Getwindowthreadprocessid (wndhandle, pid );
{Open Process Handle with full access permission}
Phandle: = OpenProcess (process_all_access, false, pid );
{Allocate memory in the target process}
Threadadd: = virtualallocex (phandle, nil, 4096, mem_commit, page_execute_readwrite );
{Write the custom function to the target process}
Writeprocessmemory (phandle, threadadd, @ threadpro, 4096, writecount );
{Create a remote thread as a pending thread for modification}
Threadhandle: = createremotethread (phandle, nil, 0, threadadd, nil, create_suincluded, threadid );
{Obtain the actual API address}
Dllmodule: = loadlibrary ('user32. dll ');
Sendpro: = DWORD (getprocaddress (dllmodule, 'sendmessagew '));
Dllmodule: = loadlibrary ('kernel32. dll ');
Exitpro: = DWORD (getprocaddress (dllmodule, 'exitprocess '));
Exittpro: = DWORD (getprocaddress (dllmodule, 'exitthread '));
{Write the real API address and data to the function in the target process}
Tmphandle: = self. Handle;
Writeprocessmemory (phandle, pointer (longint (threadadd) + 7), @ sendpro, sizeof (DWORD), writecount );
Writeprocessmemory (phandle, pointer (longint (threadadd) + 15), @ tmphandle, sizeof (DWORD), writecount );
Writeprocessmemory (phandle, pointer (longint (threadadd) + 23), @ exitpro, sizeof (DWORD), writecount );
Writeprocessmemory (phandle, pointer (longint (threadadd) + 31), @ exittpro, sizeof (DWORD), writecount );
{Start running remote thread}
Resumethread (threadhandle );
Closehandle (threadhandle );
End;

Procedure tform1.button2click (Sender: tobject );
Begin
{Release the memory allocated in the target process}
Virtualfreeex (phandle, threadadd, 4096, mem_decommit );
{Close unused handles}
Closehandle (phandle );
End;

Procedure tform1.wmhooked (var msg: tmessage );
Begin
MessageBox (self. Handle, 'remote thread created successfully ','!!! ', Mb_ OK );
End;

End.

To define a new variable in the thread function, add the variable in the tthreadprovarlist type, and then add a variable similar
MoV eax, $ ffffffff
MoV varlist. exitprocess, eax
Write the value of the new variable with writeprocessmemory. if you apply for a variable in Var, the offset address at the first point of the function will change, and the source program will also change accordingly. You can view the variable in the CPU window. if you have a better way to pass variables, please let me know.
Note that calling the VCL function in a thread function is also problematic because it points to the function address in the process. if you use a pchar string, you must first use the virtualallocex function to apply for memory, and then use writeprocessmemory to write string to the target process and save the string address, you can use this function by sending the API address to the thread function.
Remember to use the virtualfreeex function to release the memory allocated in the target process.

Using the virtualallocex function, you can also implement the Hook Technology without DLL files. If you are interested, you can try to extend it yourself.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.