Jump to content
Tuts 4 You

[MSVC++]Win32 Console Dll Injector


0xFF

Recommended Posts

Pre-compiled header, and add conio.h and windows.h

if anyone needs describition on what's going on or have a question, then post here and i will be glad to help out.

// ConsoleInjector.cpp : Defines the entry point for the console application.
//#include "stdafx.h"//DWORD dwProcessId;void inject(LPCWSTR procname, LPCSTR dll_path)
{
SIZE_T BytesWritten;
HANDLE hSnap;
PROCESSENTRY32 lppe; lppe.dwSize = sizeof(lppe);
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); Process32First(hSnap, &lppe);
do
{
if( wcscmp( lppe.szExeFile, procname ) == 0 )
{
printf("Found target!\n");
break;
}
}
while( Process32Next(hSnap, &lppe) ); HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, lppe.th32ProcessID);
if( hProcess == NULL )
{
printf( "GetLastError: %d", GetLastError() );
exit( 0 );
}
LPVOID MemRegion = VirtualAllocEx(hProcess, NULL, strlen(dll_path), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if( MemRegion == NULL )
{
printf( "GetLastError: %d", GetLastError() );
exit( 0 );
}
__try
{
WriteProcessMemory(hProcess, MemRegion, (LPCVOID)dll_path, strlen(dll_path), &BytesWritten);
HANDLE remoteHandle = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA"), MemRegion, 0, NULL);
if( remoteHandle != INVALID_VALUE_HANDLE )WaitForSingleObject(remoteHandle, INFINITE);
}
__finally
{
CloseHandle(remoteHandle);
VirtualFreeEx(hProcess, MemRegion, 0, MEM_RELEASE);
CloseHandle(hProcess);
CloseHandle(hSnap);
} printf("Injected into: %d", lppe.th32ProcessID);
}int _tmain(int argc, _TCHAR* argv[])
{
WCHAR* pName[MAX_PATH];
CHAR* dll[MAX_PATH]; printf("Please enter the process name: ");
scanf_s("%s", &pName);
printf("Selected process: %s\n", pName);
printf("Please fill in .dll path: ");
scanf_s("%s", &dll);
printf("Selected .dll: %s\n", dll); inject( (LPCWSTR)pName, (LPCSTR)dll); //type cast _getch(); //waits for user input to close return 0;
}
Edited by Rot1
  • Thanks 1
Link to comment
ahmadmansoor

nice I will try to test it even i am not so good in C++ ...

but is there anyway to make an example with a good prodector like Themida or execrypter ...

mnay thanks

Edited by ahmadmansoor
Link to comment
nice I will try to test it even i am not so good in C++ ...

but is there anyway to make an example with a good prodector like Themida or execrypter ...

mnay thanks

Your welcome, and i'm not sure i understand what you mean by "with a good protector", can you describe what you ment ?

Edit: This is C, the IDE is MSVC++ 2008 (MSVS)

Edited by Rot1
Link to comment
ahmadmansoor
nice I will try to test it even i am not so good in C++ ...

but is there anyway to make an example with a good prodector like Themida or execrypter ...

mnay thanks

Your welcome, and i'm not sure i understand what you mean by "with a good protector", can you describe what you ment ?

Edit: This is C, the IDE is MSVC++ 2008 (MSVS)

hehe i forget to write "MSV" ...

about what I mean ...try to protect any file with a protector program like (thimida .or ...) then try to Inject a dll file inside it ...

and as i see form the code u will inject the code after the prog is loaded (completely) ...I think i will ask this later :happy:

Link to comment

From a brief glance this looks like it injects into a running process.... might also be nice to add an option to run a given exe and inject a dll from the start. Just an idea incase you wanted to improve it.

Link to comment
From a brief glance this looks like it injects into a running process.... might also be nice to add an option to run a given exe and inject a dll from the start. Just an idea incase you wanted to improve it.

Will be kinda pain to do it in a win32 console application, i'm working on a perfect one in Borland C++ Builder 2009. (Feature will be called Process Watcher)

Ahmadmansoor: Yes, it will inject into a protected process (Even if it's packed by anything), because it's not packed when it's being mapped into the memory (of course), and.. the problem is just disassembling the client to find the target you're looking for...

Link to comment
ahmadmansoor
From a brief glance this looks like it injects into a running process.... might also be nice to add an option to run a given exe and inject a dll from the start. Just an idea incase you wanted to improve it.

hehe LoKi :blink: ....this was my later question how u know it :happy: ...

many thanks for u I

Link to comment

I wouldn't suggest using this as it is poorly written and doesn't include error handling nor proper code flow. Your code will still attempt to inject even if the process isn't found.

@ahmadmansoor: You can inject into a process as it is loading by calling CreateProcess and passing CREATE_SUSPENDED as the creation flag. Once the process is suspended, you have the needed handles etc. within the process information variable you passed to inject your module. Once injected you can resume the processes main thread to resume normal functionality.

A small example, as taken from an example of a loader I wrote for someone else here:

#include <windows.h>
#include <tchar.h>
#include <stdio.h>int main()
{
TCHAR tszHook[ MAX_PATH ];
TCHAR tszWindows[ MAX_PATH ];
TCHAR tszMinesweeper[ MAX_PATH ]; GetCurrentDirectory( MAX_PATH, tszHook );
GetWindowsDirectory( tszWindows, MAX_PATH ); _tcscpy_s( tszMinesweeper, MAX_PATH, tszWindows );
_tcscat_s( tszMinesweeper, MAX_PATH, _T("\\system32\\winmine.exe") );
_tcscat_s( tszHook, MAX_PATH, _T("\\your_dll_name.dll") ); PROCESS_INFORMATION pi;
STARTUPINFO si; memset( π, 0x0, sizeof(PROCESS_INFORMATION) );
memset( &si, 0x0, sizeof(STARTUPINFO) );
si.cb = sizeof( STARTUPINFO ); BOOL bReturned = CreateProcess( tszMinesweeper, 0, 0, 0, FALSE, CREATE_SUSPENDED, 0, tszWindows, &si, π );
if( !bReturned ) {
_tprintf_s( _T("Failed to launch Winmine.exe") );
return 0;
} /* Inject DLL */
LPVOID lpAlloc = VirtualAllocEx( pi.hProcess, 0, _tcslen( tszHook ), MEM_COMMIT, PAGE_EXECUTE_READWRITE );
WriteProcessMemory( pi.hProcess, lpAlloc, tszHook, _tcslen( tszHook ), 0 );
HANDLE hThread = CreateRemoteThread( pi.hProcess, 0, 0, (LPTHREAD_START_ROUTINE)::GetProcAddress( GetModuleHandle( _T("kernel32") ), "LoadLibraryA" ), lpAlloc, 0, 0 ); /* Obtain Exit Code Of Thread */
DWORD dwExitCode = 0;
WaitForSingleObject( hThread, INFINITE );
GetExitCodeThread( hThread, &dwExitCode );
CloseHandle( hThread ); /* Cleanup */
VirtualFreeEx( pi.hProcess, lpAlloc, _tcslen( tszHook ), MEM_RELEASE );
ResumeThread( pi.hThread );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread ); if( !dwExitCode ) {
_tprintf_s( _T("Failed to load the DLL, injection failed.") );
} else {
_tprintf_s( _T("Injection successful.") );
} return 0;
}

There are various suggestions by many people for different sections of DLL injection on what you should/shouldn't do as well as suggested changes, code adjustments, etc. that are preferred by different people.

The example I posted here is a small, quick, and easy demonstration of getting the job done while determining if the module was loaded or not. The returned code from the thread is the base of your module (the return from LoadLibrary) which can be used to determine if the injection was successful. Keep in mind if you use techniques to hide your module, or hooks to fake returns, you can skew the results of that return so be sure to check for the module the best way that fits what you are doing.

It is also suggested not to use INFINITE for the thread wait time as this could leave your process, as well as the process you are injecting into in a deadlock. Depending on your hook, use a set time instead, in milliseconds. As a base I would recommend 10 seconds tops for a module to load if it is nothing huge. Bigger projects might require more time so use what you feel is needed.

Edited by Atomos
Link to comment

What you just posted is a loader, so it MUST check if the process is running (PROCESS_INFORMATION), a .dll injector is not a loader, and i'm sure no one will try injecting without a target.

Link to comment
What you just posted is a loader, so it MUST check if the process is running (PROCESS_INFORMATION), a .dll injector is not a loader, and i'm sure no one will try injecting without a target.

Suggest you relook at the code and rethink your post lol.

Link to comment
What you just posted is a loader, so it MUST check if the process is running (PROCESS_INFORMATION), a .dll injector is not a loader, and i'm sure no one will try injecting without a target.

Suggest you relook at the code and rethink your post lol.

Holy ****, Wiccaan ? what are you doing here... ? lol i'm suprised cause... (nvm)

Edit: lets not fight here too, cause it's not CEF.

Edited by Rot1
Link to comment
  • 1 month later...

Hey, can someone post a loader that injects efficiently a hook DLL into a packed/protected target?

Is there a generic way to accomplish this to work for most of the packers/protectors?

I have one but it's crap and works like this:

1-Loader creates the process with createprocess;

2-Loader does a Sleep(8); or Sleep(16); or whatever, depending on the time that the packer you're using takes to uncompress it's code;

3-Loader injects the hook DLL into the target process;

4-And it's able to hook the functions of the original target process;

This way it works "fine" for a specified target, but now i need a way that must work with any type of packers!

Please help!!

Link to comment

Code is flawed? Yea! Sure!

	Process32First(hSnap, &lppe);
do
{
if( wcscmp( lppe.szExeFile, procname ) == 0 )
{
printf("Found target!\n");
//BUG
}
}
while( Process32Next(hSnap, &lppe) );

Where is the break; statement?

Link to comment
Code is flawed? Yea! Sure!
	Process32First(hSnap, &lppe);
do
{
if( wcscmp( lppe.szExeFile, procname ) == 0 )
{
printf("Found target!\n");
//BUG
}
}
while( Process32Next(hSnap, &lppe) );

Where is the break; statement?

No bug no nothing, doesn't have to be a break; there, it'll stop as soon as it meets the condition.

Link to comment

The condition is Process32Next(...) == true, so it'll stop enumerating if there're no processes left. But you might want to stop earlier, since there's no need to enumerate anything anymore if you already got the process you've been searching for. I think that's what Cyclops wanted to say.

You might also want to add some further error handling, checking return values and the like. Usually, one has to include tlhelp32.h as well.

Link to comment

This code was done to inject DLL to specified process.(I hope so)

If it was so, there should bebreak statement to get the correct process.

Otherwise it will just try to inject to the last process in the process list.

There should be other verifications also.

Like whether the OpenProcess() returns a valid hadle or not!

Link to comment

Yeah, Cyclops, I messed the clarification up lol. It injects in the last - if one wanted to inject into the last found process, he could put this part:

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, lppe.th32ProcessID);

into the if(!wcscmp(...))-statement (that's how I usually do it, if not break'ing out on first process matching the criteria).

Link to comment
Then those who wanna use it will do error checking (INVALID_HANDLE_VALUE), and this sample injects to a running process

Okay! What ever you think!

This will inject to last process. so no need to check the

 wcscmp( lppe.szExeFile, procname ) == 0

If you really want to inject to a specified process, u have to break from the loop when u found the correct process.

Thanks for the heads up metr0!

Link to comment
Then those who wanna use it will do error checking (INVALID_HANDLE_VALUE), and this sample injects to a running process

Okay! What ever you think!

This will inject to last process. so no need to check the

 wcscmp( lppe.szExeFile, procname ) == 0

If you really want to inject to a specified process, u have to break from the loop when u found the correct process.

Thanks for the heads up metr0!

Calm down :o i'll edit the code and do some error checking and add the break; ok ? :unsure:

just don't get mad ! :D

Link to comment
I don't think anyone ever got mad about anything, it just seems to be part of a reverser's nature to optimize a given approach. :)

Sure!

Any way, thanks for the code :)

Link to comment
Hey, can someone post a loader that injects efficiently a hook DLL into a packed/protected target?

Is there a generic way to accomplish this to work for most of the packers/protectors?

I have one but it's crap and works like this:

1-Loader creates the process with createprocess;

2-Loader does a Sleep(8); or Sleep(16); or whatever, depending on the time that the packer you're using takes to uncompress it's code;

3-Loader injects the hook DLL into the target process;

4-And it's able to hook the functions of the original target process;

This way it works "fine" for a specified target, but now i need a way that must work with any type of packers!

Please help!!

The only "true" way to do this would be to create a debugger as a launcher to that can handle locating the [true] OEP before injecting. That way the IAT and such is built and ready for hooking and such. I don't think you will honestly ever need to be able to inject a single DLL into any type of packed executable, but rather, into specific ones.

You can locate the signature based on the byte strings found in various databases, such as PEiD's user databases to detect the packer, then use a specific code routine to "unpack" the target to get the OEP during runtime to know when it is best to inject.

Or if you don't need to inject right away, you can wait til a specific value is set in an address to inject.

@Cyclops/metr0: rot1 is known for his bad coding and constant ripping of others work. So get used to it lol. ;)

Link to comment

what's so hard about this ? i went to Wikipedia and there's a instruction of how a .dll injector works, no need to steal a source for this.

Edited by Rot1
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...