process crashes when I read/write memory with dll injection - c++

I wrote a hackme program and I want to hook it and make bruteforce to crack it (with dll injection).
the problem is when I'm trying to write or read the memory, the process crashes (its happens to me not only with the hackme program, but every program), although I give myself writing and reading privilleges with VirtualProtect.
If I add messagebox to the dll, the messagebox works.
here is the dll that supposed to prevent from the process to print something (with NOPing):
#include "DLL.h"
#include <windows.h>
#include <tlhelp32.h>
BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
DWORD threadId;
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadProc, NULL, 0, &threadId);
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return true;
}
DWORD ThreadProc(LPVOID lpdwThreadParam)
{
VirtualProtect((LPVOID)0x00417D10, 5, PAGE_EXECUTE_READWRITE, NULL);
*(char *)0x00417D10 = 0x90;
*(char *)0x00417D11 = 0x90;
*(char *)0x00417D12 = 0x90;
*(char *)0x00417D13 = 0x90;
*(char *)0x00417D14 = 0x90;
return 0;
}
here's the information about the address in the process that I'm writing to:
http://prntscr.com/2bveja (with IDA)
the dll, the injector and the hackme are compiled for 32bit.
I'm using win7 64b.

There were 2 problems:
VirtualProtect can not receive NULL in the last parameter (old privilege).
Therefore I gave it pointer to DWORD variable.
I gave the VirtualProtect a permanent address, but it was not good, since in windows 7 the image base changes every execution, so I found out the process image base and added it the offset 0x12d1.
HMODULE hand = GetModuleHandle(L"HackMe.exe");
VirtualProtect((LPVOID)((DWORD)hand + (DWORD)0x12d1), 6, PAGE_EXECUTE_READWRITE, &oldp);

Related

Why is my console not showing up when my Dll is loaded?

I have two files, the file which I'll use to load the Dll into the process is the following:
#include <Windows.h>
int main()
{
// path to our dll
LPCSTR DllPath = any_path;
// Open a handle to target process
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 26188);
// Allocate memory for the dllpath in the target process
// length of the path string + null terminator
LPVOID pDllPath = VirtualAllocEx(hProcess, 0, strlen(DllPath) + 1,
MEM_COMMIT, PAGE_READWRITE);
// Write the path to the address of the memory we just allocated
// in the target process
WriteProcessMemory(hProcess, pDllPath, (LPVOID)DllPath,
strlen(DllPath) + 1, 0);
// Create a Remote Thread in the target process which
// calls LoadLibraryA as our dllpath as an argument -> program loads our dll
HANDLE hLoadThread = CreateRemoteThread(hProcess, 0, 0,
(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("Kernel32.dll"),
"LoadLibraryA"), pDllPath, 0, 0);
// Wait for the execution of our loader thread to finish
WaitForSingleObject(hLoadThread, INFINITE);
// Free the memory allocated for our dll path
VirtualFreeEx(hProcess, pDllPath, strlen(DllPath) + 1, MEM_RELEASE);
return 0;
}
So far, it's working properly and loading the Dll into the file, however, the Dll doesn't seem to be working:
#include "pch.h"
#include <iostream>
#include <windows.h>
#include <TlHelp32.h>
DWORD WINAPI HackThread(HMODULE hModule)
{
//Create Console
AllocConsole();
FILE* f;
freopen_s(&f, "CONOUT$", "w", stdout);
std::cout << "ttt" << std::endl;
std::cin.get();
fclose(f);
FreeConsole();
FreeLibraryAndExitThread(hModule, 0);
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)HackThread, hModule, 0, nullptr);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
I know the Dll is loading properly because the process is hitting the 'DLL_PROCESS_ATTACH' case and when I tested it with a message box instead of the CreateThread, it showed up, however, I can't seem to make the console show up. What would be the problem?
One issue I see is that your thread is re-mapping only stdout to the new console, but it is not re-mapping stdin as well. So it is quite likely (use a debugger to verify this) that std::cin.get() is failing and thus not blocking the thread from closing the console immediately after creating it.

Call function from thread created via CreateRemoteThread

I'm studying dll injection and so far I managed to inject a dll in a process causing the message box to show up.
The part I didn't quite understand, even after tons of readings and research, is how I pass a parameter to the dll, or call a specific function within it.
The dll:
extern "C" __declspec(dllexport) bool WINAPI
DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
MessageBoxA(NULL, "Hello World!", "Dll says:", MB_OK);
break;
}
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return true;
}
The injection:
char dllPath[] = "sampleDll.dll";
// For dll path injection.
int memAmountToAllocate = strlen(dllPath);
LPVOID dllPathAddress = VirtualAllocEx(procHandle, 0, memAmountToAllocated, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
FARPROC loadLibraryAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
WriteProcessMemory(procHandle, dllPathAddress, dllPath, memAmountToAllocated, 0);
// creating a thread that will call LoadLibraryA with allocMemAddress as argument
CreateRemoteThread(procHandle, 0, 0, loadLibraryAddr, dllPathAddress, 0, 0);
As I said, the injection works fine, i.e. the message box appears.
But say I have a method in the dll foo(LPVOID ptrToData). How can I call the foo function?
I have the address of the function I want to execute on the target process, it is an adding function, so I need to pass x and y.
I can call the function like this
_asm
{
push 0;
push 0x7;
mov ecx, esi;
mov eax, 0x41367C;
call eax;
}
however the values for push must come from the injecting process.
How can I do that?
The solution to my problem was to use an IPC mechanism to allow my main application and dll to communicate.
I used a named pipe.
I created the pipe in C# and then when I inject the dll I connect to the pipe.

Detours: Prevent task kill of my software via another software

I have found a code that promises to intercept and detour calls to the TerminateProcess function and thus prevent my software from being killed directly from other program.
But this code is not working and I am still able to kill my process via other program.
Here is the last my attempt with a code I have found in this YouTube video:
PS: victim.exe is the killer program.
DLL
// DllRedirectAPI.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include <Windows.h>
BYTE MOV[10] = { 0x48, 0xB8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
BYTE JMP_RAX[2] = { 0xFF, 0xE0 };
#define BuffSizeX64 (sizeof(MOV) + sizeof(JMP_RAX))
BOOL Hook_Det_x64(char LibName[], char API_Name[], LPVOID NewFun) {
DWORD OldProtect;
DWORD64 OrgAddress = (DWORD64)GetProcAddress(LoadLibraryA(LibName), API_Name);
if (OrgAddress == NULL) return 0;
memcpy(&MOV[2], &NewFun, 8);
VirtualProtect((LPVOID)OrgAddress, BuffSizeX64, PAGE_EXECUTE_READWRITE, &OldProtect);
memcpy((LPVOID)OrgAddress, MOV, sizeof(MOV));
memcpy((LPVOID)(OrgAddress + sizeof(MOV)), JMP_RAX, sizeof(JMP_RAX));
VirtualProtect((LPVOID)OrgAddress, BuffSizeX64, OldProtect, &OldProtect);
return 1;
}
int WINAPI MessageBoxAX(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType) {
MessageBoxExA(0, "Hooked ...", "Mahmoud", 0, 0);
return 999;
}
BOOL WINAPI DllMain(HMODULE hModule, DWORD Call_Reason, LPVOID lpReserved) {
switch (Call_Reason) {
case DLL_PROCESS_ATTACH:
Hook_Det_x64("Kernel32.dll", "TerminateProcess", MessageBoxAX);
}
return 1;
}
INJECTOR
// Injector.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <tlhelp32.h>
#include <shlwapi.h>
#include <conio.h>
#include <stdio.h>
#include <comdef.h>
#define WIN32_LEAN_AND_MEAN
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
BOOL Inject(DWORD pID, const char * DLL_NAME);
DWORD GetTargetThreadIDFromProcName(const char * ProcName);
int main(int argc, char * argv[])
{
//############### CHANGE HERE ONLY ###################
char *Target_Process = "victim.exe"; //###
//#######################################################
char *buf;
DWORD pID = GetTargetThreadIDFromProcName(Target_Process);
buf = "DllRedirectAPI.dll";
if (!Inject(pID, buf))
{
printf("DLL Not Loaded!");
}
else{
printf("DLL is Injected in torget Process");
}
_getch();
return 0;
}
BOOL Inject(DWORD pID, const char * DLL_NAME)
{
HANDLE Proc;
char buf[50] = { 0 };
LPVOID RemoteString, LoadLibAddy;
if (!pID)
return false;
Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
if (!Proc)
{
sprintf_s(buf, "OpenProcess() failed: %d", GetLastError());
printf(buf);
return false;
}
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryA");
RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(DLL_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(Proc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME), NULL);
CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL);
CloseHandle(Proc);
return true;
}
DWORD GetTargetThreadIDFromProcName(const char * ProcName)
{
PROCESSENTRY32 pe;
HANDLE thSnapShot;
BOOL retval, ProcFound = false;
thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (thSnapShot == INVALID_HANDLE_VALUE)
{
printf("Error: Unable create toolhelp snapshot!");
return false;
}
pe.dwSize = sizeof(PROCESSENTRY32);
retval = Process32First(thSnapShot, &pe);
while (retval)
{
if (_bstr_t(pe.szExeFile) == _bstr_t(ProcName))
{
return pe.th32ProcessID;
}
retval = Process32Next(thSnapShot, &pe);
}
return 0;
}
Can someone help me, telling me where I'm making a mistake?
My system is Windows 7 Ultimate 64 Bits.
Thanks in advance.
(Wanted to write a comment, but it got quite long...)
As #AndrewMedico says in the comment: You need to hook the TerminateProcess of the Task Manager process to prevent the Task Manager from terminating anything.
I suggest you the following approach:
Try a simple DLL injection
a/ Make a DLL which prints some text in its DllMain, e.g. printf("I am here\n"); fflush(stdout);
b/ Try to inject it into some other command line process using the process hacker's Miscellaneous>Inject DLL...
c/ Verify your DLL was executed inside the target process by checking it's standard output
Try a simple API hook:
a/ Make a command line application which waits for a key and then terminates itself using some variant of TerminateProcess(GetCurrentProcess(), 1);. Add code to print some text after the TerminateProcess call.
b/ Run this application to verify the text after calling the TerminateProcess is not printed.
c/ Hook the TerminateProcess before waiting for the key using, e.g. mhook. Print some text in the replacement function and then return. Do not call the original TerminateProcess here.
d/ Run this application to verify the text inside the hook is printed and the text after the TerminateProcess call is printed as well (i.e. verify the process termination was suppressed).
Combine the results of previous steps to reach your goal:
a/ Put the hooking code from from step 2 into the DLL from step 1
b/ Inject it into the application from step 2b (i.e. the one without the hook) while it is waiting for the key and verify the text after TerminateProcess is printed.
c/ Enjoy (or debug/blame me)
Good luck!
EDIT>
OK, here is my view of what we have here:
Code in the question:
(Is an application very similar to what I suggest in "2b")
Hooks the TerminateProcess and shows a message box instead.
Should display a message box when executed
(Looks like it is a 32-bit only version)
YouTube video
Shows an application "Terminate process.exe" which terminates process given by name
After the "Injector.exe" is executed the application ceases to terminate the process and displays a message box instead (IMHO the "Injector.exe" injects a "DllFile.dll" into the running "Terminate process.exe")
Source code for the injector in the YouTube comments
This code injects DLL "C:\DllRedirectAPI.dll" into the first process with name "victim.exe" it finds
(It does not inject into "Terminate process.exe", it does not use "DllFile.dll")
Source code for the DLL in the YouTube comments
This code hooks function MessageBoxA that it shows a different message box instead. It is worth noting that the hook code itself calls the original MessageBoxA and takes the approach that it reverts the modification it did during the hooking, calls the original function and then re-applies the hook.
(It does not hook 'TerminateProcess' at all)
(Looks like it is a 32-bit only version)
64-bit version excerpts
Destructive hook of MessageBoxA (i.e. does not backup the original code)
The hook uses MessageBoxExA (which is intact) to display a different message box instead (i.e. it does not use the overwritten MessageBoxA)
(It does not hook 'TerminateProcess' at all)
(It is a 64-bit version)
Disclaimer: I am not that proficient with the topic to be 100% sure, feel free to correct/clarify me.
For the actual hooking I personally recommend to use the mhook library, which worked for me. It's documentation is worth reading as well.
See e.g. this for some alternatives (I have not tried any of them)...
EDIT>
This one works for me on Win XP inside VirtualBox:
#include <windows.h>
#include <stdio.h>
#include <mhook.h>
static BOOL WINAPI
(*_TerminateProcess)(
_In_ HANDLE hProcess,
_In_ UINT uExitCode
) = NULL;
BOOL WINAPI
TerminateProcessImpl(
_In_ HANDLE hProcess,
_In_ UINT uExitCode) {
printf("\nBlocked\n"); fflush(stdout);
return 0;
}
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved) {
if(Reason==DLL_PROCESS_ATTACH) {
printf("\nDLL attached!\n"); fflush(stdout);
HMODULE h = LoadLibrary("Kernel32");
if(h!=NULL) {
printf("\nGot Kernel32!\n"); fflush(stdout);
_TerminateProcess=(void*)GetProcAddress(h,"TerminateProcess");
if(_TerminateProcess!=NULL) {
printf("\nAbout to hook...\n"); fflush(stdout);
if(Mhook_SetHook((void*)&_TerminateProcess, &TerminateProcessImpl)) {
printf("\nHooked OK!\n"); fflush(stdout);
} else {
printf("\nHook failed!\n"); fflush(stdout);
}
}
}
}
return TRUE;
}

Dll not being loaded in Firefox but loads in custom application

I posted a recent question on SO about code injection, this one is similar but not the same. I am injecting dll into Firefox, it injects successfully but the code in the DLL doesn't run. If i inject the same code into a custom application, it works. Why might that be. This is the code that I'm using.
Injector.exe // the file that's injecting the code
#include <stdio.h>
#include <windows.h>
#define procId 2844
#define dllname "dllinject.dll" // located in same directory
int main()
{
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, false, procId);
LPVOID allocated = (LPVOID)VirtualAllocEx(hProc, NULL, strlen(dllname), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProc, (LPVOID)allocated, dllname, strlen(dllname), NULL);
LPVOID libaddr = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
CreateRemoteThread(hProc, NULL, NULL, (LPTHREAD_START_ROUTINE)libaddr, NULL, NULL);
CloseHandle(hProc);
return 0;
}
Simpleinjected.exe // the file being injected
#include <stdio.h>
int main()
{
printf("Hello");
return 0;
}
dllinject.dll
#include <windows.h>
int message(const char *msg)
{
MessageBox(NULL, msg, "Message from Dll", MB_OK);
return 0;
}
BOOL WINAPI DLLMain(HINSTANCE hInstDll, DWORD ulReason, LPVOID lpReserved)
{
switch(ulReason)
{
case DLL_PROCESS_ATTACH:
message("process attach");
break;
case DLL_THREAD_ATTACH:
message("thread attach");
break;
case DLL_PROCESS_DETACH:
message("process detach");
break;
case DLL_THREAD_DETACH:
message("thread detach");
break;
}
return true;
}
It works when injected into simpleinjected.exe but when injected in Firefox, nothing happens even though the dll is injected successfully.
I cannot reproduce your observations. I was able to inject dllinject.dll into other processes (also firefox) but I've never seen a message box.
After a bit of digging I found that your DLLMain is spelled wrong. Change it into DllMain and you'll see message boxes in Firefox.
By the way: You propably want to change MessageBox into MessageBeep since FireFox creates/destroys a lot of threads... (this is annoying even for a quick test!)

CreateProcessWithDLLEx-Hooked process starts but can't resume

Im trying to get a basic hook going using microsoft detours. My program is able to successfully run CreateProcessWithDllEx and inject a dll. However, I cannot seem to resume the actual hooked program. I am using notepad for testing and I can see notepad.exe running in my process list, but the notepad window never actually comes up.
my dll is as follows:
#undef UNICODE
#include <cstdio>
#include <windows.h>
#include <detours.h>
#pragma comment(lib, "detours.lib")
typedef void (WINAPI *pFunc)(void);
DWORD WINAPI MyFunc(void);
pFunc FuncToDetour = (pFunc)DetourFindFunction("Winmm.dll", "timeGetTime"); //Set it at address to detour in
//the process
extern "C" __declspec( dllexport )VOID NullExport( VOID )
{
}
INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
switch(Reason)
{
case DLL_PROCESS_ATTACH:
{
DisableThreadLibraryCalls(hDLL);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
//DetourAttach(&(PVOID&)FuncToDetour, MyFunc);
//DetourTransactionCommit();
}
break;
case DLL_PROCESS_DETACH:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)FuncToDetour, MyFunc);
DetourTransactionCommit();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
DWORD WINAPI MyFunc()
{
return 0;
}
And my injector is as follows:
#undef _UNICODE
#include "stdafx.h"
#include <cstdio>
#include <windows.h>
#include <detours.h>
int main()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(STARTUPINFO));
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
si.cb = sizeof(STARTUPINFO);
WCHAR DirPath[MAX_PATH+1];
wcscpy_s(DirPath, MAX_PATH, L"C:\\Documents and Settings\\Administrator\\My Documents\\Visual Studio 2010\\Projects\\hbotinjector\\Release");
char DLLPath[MAX_PATH+1] = "C:\\Documents and Settings\\Administrator\\My Documents\\Visual Studio 2010\\Projects\\hbotinjector\\Release\\hbotdll.dll";
WCHAR EXE[MAX_PATH+1]={0};
wcscpy_s( EXE, MAX_PATH, L"C:\\Documents and Settings\\Administrator\\My Documents\\Visual Studio 2010\\Projects\\hbotinjector\\Release\\notepad.exe" );
STARTUPINFO _StartupInfo;
PROCESS_INFORMATION _Information;
ZeroMemory( &_Information, sizeof( PROCESS_INFORMATION ) );
if(DetourCreateProcessWithDllEx( EXE, NULL, NULL, NULL, TRUE,
CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED, NULL, DirPath, &_StartupInfo, &_Information,
DLLPath, NULL ))
{
MessageBoxA(NULL,"INJECTED", NULL, NULL);
ResumeThread(_Information.hThread);
WaitForSingleObject(_Information.hProcess, INFINITE);
}
else
{
char error[100];
sprintf(error, "%d", GetLastError());
MessageBoxA(NULL, error, NULL, NULL);
}
return 0;
}
And I build my dll with a .def file, insuring that there is the required function at ordinal 1 for detours to work properly:
LIBRARY HBOTDLL
EXPORTS
NullExport #1
Does anyone know what is causing the process from not running? As a side note, I've tried it with a blank dll as well where it just contains the required function at ordinal 1 and nothing else and it seems to have identical results.
Also, my injector runs forever as long as the notepad.exe process is showing in the process list. This is in response to WaitForSingleObject, which seems to indicate the process has been spawned correctly.
On the comment of Hans Passant, I went back and realized that I had declared pi and si as well as _Information and _StartupInfo. I wasn't zeroing out the second group I had created, and that was the group I was using. So I changed the call to CreateProcessWithDllEx to use &pi and &si. Everything works fine now.