I'm a novice when it comes to RE but I'm trying to get into it. I have a background in C/C++ so doing the development side of things should be a breeze (aside from when assembly has to be used, im rusty there). I just need to be pointed in the right direction with RE things and will be able to pick things up from there.
I wrote a simple CLI program (HackMe.exe) to practice RE with, using OllyDbg. It just has a string("change me") which I'm attempting to change (patch?) via a DLL.
Here's the CLI prog source
#include <iostream>
#include <string>
#include <Windows.h>
int main(int argc, char** argv) {
char* change_me = "change me";
while(true) {
std::cout << change_me << std::endl;
Sleep(3000);
}
return 0;
}
and the DLL source so far which is bare bone
#include <Windows.h>
#include <fstream>
#include <iostream>
VOID attach();
BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
switch(reason) {
case DLL_PROCESS_ATTACH: {
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&attach, 0, 0, 0);
break;
}
}
return TRUE;
}
VOID attach() {
// patching code will go here
}
So far what I've done is
- Attached OllyDbg to running HackMe.exe process
- Searched for all referenced text strings and followed the "change me" string
Following the the string brought me to where the string was found
So correct me if I'm wrong or not including something but I believe I need to
- Find the base address of the process and the offset to the string address
- Patch the memory at base + offset with a new string thats len is == to the original
So i guess my questions are
- How do I find the base offset of process (I assume I can do in the DLL using something like GetModuleHandle("HackMe.exe"))?
- Is there a way to see the base offset in OllyDbg (not that useful I suppose since the base will more than likely change every time the exe is ran)?
- How do I find the +offset of the string from the base?
Working end result
#include <Windows.h>
VOID attach();
BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
switch(reason) {
case DLL_PROCESS_ATTACH: {
attach();
break;
}
}
return TRUE;
}
VOID attach() {
DWORD old;
DWORD base = (DWORD)GetModuleHandle(NULL);
DWORD offset = 0x01CC80;
char* ptr = reinterpret_cast<char*>(base + offset);
const size_t length = 10;
char buffer[ length ] = "changed:)";
VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old);
memcpy(ptr, buffer, length);
VirtualProtect(ptr, length, old, nullptr);
}