Remote Module Unloader Application

  • Posted on: 3 August 2014
  • By: siteadm

This is the app I talked about in previous post

Based on shellcode in previous post, I wrote a functional application which injects shellcode into remote process and unloads given module name. We can also call it remote process DLL unloader.

ProcModUnload.c

#include <windows.h>
#include <stdio.h>
#pragma warning( disable : 4047 4024 )
int InjectShell(unsigned char *shellcode, int codesize, int ProcessID)
{
	HANDLE processHandle, shellcodeThread, baseAddress;
	int retval;
	unsigned long OldProtect;
	// Open the target process
	processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID);
	if(!processHandle) return -1;
	// Allocate memory space for shellcode
	baseAddress = VirtualAllocEx(processHandle, NULL, codesize, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	if (baseAddress == NULL) return -1;
	// Write Shellcode
	retval = WriteProcessMemory(processHandle, baseAddress, shellcode, codesize, NULL);
	if (retval == 0) return -1;
	VirtualProtect(baseAddress, codesize, PAGE_EXECUTE_READWRITE, &OldProtect);
	// Run shellcode in remote process
	shellcodeThread = CreateRemoteThread(processHandle, NULL, NULL, (LPTHREAD_START_ROUTINE)baseAddress, NULL, NULL, NULL);
	WaitForSingleObject(shellcodeThread, INFINITE);
	if (shellcodeThread == NULL) return -1;
	CloseHandle(processHandle);
	return 0;
}
 
int main(int argc, char* argv[])
{
 
	int pid,ret,arrayloc,i,modnamelen;
	char modname[100];
	// 357 bytes shellcode, 3 prime digits, coincidence? I think not...
	unsigned char shellcode[357] = { 
	0x31, 0xC9, 0x64, 0x8B, 0x41, 0x30, 0x8B, 0x40, 0x0C, 0x8B, 0x70, 0x14, 0xAD, 0x96, 0xAD, 0x8B, 0x58, 0x10, 0x8B, 0x53, 0x3C, 0x01, 0xDA, 0x8B, 
	0x52, 0x78, 0x01, 0xDA, 0x8B, 0x72, 0x20, 0x01, 0xDE, 0x31, 0xC9, 0x31, 0xC9, 0x64, 0x8B, 0x41, 0x30, 0x8B, 0x40, 0x0C, 0x8B, 0x70, 0x14, 0xAD, 
	0x96, 0xAD, 0x8B, 0x58, 0x10, 0x8B, 0x53, 0x3C, 0x01, 0xDA, 0x8B, 0x52, 0x78, 0x01, 0xDA, 0x8B, 0x72, 0x20, 0x01, 0xDE, 0x31, 0xC9, 0x41, 0xAD, 
	0x01, 0xD8, 0x81, 0x38, 0x47, 0x65, 0x74, 0x50, 0x75, 0xF4, 0x81, 0x78, 0x04, 0x72, 0x6F, 0x63, 0x41, 0x75, 0xEB, 0x81, 0x78, 0x08, 0x64, 0x64, 
	0x72, 0x65, 0x75, 0xE2, 0x8B, 0x72, 0x24, 0x01, 0xDE, 0x66, 0x8B, 0x0C, 0x4E, 0x49, 0x8B, 0x72, 0x1C, 0x01, 0xDE, 0x8B, 0x14, 0x8E, 0x01, 0xDA,
	0x31, 0xC9, 0x6A, 0x00, 0x53, 0x52, 0x51, 0x68, 0x64, 0x6C, 0x65, 0x41, 0x68, 0x65, 0x48, 0x61, 0x6E, 0x68, 0x6F, 0x64, 0x75, 0x6C, 0x68, 0x47, 
	0x65, 0x74, 0x4D, 0x54, 0x53, 0xFF, 0xD2, 0x50, 0x6A, 0x00, 0x68, 0x61, 0x72, 0x79, 0x00, 0x68, 0x4C, 0x69, 0x62, 0x72, 0x68, 0x46, 0x72, 0x65, 
	0x65, 0x54, 0x8B, 0x44, 0x24, 0x30, 0x50, 0xFF, 0x54, 0x24, 0x30, 0x50, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 
	0x00, 0x00 ,0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 
	0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 
	0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 
	0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 
	0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x54, 0xFF, 0x54, 0x24, 0x7C, 0x50, 0xFF, 
	0x54, 0x24, 0x68, 0x6A, 0x00, 0x68, 0x61, 0x64, 0x00, 0x00, 0x68, 0x54, 0x68, 0x72, 0x65, 0x68, 0x45, 0x78, 0x69, 0x74, 0x54, 0x8B, 0x84, 0x24, 
	0xA8, 0x00, 0x00, 0x00, 0x50, 0xFF, 0x94, 0x24, 0xA8, 0x00, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00 } ;
	 
	if (argc != 3) 
	{
		printf("\nPlease enter PID and modulename\n");
		printf("\nExample: ProcModUnload.exe 345 imm32.dll\n");
		return 0;
	}

	pid = atoi(argv[1]);
	modnamelen=strlen(argv[2]);
	if (modnamelen > 100)
	{
		printf("Module name have 100 chars limit. Update shellcode if you want more chars.\n");
		return -1;
	}
	strcpy(modname, argv[2]);
	arrayloc=304; //location of last byte allocated for modname to be stored
	for (i=0;i<modnamelen;i+=4)
	{
		(i >= modnamelen) ? (shellcode[arrayloc-3] = 0x00) : (shellcode[arrayloc-3]=modname[i]);
		(i+1 >= modnamelen) ? (shellcode[arrayloc-2] = 0x00) : (shellcode[arrayloc-2]=modname[i+1]);
		(i+2 >= modnamelen) ? (shellcode[arrayloc-1] = 0x00) : (shellcode[arrayloc-1]=modname[i+2]);
		(i+3 >= modnamelen) ? (shellcode[arrayloc] = 0x00) : (shellcode[arrayloc]=modname[i+3]);
		arrayloc -= 5;
	}

	ret = InjectShell(shellcode, 357, pid);
	if (ret == 0) 
		return 0;
	else
	{
		printf("Something went wrong...Bad PID?\n");
		return -1;
	}
}

 

Save the code as ProcModUnloader.c, then:

cl ProcModUnloader.c 

Now you can run it like:

ProcModUnloader.exe [pid] [modname] ProcModUnloader.exe 1010 shimeng.dll 

 

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.