Skip to content

Instantly share code, notes, and snippets.

@andr1972
Created September 19, 2017 21:51
Show Gist options
  • Save andr1972/c780e34fbfeddc90ae1a224154502119 to your computer and use it in GitHub Desktop.
Save andr1972/c780e34fbfeddc90ae1a224154502119 to your computer and use it in GitHub Desktop.
Simple WinDebug loop
#include <cstdio>
#include <cstdlib>
#include <string>
using namespace std;
int main() {
for (unsigned int i = 0; i < 10; i++) {
fprintf(stderr, "Hello, world!\n");
}
return 0;
}
#include <Windows.h>
#include <cstdio>
//#include "udis86.h"
#include <map>
ULONG mink(ULONG a, ULONG b)
{
if (a < b) return a; else return b;
}
std::map<DWORD, HANDLE> processes;
std::map<DWORD, HANDLE> threads;
DEBUG_EVENT debug_ev;
void readMemory()
{
CONTEXT ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.ContextFlags = CONTEXT_CONTROL;
GetThreadContext(threads[debug_ev.dwThreadId], &ctx);
const ULONG kMaxInstrLength = 15;
const ULONG kSmallPageSize = (1 << 12);
BYTE opcode[kMaxInstrLength];
SIZE_T bytes_read = 0;
LPBYTE pc = (LPBYTE)ctx.Eip;//<==================
/*
ctx.Eip is 1 affter 0xcc
ctx.Eip-1 - 0xcc = int3, but I want previous opcode before set int3
*/
while (bytes_read < kMaxInstrLength) {
SIZE_T remote_bytes_read;
if (!ReadProcessMemory(processes[debug_ev.dwProcessId],
&pc[bytes_read],
&opcode[bytes_read],
mink(kMaxInstrLength-bytes_read,
(((SIZE_T)&pc[bytes_read] + kSmallPageSize) & ~(kSmallPageSize - 1))-(SIZE_T)&pc[bytes_read]),
&remote_bytes_read)) {
break;
}
bytes_read += remote_bytes_read;
}
printf("[%.8x] %x\n", ctx.Eip, opcode[0]);
/*ud_t ud_obj;
ud_init(&ud_obj);
ud_set_mode(&ud_obj, 32);
ud_set_syntax(&ud_obj, UD_SYN_INTEL);
ud_set_input_buffer(&ud_obj, opcode, bytes_read);
if (ud_disassemble(&ud_obj) > 0) {
printf("[%.8x] %s\n", ctx.Eip, ud_insn_asm(&ud_obj));
}
else {
printf("[%.8x] invalid\n", ctx.Eip);
}*/
}
BOOL SpawnAndAttachProcess(LPTSTR lpApplicationName) {
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
if (!CreateProcess(lpApplicationName, NULL,
NULL, NULL, FALSE,
DEBUG_ONLY_THIS_PROCESS,
NULL, NULL, &si, &pi)) {
return FALSE;
}
do {
DWORD cont_status;
if (!WaitForDebugEvent(&debug_ev, INFINITE)) {
break;
}
switch (debug_ev.dwDebugEventCode) {
case CREATE_PROCESS_DEBUG_EVENT:
printf("CREATE_PROCESS, id: %u, base address: %p, start address: %p\n",
debug_ev.dwProcessId,
debug_ev.u.CreateProcessInfo.lpBaseOfImage,
debug_ev.u.CreateProcessInfo.lpStartAddress);
if (debug_ev.u.CreateProcessInfo.hFile != NULL) {
CloseHandle(debug_ev.u.CreateProcessInfo.hFile);
}
processes[debug_ev.dwProcessId] = debug_ev.u.CreateProcessInfo.
hProcess;
threads[debug_ev.dwThreadId] = debug_ev.u.CreateProcessInfo.hThread;
break;
case CREATE_THREAD_DEBUG_EVENT:
printf("CREATE_THREAD, tid: %u, TLS: %p, start address: %p\n",
debug_ev.dwThreadId,
debug_ev.u.CreateThread.lpThreadLocalBase,
debug_ev.u.CreateThread.lpStartAddress);
threads[debug_ev.dwThreadId] = debug_ev.u.CreateThread.hThread;
break;
case EXCEPTION_DEBUG_EVENT:
cont_status = DBG_EXCEPTION_NOT_HANDLED;
printf("EXCEPTION, first chance: %u, code: %x, address: %p\n",
debug_ev.u.Exception.dwFirstChance,
debug_ev.u.Exception.ExceptionRecord.ExceptionCode,
debug_ev.u.Exception.ExceptionRecord.ExceptionAddress);
if (!debug_ev.u.Exception.dwFirstChance) {
TerminateProcess(processes[debug_ev.dwProcessId], 0);
}
readMemory();
break;
case EXIT_PROCESS_DEBUG_EVENT:
printf("EXIT_PROCESS, pid: %u, tid: %u, exit code: %u\n",
debug_ev.dwProcessId, debug_ev.dwThreadId,
debug_ev.u.ExitProcess.dwExitCode);
CloseHandle(processes[debug_ev.dwProcessId]);
CloseHandle(threads[debug_ev.dwThreadId]);
processes.erase(debug_ev.dwProcessId);
debug_ev.dwProcessId = 0;
threads.erase(debug_ev.dwThreadId);
debug_ev.dwThreadId = 0;
break;
case EXIT_THREAD_DEBUG_EVENT:
printf("EXIT_THREAD, tid: %u, exit code: %u\n",
debug_ev.dwThreadId,
debug_ev.u.ExitThread.dwExitCode);
CloseHandle(threads[debug_ev.dwThreadId]);
threads.erase(debug_ev.dwThreadId);
debug_ev.dwThreadId = 0;
break;
case LOAD_DLL_DEBUG_EVENT:
printf("LOAD_DLL, base address: %p\n", debug_ev.u.LoadDll.lpBaseOfDll);
if (debug_ev.u.LoadDll.hFile != NULL) {
CloseHandle(debug_ev.u.LoadDll.hFile);
}
break;
case OUTPUT_DEBUG_STRING_EVENT:
break;
case RIP_EVENT: break;
case UNLOAD_DLL_DEBUG_EVENT: break;
}
if (debug_ev.dwProcessId == 0) break;
if (debug_ev.dwThreadId == 0) break;
ContinueDebugEvent(debug_ev.dwProcessId,
debug_ev.dwThreadId,
DBG_CONTINUE);
}while (!processes.empty());
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return TRUE;
}
int main(int argc, char *argv[])
{
SpawnAndAttachProcess(L"debugged.exe");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment