Add tenketsu heap logging
git-svn-id: file:///home/svn/framework3/trunk@7340 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
70bb99b0df
commit
c7030e7705
|
@ -152,8 +152,8 @@ D. Usage:
|
||||||
b. !mushishi detect - detects several methods
|
b. !mushishi detect - detects several methods
|
||||||
c. !mushishi defeat - defeats known defeatable methods
|
c. !mushishi defeat - defeats known defeatable methods
|
||||||
|
|
||||||
4. Sympath (Import IDA map files into windbg - map files contain all custom names)
|
4. Symport (Import IDA map files into windbg - map files contain all custom names)
|
||||||
a. !sympath moduleName mapFilePath
|
a. !symport moduleName mapFilePath
|
||||||
|
|
||||||
0:001> !symport calc C:\Users\lgrenier\calc.map
|
0:001> !symport calc C:\Users\lgrenier\calc.map
|
||||||
[S] Adjusting symbols to base address of: 0x calc (00680000)
|
[S] Adjusting symbols to base address of: 0x calc (00680000)
|
||||||
|
|
|
@ -114,6 +114,9 @@ HRESULT CALLBACK jutsu(PDEBUG_CLIENT4 Client, PCSTR args) {
|
||||||
if (!_stricmp(command, "help")) {
|
if (!_stricmp(command, "help")) {
|
||||||
helpJutsu();
|
helpJutsu();
|
||||||
return (S_OK);
|
return (S_OK);
|
||||||
|
}
|
||||||
|
if (!_stricmp(command, "moduleInfo")) {
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!_stricmp(command, "memDiff")) {
|
if (!_stricmp(command, "memDiff")) {
|
||||||
bufType = strtok(NULL, " ");
|
bufType = strtok(NULL, " ");
|
||||||
|
@ -212,7 +215,7 @@ HRESULT CALLBACK jutsu(PDEBUG_CLIENT4 Client, PCSTR args) {
|
||||||
return (S_OK);
|
return (S_OK);
|
||||||
}
|
}
|
||||||
HRESULT CALLBACK tenketsu(PDEBUG_CLIENT4 Client, PCSTR args) {
|
HRESULT CALLBACK tenketsu(PDEBUG_CLIENT4 Client, PCSTR args) {
|
||||||
char *command, *heapName;
|
char *command, *heapName, *logName;
|
||||||
PVOID heapHandle;
|
PVOID heapHandle;
|
||||||
|
|
||||||
INIT_API();
|
INIT_API();
|
||||||
|
@ -224,14 +227,19 @@ HRESULT CALLBACK tenketsu(PDEBUG_CLIENT4 Client, PCSTR args) {
|
||||||
return (S_OK);
|
return (S_OK);
|
||||||
}
|
}
|
||||||
else if (!_stricmp(command, "model")) {
|
else if (!_stricmp(command, "model")) {
|
||||||
if(hookRtlHeap(1)) {
|
if(hookRtlHeap(1, NULL)) {
|
||||||
dprintf("[Byakugan] Unable to begin realtime heap modeling.\n");
|
dprintf("[Byakugan] Unable to begin realtime heap modeling.\n");
|
||||||
EXIT_API();
|
EXIT_API();
|
||||||
return (S_FALSE);
|
return (S_FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!_stricmp(command, "log")) {
|
else if (!_stricmp(command, "log")) {
|
||||||
if(hookRtlHeap(2)) {
|
logName = strtok(NULL, " ");
|
||||||
|
if (logName == NULL) {
|
||||||
|
dprintf("[Byakugan] Please provide a log name.\n");
|
||||||
|
return (S_FALSE);
|
||||||
|
}
|
||||||
|
if(hookRtlHeap(2, logName)) {
|
||||||
dprintf("[Byakugan] Unable to begin realtime heap modeling.\n");
|
dprintf("[Byakugan] Unable to begin realtime heap modeling.\n");
|
||||||
EXIT_API();
|
EXIT_API();
|
||||||
return (S_FALSE);
|
return (S_FALSE);
|
||||||
|
@ -241,10 +249,6 @@ HRESULT CALLBACK tenketsu(PDEBUG_CLIENT4 Client, PCSTR args) {
|
||||||
tenkHelp();
|
tenkHelp();
|
||||||
return (S_OK);
|
return (S_OK);
|
||||||
}
|
}
|
||||||
else if (!_stricmp(command, "help")) {
|
|
||||||
tenkHelp();
|
|
||||||
return (S_OK);
|
|
||||||
}
|
|
||||||
else if (!_stricmp(command, "validate")) {
|
else if (!_stricmp(command, "validate")) {
|
||||||
heapName = strtok(NULL, " ");
|
heapName = strtok(NULL, " ");
|
||||||
if (heapName == NULL) {
|
if (heapName == NULL) {
|
||||||
|
|
|
@ -121,13 +121,75 @@ void initializeHeapModel(struct HeapState *heapModel) {
|
||||||
heapModel->heaps = (struct HPool *) calloc(heapModel->hPoolListLen, sizeof (struct HPool));
|
heapModel->heaps = (struct HPool *) calloc(heapModel->hPoolListLen, sizeof (struct HPool));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ALLOCHEAD "<Allocation>\n"
|
||||||
|
#define ALLOCFOOT "</Allocation>\n"
|
||||||
|
#define REALLOCHEAD "<Reallocation>\n"
|
||||||
|
#define REALLOCFOOT "</Reallocation>\n"
|
||||||
|
#define FREEHEAD "<Free>\n"
|
||||||
|
#define FREEFOOT "</Free>\n"
|
||||||
|
#define HEAP "\t<Heap>0x%08x</Heap>\n"
|
||||||
|
#define ADDRESS "\t<Address>0x%08x</Address>\n"
|
||||||
|
#define RETURNPTR "\t<NewAddress>0x%08x</NewAddress>\n"
|
||||||
|
#define SIZE "\t<Size>0x%08x</Size>\n"
|
||||||
|
#define TRACEHEAD "\t<StackTrace>\n"
|
||||||
|
#define TRACEFOOT "\t</StackTrace>\n"
|
||||||
|
#define CALLADDR "\t\t<Caller>0x%08x</Caller>\n"
|
||||||
|
|
||||||
|
void hprintf(HANDLE fHandle, char *format, ...) {
|
||||||
|
char ptr[1024];
|
||||||
|
DWORD out;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
|
||||||
|
|
||||||
|
StringCbVPrintf(ptr, 1024, format, args);
|
||||||
|
WriteFile(fHandle, ptr, strlen(ptr), &out, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void logAllocate(struct HeapState *heapModel, struct AllocateStruct *aStruct) {
|
void logAllocate(struct HeapState *heapModel, struct AllocateStruct *aStruct) {
|
||||||
|
ULONG infoUsed;
|
||||||
|
|
||||||
|
WriteFile(heapModel->hLogFile, ALLOCHEAD, strlen(ALLOCHEAD), &infoUsed, NULL);
|
||||||
|
hprintf(heapModel->hLogFile, HEAP, aStruct->heapHandle);
|
||||||
|
hprintf(heapModel->hLogFile, ADDRESS, aStruct->ret);
|
||||||
|
hprintf(heapModel->hLogFile, SIZE, aStruct->size);
|
||||||
|
WriteFile(heapModel->hLogFile, TRACEHEAD, strlen(TRACEHEAD), &infoUsed, NULL);
|
||||||
|
|
||||||
|
hprintf(heapModel->hLogFile, CALLADDR, aStruct->caller);
|
||||||
|
|
||||||
|
WriteFile(heapModel->hLogFile, TRACEFOOT, strlen(TRACEFOOT), &infoUsed, NULL);
|
||||||
|
WriteFile(heapModel->hLogFile, ALLOCFOOT, strlen(ALLOCFOOT), &infoUsed, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void logReallocate(struct HeapState *heapModel, struct ReallocateStruct *rStruct) {
|
void logReallocate(struct HeapState *heapModel, struct ReallocateStruct *rStruct) {
|
||||||
|
ULONG infoUsed;
|
||||||
|
|
||||||
|
WriteFile(heapModel->hLogFile, REALLOCHEAD, strlen(REALLOCHEAD), &infoUsed, NULL);
|
||||||
|
hprintf(heapModel->hLogFile, HEAP, rStruct->heapHandle);
|
||||||
|
hprintf(heapModel->hLogFile, ADDRESS, rStruct->memoryPointer);
|
||||||
|
hprintf(heapModel->hLogFile, RETURNPTR, rStruct->ret);
|
||||||
|
hprintf(heapModel->hLogFile, SIZE, rStruct->size);
|
||||||
|
WriteFile(heapModel->hLogFile, TRACEHEAD, strlen(TRACEHEAD), &infoUsed, NULL);
|
||||||
|
|
||||||
|
hprintf(heapModel->hLogFile, CALLADDR, rStruct->caller);
|
||||||
|
|
||||||
|
WriteFile(heapModel->hLogFile, TRACEFOOT, strlen(TRACEFOOT), &infoUsed, NULL);
|
||||||
|
WriteFile(heapModel->hLogFile, ALLOCFOOT, strlen(REALLOCFOOT), &infoUsed, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void logFree(struct HeapState *heapModel, struct FreeStruct *fStruct) {
|
void logFree(struct HeapState *heapModel, struct FreeStruct *fStruct) {
|
||||||
|
ULONG infoUsed;
|
||||||
|
|
||||||
|
WriteFile(heapModel->hLogFile, FREEHEAD, strlen(FREEHEAD), &infoUsed, NULL);
|
||||||
|
hprintf(heapModel->hLogFile, HEAP, fStruct->heapHandle);
|
||||||
|
hprintf(heapModel->hLogFile, ADDRESS, fStruct->memoryPointer);
|
||||||
|
WriteFile(heapModel->hLogFile, TRACEHEAD, strlen(TRACEHEAD), &infoUsed, NULL);
|
||||||
|
|
||||||
|
hprintf(heapModel->hLogFile, CALLADDR, fStruct->caller);
|
||||||
|
|
||||||
|
WriteFile(heapModel->hLogFile, TRACEFOOT, strlen(TRACEFOOT), &infoUsed, NULL);
|
||||||
|
WriteFile(heapModel->hLogFile, FREEFOOT, strlen(FREEFOOT), &infoUsed, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void heapAllocate(struct HeapState *heapModel, struct AllocateStruct *aStruct) {
|
void heapAllocate(struct HeapState *heapModel, struct AllocateStruct *aStruct) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ struct HeapState {
|
||||||
BYTE state;
|
BYTE state;
|
||||||
ULONG numHeaps;
|
ULONG numHeaps;
|
||||||
ULONG hPoolListLen;
|
ULONG hPoolListLen;
|
||||||
|
HANDLE hLogFile;
|
||||||
struct HPool *heaps;
|
struct HPool *heaps;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -72,6 +73,7 @@ struct AllocateStruct {
|
||||||
ULONG flags;
|
ULONG flags;
|
||||||
ULONG size;
|
ULONG size;
|
||||||
PVOID ret;
|
PVOID ret;
|
||||||
|
PVOID caller;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ReallocateStruct {
|
struct ReallocateStruct {
|
||||||
|
@ -81,6 +83,7 @@ struct ReallocateStruct {
|
||||||
PVOID memoryPointer;
|
PVOID memoryPointer;
|
||||||
ULONG size;
|
ULONG size;
|
||||||
PVOID ret;
|
PVOID ret;
|
||||||
|
PVOID caller;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FreeStruct {
|
struct FreeStruct {
|
||||||
|
@ -89,6 +92,7 @@ struct FreeStruct {
|
||||||
ULONG flags;
|
ULONG flags;
|
||||||
PVOID memoryPointer;
|
PVOID memoryPointer;
|
||||||
PVOID ret;
|
PVOID ret;
|
||||||
|
PVOID caller;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CreateStruct {
|
struct CreateStruct {
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -20,13 +20,6 @@
|
||||||
* along with the nature of the overflow in question.
|
* along with the nature of the overflow in question.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Build instructions:
|
|
||||||
* C:\share\noxHeap>cl noxheap.c /LD /link "C:\Program Files\Microsoft Research\Detours Express 2.1\lib\detours.lib" "C:\Program Files\Microsoft Research\Detours Express 2.1\lib\detoured.lib"
|
|
||||||
* -------------------------
|
|
||||||
* This assumes all of the libraries for detours have been built correctly
|
|
||||||
* Please copy detours.dll into C:\WINDOWS\System32
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define NTSTATUS ULONG
|
#define NTSTATUS ULONG
|
||||||
#define BUFSIZE 4096
|
#define BUFSIZE 4096
|
||||||
/* UNDOCUMENTED HEAP STRUCTURES */
|
/* UNDOCUMENTED HEAP STRUCTURES */
|
||||||
|
@ -82,6 +75,14 @@ PVOID WINAPI noxRtlFreeHeap(PVOID heapHandle, ULONG flags, PVOID memoryPointer){
|
||||||
freeinfo.memoryPointer = memoryPointer;
|
freeinfo.memoryPointer = memoryPointer;
|
||||||
freeinfo.ret = ret;
|
freeinfo.ret = ret;
|
||||||
|
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
push ebx
|
||||||
|
mov ebx, [ebp+4]
|
||||||
|
mov freeinfo.caller, ebx
|
||||||
|
pop ebx
|
||||||
|
}
|
||||||
|
|
||||||
WriteFile(hPipe, &freeinfo, sizeof(struct FreeStruct), &bytesWritten, NULL);
|
WriteFile(hPipe, &freeinfo, sizeof(struct FreeStruct), &bytesWritten, NULL);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
|
@ -100,6 +101,14 @@ PVOID WINAPI noxRtlReallocateHeap(PVOID heapHandle, ULONG flags, PVOID memoryPoi
|
||||||
reallocinfo.size = size;
|
reallocinfo.size = size;
|
||||||
reallocinfo.ret = ret;
|
reallocinfo.ret = ret;
|
||||||
|
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
push ebx
|
||||||
|
mov ebx, [ebp+4]
|
||||||
|
mov reallocinfo.caller, ebx
|
||||||
|
pop ebx
|
||||||
|
}
|
||||||
|
|
||||||
WriteFile(hPipe, &reallocinfo, sizeof(struct ReallocateStruct), &bytesWritten, NULL);
|
WriteFile(hPipe, &reallocinfo, sizeof(struct ReallocateStruct), &bytesWritten, NULL);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
|
@ -117,6 +126,14 @@ PVOID WINAPI noxRtlAllocateHeap(PVOID heapHandle, ULONG flags, ULONG size){
|
||||||
allocinfo.size = size;
|
allocinfo.size = size;
|
||||||
allocinfo.ret = ret;
|
allocinfo.ret = ret;
|
||||||
|
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
push ebx
|
||||||
|
mov ebx, [ebp+4]
|
||||||
|
mov allocinfo.caller, ebx
|
||||||
|
pop ebx
|
||||||
|
}
|
||||||
|
|
||||||
WriteFile(hPipe, &allocinfo, sizeof(struct AllocateStruct), &bytesWritten, NULL);
|
WriteFile(hPipe, &allocinfo, sizeof(struct AllocateStruct), &bytesWritten, NULL);
|
||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
|
|
|
@ -676,7 +676,12 @@ void hunterJutsu() {
|
||||||
ULONG64 allocateMemoryBlock(unsigned long size){
|
ULONG64 allocateMemoryBlock(unsigned long size){
|
||||||
unsigned long processId = 0;
|
unsigned long processId = 0;
|
||||||
void * allocBuffer = 0;
|
void * allocBuffer = 0;
|
||||||
|
ULONG Class;
|
||||||
|
ULONG Qualifier;
|
||||||
|
|
||||||
|
g_ExtControl->GetDebuggeeType(&Class, &Qualifier);
|
||||||
|
if (Class & DEBUG_CLASS_USER_WINDOWS) {
|
||||||
|
// USER LAND!
|
||||||
if(g_ExtSystem->GetCurrentProcessSystemId(&processId) != S_OK){
|
if(g_ExtSystem->GetCurrentProcessSystemId(&processId) != S_OK){
|
||||||
dprintf("[J] failed to find process id\n");
|
dprintf("[J] failed to find process id\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -692,7 +697,10 @@ ULONG64 allocateMemoryBlock(unsigned long size){
|
||||||
CloseHandle(processHandle);
|
CloseHandle(processHandle);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// KERNEL LAND!
|
||||||
|
|
||||||
|
}
|
||||||
//CloseHandle(processHandle);
|
//CloseHandle(processHandle);
|
||||||
|
|
||||||
return ((ULONG64)allocBuffer);
|
return ((ULONG64)allocBuffer);
|
||||||
|
|
|
@ -18,6 +18,7 @@ TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
|
||||||
$(DBGSDK_LIB_PATH)\dbgeng.lib
|
$(DBGSDK_LIB_PATH)\dbgeng.lib
|
||||||
|
|
||||||
USE_MSVCRT=1
|
USE_MSVCRT=1
|
||||||
|
USE_STL=1
|
||||||
|
|
||||||
UMTYPE=windows
|
UMTYPE=windows
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ BOOLEAN running = FALSE;
|
||||||
// Two things that fucking rock? Bunnies and Jaguars. Werd.
|
// Two things that fucking rock? Bunnies and Jaguars. Werd.
|
||||||
|
|
||||||
|
|
||||||
int hookRtlHeap(BYTE type) {
|
int hookRtlHeap(BYTE type, char *fileName) {
|
||||||
HRESULT Status;
|
HRESULT Status;
|
||||||
HANDLE process;
|
HANDLE process;
|
||||||
DWORD pid;
|
DWORD pid;
|
||||||
|
@ -109,7 +109,13 @@ int hookRtlHeap(BYTE type) {
|
||||||
CloseHandle(threadHandle);
|
CloseHandle(threadHandle);
|
||||||
CloseHandle(processHandle);
|
CloseHandle(processHandle);
|
||||||
|
|
||||||
|
// Set up the log file
|
||||||
|
if (type == 2) {
|
||||||
|
heapModel.hLogFile = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (!heapModel.hLogFile) {
|
||||||
|
dprintf("[T] Unable to open file \"%s\" for writing. :(\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ typedef struct _RTL_HEAP_DEFINITION {
|
||||||
|
|
||||||
/* FUNCTIONS */
|
/* FUNCTIONS */
|
||||||
|
|
||||||
int hookRtlHeap(BYTE);
|
int hookRtlHeap(BYTE, char *);
|
||||||
int tenkListener(void);
|
int tenkListener(void);
|
||||||
void tenkListHeaps(void);
|
void tenkListHeaps(void);
|
||||||
void tenkListChunks(PVOID);
|
void tenkListChunks(PVOID);
|
||||||
|
|
Loading…
Reference in New Issue