Reputation: 99
bool bInject(uint pToBeInjected, string sDllPath)
{
IntPtr hndProc = OpenProcess((0x2 | 0x8 | 0x10 | 0x20 | 0x400), 1, pToBeInjected);
if (hndProc == INTPTR_ZERO)
{
return false;
}
IntPtr lpLLAddress = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if (lpLLAddress == INTPTR_ZERO)
{
return false;
}
IntPtr lpAddress = VirtualAllocEx(hndProc, (IntPtr)null, (IntPtr)sDllPath.Length, (0x1000 | 0x2000), 0X40);
byte[] bytes = Encoding.ASCII.GetBytes(sDllPath);
WriteProcessMemory(hndProc, lpAddress, bytes, (uint)bytes.Length, 0);
// This next one is the one that doesn't seem to work.
CreateRemoteThread(hndProc, (IntPtr)null, INTPTR_ZERO, lpLLAddress, lpAddress, 0, (IntPtr)null);
CloseHandle(hndProc);
return true;
}
I am using C#(obviously) in .NET 4.6.1 compiled for x86. In the code above I commented the command that doesn't seem to be working. The CreateRemoteThread call. No errors are returned, the the victim process (Notepad) does not show any sign of the following DLL (I pulled from an example project because I was lazy.) being injected.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
extern "C" __declspec(dllexport)
DWORD WINAPI MessageBoxThread(LPVOID lpParam) {
MessageBox(NULL, "Hello world!", "Hello World!", NULL);
return 0;
}
extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
CreateThread(NULL, NULL, MessageBoxThread, NULL, NULL, NULL);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Remember I am using windows 10. I thought maybe there were additional security checks to prevent me from injecting said DLL. After this, I plan on making a bootstrap DLL to load CLR, and another C# DLL.
Thanks so much for any help you can provide!
Upvotes: 0
Views: 926
Reputation: 124
You should use the preprocessor definitions as flags to your API calls, its more clear.
I believe for VirtualAllocEx
you attempted to pass PAGE_READWRITE
as a flag, however you passed 0x40
instead, and it's defined as #define PAGE_READWRITE 0x04
. So either use PAGE_READWRITE
directly or if you want to be "cool" use 0x04
.
Also, I never used the string class, but you should do sDllPath.Length + 1
, as it might not add the null terminator to your path as well!
To be more precise (in future questions), you can add the error code to the question! You can use:
CHAR Error[MAX_PATH]; // MAX_PATH is used for system paths, it's still big enough
wsprintfA(Error, "Error: %lu", GetLastError());
MessageBoxA(0, Error, 0, 0);
Right after your CreateRemoteThread
to get the system error code - it can help shed some light on the errors in your application, at any time!
Upvotes: 1