Created
September 19, 2017 21:51
-
-
Save andr1972/c780e34fbfeddc90ae1a224154502119 to your computer and use it in GitHub Desktop.
Simple WinDebug loop
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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