Click here to Skip to main content
14,866,950 members
Articles / Programming Languages / C++
Article
Posted 10 Jun 2004

Stats

72.3K views
2.1K downloads
35 bookmarked

RmThread - Code execution in Another Process Context.

Rate me:
Please Sign up or sign in to vote.
4.49/5 (14 votes)
17 Aug 2006CPOL3 min read
An injection code tool to make simple run threads remotely.

Sample Image - rmthread.gif

Introduction

RmThread is a project that I made based on one of three ideas from the Robert Kuster article, "Three Ways to Inject Your Code into Another Process". However, I didn't use any code. I wanted to learn about it, searched over the net, and got influenced by the CreateRemoteThread & LoadLibrary technique. The rest was a prescription of "quite right function calls" and MSDN.

The project is useful for someone who need to run some code in a neighbor process, but doesn't want to worry about remote thread technique development. He wants just to write the code to run remotely. The demo project, RmThread.exe, works precisely to do the dirty thing. You say what process to run and the DLL to load, and it starts the process and loads the DLL in the process context. The rest remains in the DLL code.

To write your DLL, there's a demo project that uses a technique that I created to run some code starting from the DllMain execution (apart from another DLL function calling) and doesn't be a slave of its limitations (like: you can safely call only kernel32.dll functions).

Using the code

There're three useful functions that could be called from your program:

/** Run process and get rights for running remote threads. */ 
HANDLE CreateAndGetProcessGodHandle(LPCTSTR lpApplicationName, 
                                            LPTSTR lpCommandLine);

/** Load DLL in another process. */
HMODULE RemoteLoadLibrary(HANDLE hProcess, LPCTSTR lpFileName);

/** Free DLL in another process. */
BOOL RemoteFreeLibrary(HANDLE hProcess, HMODULE hModule);

Here's a simplified main routine showing how simple it is to use the functions:

//...
   // Start process and get handle with powers.
   hProc = CreateAndGetProcessGodHandle(tzProgPath, tzProgArgs);

   if( hProc != NULL )
   {
      // Load DLL in the create process context.
      HMODULE hDll = RemoteLoadLibrary(hProc, tzDllPath);

      if( hDll != NULL )
         RemoteFreeLibrary(hProc, hDll);

      CloseHandle(hProc);
   }
//...

The most complicated thing maybe what to do when your DLL is loaded. Considering that when it is called in your entry point, the DLL code has to follow some boring rules to avoid boring things like access violations (for more, read the DllMain help at MSDN). I made an "alternative execution", creating a thread in the DllMain function:

BOOL APIENTRY DllMain(HANDLE hModule, 
        DWORD ul_reason_for_call, LPVOID lpReserved) {
   switch( ul_reason_for_call )
   {
      case DLL_PROCESS_ATTACH:
      {
         DWORD dwThrId;

         // Fill global variable with handle copy of this thread.
         BOOL bRes =
         DuplicateHandle(GetCurrentProcess(),
                         GetCurrentThread(),
                         GetCurrentProcess(),
                         &g_hThrDllMain,
                         0, 
                         FALSE, 
                         0);
         if( bRes == FALSE ) break;

         // Call function that do the useful stuff with its DLL handle.
         CloseHandle(CreateThread(NULL, 
                                  0,
                                  RmThread,
                                  (LPVOID) LoadLibrary(g_tzModuleName),
                                  0, 
                                  &dwThrId));
      }
      break;
//...

The tasks for our newly created thread, by its turn are, to wait for the DllMain finalization (we'd have its handle stored in g_hThrDllMain), to do what it must to do (the all this stuff purpose), and to get back, releasing at the same time the DLL handle allocated for itself:

/**
 * Sample function, called remotely for RmThread.exe.
 */
DWORD WINAPI RmThread(LPVOID lpParameter) {
   HMODULE hDll = (HMODULE) lpParameter;
   LPCTSTR ptzMsg = 
           _T("Congratulations! Did you call RmThread.dll successfully!");

   // Wait DllMain termination.
   WaitForSingleObject(g_hThrDllMain, INFINITE);

   //TODO: Put your remote code here.
   MessageBox(NULL,
              ptzMsg,
              g_tzModuleName,
              MB_OK | MB_ICONINFORMATION);
 
   // Do what the function name says.
   FreeLibraryAndExitThread(hDll, 0);
}

The TODO mark is where your code must be written (you can pull out the MessageBox, if you want). Like DllMain code was previously executed, this part of the code is free to do what it wants to do in the neighbor process context.

An interesting detail is the requirement to call FreeLibraryAndExitThread. In another way, if you call FreeLibrary and then return, the code to be executed after that (a simple ret assembly instruction) would be in an invalid memory address (the DLL code is no more loaded at the address space). So, the result could not be so delightful like the final solution.

Points of Interest

A boring problem that you can find is: if the DLL couldn't be loaded successfully, how can I get the error code? Unfortunately, there's no trivial way to get the error code returned from LoadLibrary call. In order for the thread to start and finish in this API function, the LastError code is lost (there's a LastError for each thread in the process). Any idea?

History

  • 2004.06.11 - 1.0.0.1 version released.
  • 2004.06.13 - Support to VC6 project.
  • 2006.08.17 - Support for VS2005.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Wanderley Caloni
Technical Lead Intelitrader
Brazil Brazil
Wanderley Caloni
Backend Specialist
Location: São Paulo, Brazil
Email: wanderley.caloni@gmail.com
Skills
C, C++, Assembly, Windows, x86, Reverse Engineering, Cryptography, Tech/Art Writing, Debugging, Git, SQL

Experience
Intelitrader, 2015 - current (Tech Lead)
Market Data System
DataHub System
Finantial Market Vendor Projects
BitForge, 2015 - current (Owner Developer)
Appliance ATM System Security
Information Security Product Maintenance
Minor projects and skills
Communication API with HID USB devices
Windows Phone and Android user interfaces programming
Boost.Asio Winsock bug
Hidapi issue with IO pending
UOL Diveo Broker, 2012 - 2015 (Backend Developer)
Financial Market Risk System (Stock Broker)
HUB Network API Development and Maintenance
Scua Information Security, 2008 - 2012 (Security Developer)
Information Security Product Maintenance
Disk Cryptography
Team Coordination
Minor projects and skills
Hardware inventory using WMI/SMBIOS
Software inventory using Windows Registry
PrintScreen protection using COM interfaces
Windows Event Log using device driver
User/Kernel communication using DeviceIoControl API
VNC like development
PsExec like development
Documents print control using regex (boost) and shell hook
User policies management using Windows Registry and API hooks
Database migration from CTree to SQL using OLE classes
Windows authentication using DCOM service, custom GINA and Credential Provider (Windows Vista)
Database synchronization using DCOM service
Linux maintenance bootable CD, bash scripts and cryptography tools
USB Cryptography (pen drives)
Crash dump analysis using Windbg
System account process execution using COM service
MBR (Master Boot Record) customization analysing BIOS features
Blowfish and SHA-1 development in 16 bits assembly (x86)
Audit driver using shared memory between user and kernel events
Open Communications Security, 2005 - 2008 (Security Specialist)
Reverse Engineering (Trojan Analysis)
API Hooking
Antidebugging Solution
Code Ofusc

Comments and Discussions

 
GeneralApplication Pin
Somen Shaw22-Jul-08 0:26
MemberSomen Shaw22-Jul-08 0:26 
GeneralRe: Application Pin
Wanderley Caloni22-Jul-08 2:11
professionalWanderley Caloni22-Jul-08 2:11 
GeneralDelete the dll file after loading Pin
Davidi21-Jul-04 4:54
MemberDavidi21-Jul-04 4:54 
GeneralRe: Delete the dll file after loading Pin
Wanderley Caloni21-Jul-04 14:58
professionalWanderley Caloni21-Jul-04 14:58 
GeneralHeavy footprint. Pin
WREY13-Jun-04 19:02
MemberWREY13-Jun-04 19:02 
GeneralRe: Heavy footprint. Pin
Wanderley Caloni14-Jun-04 6:19
professionalWanderley Caloni14-Jun-04 6:19 
QuestionVC6 sample? Pin
WREY13-Jun-04 3:30
MemberWREY13-Jun-04 3:30 
AnswerRe: VC6 sample? Pin
Wanderley Caloni13-Jun-04 8:23
professionalWanderley Caloni13-Jun-04 8:23 
GeneralMissing files. Pin
WREY13-Jun-04 9:02
MemberWREY13-Jun-04 9:02 
GeneralRe: Missing files. Pin
Wanderley Caloni13-Jun-04 12:11
professionalWanderley Caloni13-Jun-04 12:11 
GeneralRe: Missing files. Pin
WREY13-Jun-04 17:40
MemberWREY13-Jun-04 17:40 
GeneralRe: Missing files. Pin
Wanderley Caloni14-Jun-04 2:46
professionalWanderley Caloni14-Jun-04 2:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.