536 lines
28 KiB
C
536 lines
28 KiB
C
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
|
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
|
│ │
|
|
│ This program is free software; you can redistribute it and/or modify │
|
|
│ it under the terms of the GNU General Public License as published by │
|
|
│ the Free Software Foundation; version 2 of the License. │
|
|
│ │
|
|
│ This program is distributed in the hope that it will be useful, but │
|
|
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
|
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
|
│ General Public License for more details. │
|
|
│ │
|
|
│ You should have received a copy of the GNU General Public License │
|
|
│ along with this program; if not, write to the Free Software │
|
|
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
|
│ 02110-1301 USA │
|
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
|
#include "libc/bits/safemacros.internal.h"
|
|
#include "libc/calls/calls.h"
|
|
#include "libc/calls/internal.h"
|
|
#include "libc/dce.h"
|
|
#include "libc/log/log.h"
|
|
#include "libc/nt/dll.h"
|
|
#include "libc/nt/enum/filetype.h"
|
|
#include "libc/nt/enum/startf.h"
|
|
#include "libc/nt/files.h"
|
|
#include "libc/nt/process.h"
|
|
#include "libc/nt/runtime.h"
|
|
#include "libc/nt/struct/ldr.h"
|
|
#include "libc/nt/struct/ldrdatatableentry.h"
|
|
#include "libc/nt/struct/linkedlist.h"
|
|
#include "libc/nt/struct/peb.h"
|
|
#include "libc/nt/struct/systeminfo.h"
|
|
#include "libc/nt/struct/teb.h"
|
|
#include "libc/nt/struct/unicodestring.h"
|
|
#include "libc/runtime/runtime.h"
|
|
#include "libc/stdio/stdio.h"
|
|
#include "libc/sysv/consts/madv.h"
|
|
#include "libc/sysv/consts/o.h"
|
|
#include "tool/decode/lib/flagger.h"
|
|
#include "tool/decode/lib/idname.h"
|
|
|
|
char *GetString(struct NtUnicodeString *s) {
|
|
static char buf[1024];
|
|
unsigned len = min(sizeof(buf) - 1, s->Length);
|
|
for (unsigned i = 0; i < len; ++i) {
|
|
buf[i] = (unsigned char)s->Data[i];
|
|
}
|
|
buf[len] = '\0';
|
|
return &buf[0];
|
|
}
|
|
|
|
int NextBestThing(void) {
|
|
int64_t fd = open("/proc/self/maps", O_RDONLY);
|
|
posix_fadvise(fd, 0, 0, MADV_SEQUENTIAL);
|
|
ssize_t wrote;
|
|
while ((wrote = copyfd(fd, NULL, 1, NULL, 1024 * 64, 0)) != -1) {
|
|
if (wrote == 0) break;
|
|
}
|
|
close(fd);
|
|
return 0;
|
|
}
|
|
|
|
const struct IdName kNtStartfFlagNames[] = {
|
|
{kNtStartfUseshowwindow, "kNtStartfUseshowwindow"},
|
|
{kNtStartfUsesize, "kNtStartfUsesize"},
|
|
{kNtStartfUseposition, "kNtStartfUseposition"},
|
|
{kNtStartfUsecountchars, "kNtStartfUsecountchars"},
|
|
{kNtStartfUsefillattribute, "kNtStartfUsefillattribute"},
|
|
{kNtStartfRunfullscreen, "kNtStartfRunfullscreen"},
|
|
{kNtStartfForceonfeedback, "kNtStartfForceonfeedback"},
|
|
{kNtStartfForceofffeedback, "kNtStartfForceofffeedback"},
|
|
{kNtStartfUsestdhandles, "kNtStartfUsestdhandles"},
|
|
{kNtStartfUsehotkey, "kNtStartfUsehotkey"},
|
|
{kNtStartfTitleislinkname, "kNtStartfTitleislinkname"},
|
|
{kNtStartfTitleisappid, "kNtStartfTitleisappid"},
|
|
{kNtStartfPreventpinning, "kNtStartfPreventpinning"},
|
|
{kNtStartfUntrustedsource, "kNtStartfUntrustedsource"},
|
|
{0, 0},
|
|
};
|
|
|
|
void PrintStartupInfo(void) {
|
|
printf("\n\
|
|
╔──────────────────────────────────────────────────────────────────────────────╗\n\
|
|
│ new technology § startup info │\n\
|
|
╚──────────────────────────────────────────────────────────────────────────────╝\n\
|
|
\n");
|
|
#define X(D, F) \
|
|
printf("%s.%-22s= " D "\n", "g_ntstartupinfo", #F, g_ntstartupinfo.F);
|
|
X("%u", cb);
|
|
X("%p", lpReserved);
|
|
X("%hs", lpDesktop);
|
|
X("%hs", lpTitle);
|
|
X("%u", dwX);
|
|
X("%u", dwY);
|
|
X("%u", dwXSize);
|
|
X("%u", dwYSize);
|
|
X("%u", dwXCountChars);
|
|
X("%u", dwYCountChars);
|
|
X("%u", dwFillAttribute);
|
|
printf("%s.%-22s: %s\n", "g_ntstartupinfo", "dwFlags",
|
|
RecreateFlags(kNtStartfFlagNames, g_ntstartupinfo.dwFlags));
|
|
X("%hu", wShowWindow);
|
|
X("%hu", cbReserved2);
|
|
X("%s", lpReserved2);
|
|
X("%ld", hStdInput);
|
|
X("%ld", hStdOutput);
|
|
X("%ld", hStdError);
|
|
#undef X
|
|
}
|
|
|
|
void PrintSystemInfo(void) {
|
|
printf("\n\
|
|
╔──────────────────────────────────────────────────────────────────────────────╗\n\
|
|
│ new technology § system info │\n\
|
|
╚──────────────────────────────────────────────────────────────────────────────╝\n\
|
|
\n");
|
|
#define X(D, F) \
|
|
printf("%s.%-28s= " D "\n", "g_ntsysteminfo", #F, g_ntsysteminfo.F);
|
|
X("%08x", dwOemId);
|
|
X("%04hx", wProcessorArchitecture);
|
|
X("%d", dwPageSize);
|
|
X("%p", lpMinimumApplicationAddress);
|
|
X("%p", lpMaximumApplicationAddress);
|
|
X("%p", dwActiveProcessorMask);
|
|
X("%u", dwNumberOfProcessors);
|
|
X("%u", dwProcessorType);
|
|
X("%u", dwAllocationGranularity);
|
|
X("%hu", wProcessorLevel);
|
|
X("%hu", wProcessorRevision);
|
|
#undef X
|
|
}
|
|
|
|
const char *ft2str(int ft) {
|
|
if (ft == kNtFileTypeUnknown) return "kNtFileTypeUnknown";
|
|
if (ft == kNtFileTypeDisk) return "kNtFileTypeDisk";
|
|
if (ft == kNtFileTypeChar) return "kNtFileTypeChar";
|
|
if (ft == kNtFileTypePipe) return "kNtFileTypePipe";
|
|
if (ft == kNtFileTypeRemote) return "kNtFileTypeRemote";
|
|
return "wut?";
|
|
}
|
|
|
|
void PrintStdioInfo(void) {
|
|
printf("\n\
|
|
╔──────────────────────────────────────────────────────────────────────────────╗\n\
|
|
│ new technology § stdio info │\n\
|
|
╚──────────────────────────────────────────────────────────────────────────────╝\n\
|
|
\n");
|
|
printf("%s: %ld (%s)\n", "g_fds.p[0].handle", g_fds.p[0].handle,
|
|
ft2str(GetFileType(g_fds.p[0].handle)));
|
|
printf("%s: %ld (%s)\n", "g_fds.p[1].handle", g_fds.p[1].handle,
|
|
ft2str(GetFileType(g_fds.p[1].handle)));
|
|
printf("%s: %ld (%s)\n", "g_fds.p[2].handle", g_fds.p[2].handle,
|
|
ft2str(GetFileType(g_fds.p[2].handle)));
|
|
}
|
|
|
|
void PrintTeb(void) {
|
|
GetCurrentProcessId();
|
|
SetLastError(0x1234);
|
|
printf("\n\
|
|
╔──────────────────────────────────────────────────────────────────────────────╗\n\
|
|
│ new technology § teb? │\n\
|
|
╚──────────────────────────────────────────────────────────────────────────────╝\n\
|
|
\n");
|
|
printf("gs:0x%02x: %-39s = 0x%lx\n", 0x00, "NtGetSeh()", _NtGetSeh());
|
|
printf("gs:0x%02x: %-39s = 0x%lx\n", 0x08, "NtGetStackHigh()",
|
|
_NtGetStackHigh());
|
|
printf("gs:0x%02x: %-39s = 0x%lx\n", 0x10, "NtGetStackLow()",
|
|
_NtGetStackLow());
|
|
printf("gs:0x%02x: %-39s = 0x%lx\n", 0x18, "_NtGetSubsystemTib()",
|
|
_NtGetSubsystemTib());
|
|
printf("gs:0x%02x: %-39s = 0x%lx\n", 0x20, "NtGetFib()", _NtGetFib());
|
|
printf("gs:0x%02x: %-39s = 0x%lx\n", 0x30, "NtGetTeb()", NtGetTeb());
|
|
printf("gs:0x%02x: %-39s = 0x%lx\n", 0x38, "NtGetEnv()", _NtGetEnv());
|
|
printf("gs:0x%02x: %-39s = 0x%lx\n", 0x40, "NtGetPid()", NtGetPid());
|
|
printf("gs:0x%02x: %-39s = 0x%lx\n", 0x48, "NtGetTid()", NtGetTid());
|
|
printf("gs:0x%02x: %-39s = 0x%lx\n", 0x50, "NtGetRpc()", _NtGetRpc());
|
|
printf("gs:0x%02x: %-39s = 0x%lx\n", 0x58, "NtGetTls()", _NtGetTls());
|
|
printf("gs:0x%02x: %-39s = 0x%lx\n", 0x60, "NtGetPeb()", NtGetPeb());
|
|
printf("gs:0x%02x: %-39s = 0x%lx\n", 0x68, "NtGetErr()", NtGetErr());
|
|
}
|
|
|
|
void PrintPeb(void) {
|
|
struct NtPeb *peb = NtGetPeb();
|
|
printf("\n\
|
|
╔──────────────────────────────────────────────────────────────────────────────╗\n\
|
|
│ new technology § peb │\n\
|
|
╚──────────────────────────────────────────────────────────────────────────────╝\n\
|
|
\n");
|
|
printf("0x%04x: %-40s = %u\n", offsetof(struct NtPeb, InheritedAddressSpace),
|
|
"InheritedAddressSpace", (unsigned)peb->InheritedAddressSpace);
|
|
printf("0x%04x: %-40s = %u\n",
|
|
offsetof(struct NtPeb, ReadImageFileExecOptions),
|
|
"ReadImageFileExecOptions", (unsigned)peb->ReadImageFileExecOptions);
|
|
printf("0x%04x: %-40s = %u\n", offsetof(struct NtPeb, BeingDebugged),
|
|
"BeingDebugged", (unsigned)peb->BeingDebugged);
|
|
printf("0x%04x: %-40s = %u\n", offsetof(struct NtPeb, __wut1), "__wut1",
|
|
(unsigned)peb->__wut1);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, Mutant), "Mutant",
|
|
peb->Mutant);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, ImageBaseAddress),
|
|
"ImageBaseAddress", peb->ImageBaseAddress);
|
|
/* struct NtLdr *Ldr; */
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, ProcessParameters),
|
|
"ProcessParameters", peb->ProcessParameters);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, SubSystemData),
|
|
"SubSystemData", peb->SubSystemData);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, ProcessHeap),
|
|
"ProcessHeap", peb->ProcessHeap);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, FastPebLock),
|
|
"FastPebLock", peb->FastPebLock);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, __wut3), "__wut3",
|
|
peb->__wut3);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, __wut4), "__wut4",
|
|
peb->__wut4);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, __wut5), "__wut5",
|
|
peb->__wut5);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, KernelCallbackTable),
|
|
"KernelCallbackTable", peb->KernelCallbackTable);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, UserSharedInfoPtr),
|
|
"UserSharedInfoPtr", peb->UserSharedInfoPtr);
|
|
printf("0x%04x: %-40s = 0x%x\n", offsetof(struct NtPeb, SystemReserved),
|
|
"SystemReserved", peb->SystemReserved);
|
|
printf("0x%04x: %-40s = 0x%x\n", offsetof(struct NtPeb, __wut6), "__wut6",
|
|
peb->__wut6);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, __wut7), "__wut7",
|
|
peb->__wut7);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, TlsExpansionCounter),
|
|
"TlsExpansionCounter", peb->TlsExpansionCounter);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, TlsBitmap),
|
|
"TlsBitmap", peb->TlsBitmap);
|
|
printf("0x%04x: %-40s = 0x%x 0x%x\n", offsetof(struct NtPeb, TlsBitmapBits),
|
|
"TlsBitmapBits", peb->TlsBitmapBits[0], peb->TlsBitmapBits[1]);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtPeb, ReadOnlySharedMemoryBase),
|
|
"ReadOnlySharedMemoryBase", peb->ReadOnlySharedMemoryBase);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, __wut8), "__wut8",
|
|
peb->__wut8);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtPeb, ReadOnlyStaticServerData),
|
|
"ReadOnlyStaticServerData", peb->ReadOnlyStaticServerData);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, AnsiCodePageData),
|
|
"AnsiCodePageData", peb->AnsiCodePageData);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, OemCodePageData),
|
|
"OemCodePageData", peb->OemCodePageData);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtPeb, UnicodeCaseTableData), "UnicodeCaseTableData",
|
|
peb->UnicodeCaseTableData);
|
|
printf("0x%04x: %-40s = 0x%x\n", offsetof(struct NtPeb, NumberOfProcessors),
|
|
"NumberOfProcessors", peb->NumberOfProcessors);
|
|
printf("0x%04x: %-40s = 0x%x\n", offsetof(struct NtPeb, NtGlobalFlag),
|
|
"NtGlobalFlag", peb->NtGlobalFlag);
|
|
printf("0x%04x: %-40s = %ld\n",
|
|
offsetof(struct NtPeb, CriticalSectionTimeout),
|
|
"CriticalSectionTimeout", peb->CriticalSectionTimeout);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, HeapSegmentReserve),
|
|
"HeapSegmentReserve", peb->HeapSegmentReserve);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, HeapSegmentCommit),
|
|
"HeapSegmentCommit", peb->HeapSegmentCommit);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtPeb, HeapDeCommitTotalFreeThreshold),
|
|
"HeapDeCommitTotalFreeThreshold", peb->HeapDeCommitTotalFreeThreshold);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtPeb, HeapDeCommitFreeBlockThreshold),
|
|
"HeapDeCommitFreeBlockThreshold", peb->HeapDeCommitFreeBlockThreshold);
|
|
printf("0x%04x: %-40s = 0x%x\n", offsetof(struct NtPeb, NumberOfHeaps),
|
|
"NumberOfHeaps", peb->NumberOfHeaps);
|
|
printf("0x%04x: %-40s = 0x%x\n", offsetof(struct NtPeb, MaximumNumberOfHeaps),
|
|
"MaximumNumberOfHeaps", peb->MaximumNumberOfHeaps);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, ProcessHeaps),
|
|
"ProcessHeaps", peb->ProcessHeaps);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtPeb, GdiSharedHandleTable), "GdiSharedHandleTable",
|
|
peb->GdiSharedHandleTable);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtPeb, ProcessStarterHelper), "ProcessStarterHelper",
|
|
peb->ProcessStarterHelper);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, GdiDCAttributeList),
|
|
"GdiDCAttributeList", peb->GdiDCAttributeList);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, LoaderLock),
|
|
"LoaderLock", peb->LoaderLock);
|
|
printf("0x%04x: %-40s = 0x%x\n", offsetof(struct NtPeb, OSMajorVersion),
|
|
"OSMajorVersion", peb->OSMajorVersion);
|
|
printf("0x%04x: %-40s = 0x%x\n", offsetof(struct NtPeb, OSMinorVersion),
|
|
"OSMinorVersion", peb->OSMinorVersion);
|
|
printf("0x%04x: %-40s = %hu\n", offsetof(struct NtPeb, OSBuildNumber),
|
|
"OSBuildNumber", peb->OSBuildNumber);
|
|
printf("0x%04x: %-40s = %hu\n", offsetof(struct NtPeb, OSCSDVersion),
|
|
"OSCSDVersion", peb->OSCSDVersion);
|
|
printf("0x%04x: %-40s = 0x%x\n", offsetof(struct NtPeb, OSPlatformId),
|
|
"OSPlatformId", peb->OSPlatformId);
|
|
printf("0x%04x: %-40s = 0x%x\n", offsetof(struct NtPeb, ImageSubsystem),
|
|
"ImageSubsystem", peb->ImageSubsystem);
|
|
printf("0x%04x: %-40s = 0x%x\n",
|
|
offsetof(struct NtPeb, ImageSubsystemMajorVersion),
|
|
"ImageSubsystemMajorVersion", peb->ImageSubsystemMajorVersion);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtPeb, ImageSubsystemMinorVersion),
|
|
"ImageSubsystemMinorVersion", peb->ImageSubsystemMinorVersion);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtPeb, ImageProcessAffinityMask),
|
|
"ImageProcessAffinityMask", peb->ImageProcessAffinityMask);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtPeb, ActiveProcessAffinityMask),
|
|
"ActiveProcessAffinityMask", peb->ActiveProcessAffinityMask);
|
|
/* "0x%lx", GdiHandleBuffer[38 - __SIZEOF_POINTER__]; */
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtPeb, PostProcessInitRoutine),
|
|
"PostProcessInitRoutine", peb->PostProcessInitRoutine);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, TlsExpansionBitmap),
|
|
"TlsExpansionBitmap", peb->TlsExpansionBitmap);
|
|
/* "0x%x", TlsExpansionBitmapBits[32]; */
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, SessionId),
|
|
"SessionId", peb->SessionId);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, AppCompatFlags),
|
|
"AppCompatFlags", peb->AppCompatFlags);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, AppCompatFlagsUser),
|
|
"AppCompatFlagsUser", peb->AppCompatFlagsUser);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, pShimData),
|
|
"pShimData", peb->pShimData);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, AppCompatInfo),
|
|
"AppCompatInfo", peb->AppCompatInfo);
|
|
printf("0x%04x: %-40s = \"%s\"\n", offsetof(struct NtPeb, CSDVersion),
|
|
"CSDVersion", GetString(&peb->CSDVersion));
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtPeb, ActivationContextData), "ActivationContextData",
|
|
peb->ActivationContextData);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtPeb, ProcessAssemblyStorageMap),
|
|
"ProcessAssemblyStorageMap", peb->ProcessAssemblyStorageMap);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtPeb, SystemDefaultActivationContextData),
|
|
"SystemDefaultActivationContextData",
|
|
peb->SystemDefaultActivationContextData);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtPeb, SystemAssemblyStorageMap),
|
|
"SystemAssemblyStorageMap", peb->SystemAssemblyStorageMap);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, MinimumStackCommit),
|
|
"MinimumStackCommit", peb->MinimumStackCommit);
|
|
}
|
|
|
|
void PrintPebLdr(void) {
|
|
printf("\n\
|
|
╔──────────────────────────────────────────────────────────────────────────────╗\n\
|
|
│ new technology § peb » ldr │\n\
|
|
╚──────────────────────────────────────────────────────────────────────────────╝\n\
|
|
\n");
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtLdr, SizeOfThis),
|
|
"SizeOfThis", NtGetPeb()->Ldr->SizeOfThis);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtLdr, IsInitialized),
|
|
"IsInitialized", NtGetPeb()->Ldr->IsInitialized);
|
|
printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtLdr, SsHandle),
|
|
"SsHandle", NtGetPeb()->Ldr->SsHandle);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtLdr, InLoadOrderModuleList), "InLoadOrderModuleList",
|
|
NtGetPeb()->Ldr->InLoadOrderModuleList);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtLdr, InMemoryOrderModuleList),
|
|
"InMemoryOrderModuleList", NtGetPeb()->Ldr->InMemoryOrderModuleList);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtLdr, InInitOrderModuleList), "InInitOrderModuleList",
|
|
NtGetPeb()->Ldr->InInitOrderModuleList);
|
|
}
|
|
|
|
void PrintModulesLoadOrder(void) {
|
|
{
|
|
printf("\n\
|
|
╔──────────────────────────────────────────────────────────────────────────────╗\n\
|
|
│ new technology § modules » load order │\n\
|
|
╚──────────────────────────────────────────────────────────────────────────────╝\n\
|
|
\n");
|
|
struct NtLinkedList *head = &NtGetPeb()->Ldr->InLoadOrderModuleList;
|
|
struct NtLinkedList *ldr = head->Next;
|
|
do {
|
|
const struct NtLdrDataTableEntry *dll =
|
|
(const struct NtLdrDataTableEntry *)ldr;
|
|
/* struct NtLinkedList InLoadOrderLinks; /\* msdn:reserved *\/ */
|
|
/* struct NtLinkedList InMemoryOrderLinks; */
|
|
/* struct NtLinkedList InInitOrderLinks; /\* msdn:reserved *\/ */
|
|
printf("0x%p\n", ldr);
|
|
printf("0x%p vs. 0x%p\n", dll, GetModuleHandleW(dll->FullDllName.Data));
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtLdrDataTableEntry, DllBase), "DllBase",
|
|
dll->DllBase);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtLdrDataTableEntry, EntryPoint), "EntryPoint",
|
|
dll->EntryPoint);
|
|
printf("0x%04x: %-40s = 0x%x\n",
|
|
offsetof(struct NtLdrDataTableEntry, SizeOfImage), "SizeOfImage",
|
|
dll->SizeOfImage);
|
|
printf("0x%04x: %-40s = \"%s\"\n",
|
|
offsetof(struct NtLdrDataTableEntry, FullDllName), "FullDllName",
|
|
GetString(&dll->FullDllName));
|
|
printf("0x%04x: %-40s = \"%s\"\n",
|
|
offsetof(struct NtLdrDataTableEntry, BaseDllName), "BaseDllName",
|
|
GetString(&dll->BaseDllName));
|
|
printf("0x%04x: %-40s = 0x%x\n",
|
|
offsetof(struct NtLdrDataTableEntry, Flags), "Flags", dll->Flags);
|
|
printf("0x%04x: %-40s = %hu\n",
|
|
offsetof(struct NtLdrDataTableEntry, Load_Count), "Load_Count",
|
|
dll->Load_Count);
|
|
printf("0x%04x: %-40s = %hu\n",
|
|
offsetof(struct NtLdrDataTableEntry, TlsIndex), "TlsIndex",
|
|
dll->TlsIndex);
|
|
/* union { */
|
|
/* struct NtLinkedList HashLinks; */
|
|
/* struct { */
|
|
/* void *SectionPointer; */
|
|
/* uint32_t CheckSum; */
|
|
/* }; */
|
|
/* }; */
|
|
/* union { */
|
|
/* void *LoadedImports; */
|
|
/* uint32_t TimeDateStamp; */
|
|
/* }; */
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtLdrDataTableEntry, EntryPointActivationContext),
|
|
"EntryPointActivationContext", dll->EntryPointActivationContext);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtLdrDataTableEntry, PatchInformation),
|
|
"PatchInformation", dll->PatchInformation);
|
|
/* struct NtLinkedList ForwarderLinks; */
|
|
/* struct NtLinkedList ServiceTagLinks; */
|
|
/* struct NtLinkedList StaticLinks; */
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtLdrDataTableEntry, ContextInformation),
|
|
"ContextInformation", dll->ContextInformation);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtLdrDataTableEntry, OriginalBase), "OriginalBase",
|
|
dll->OriginalBase);
|
|
printf("0x%04x: %-40s = %ld\n",
|
|
offsetof(struct NtLdrDataTableEntry, LoadTime), "LoadTime",
|
|
dll->LoadTime);
|
|
printf("\n");
|
|
} while ((ldr = ldr->Next) && ldr != head);
|
|
}
|
|
}
|
|
|
|
void PrintModulesMemoryOrder(void) {
|
|
{
|
|
printf("\n\
|
|
╔──────────────────────────────────────────────────────────────────────────────╗\n\
|
|
│ new technology § modules » memory order │\n\
|
|
╚──────────────────────────────────────────────────────────────────────────────╝\n\
|
|
\n");
|
|
struct NtLinkedList *head = &NtGetPeb()->Ldr->InMemoryOrderModuleList;
|
|
struct NtLinkedList *ldr = head->Next;
|
|
do {
|
|
const struct NtLdrDataTableEntry *dll =
|
|
(const struct NtLdrDataTableEntry *)ldr;
|
|
/* struct NtLinkedList InLoadOrderLinks; /\* msdn:reserved *\/ */
|
|
/* struct NtLinkedList InMemoryOrderLinks; */
|
|
/* struct NtLinkedList InInitOrderLinks; /\* msdn:reserved *\/ */
|
|
printf("0x%p\n", dll);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtLdrDataTableEntry, DllBase), "DllBase",
|
|
dll->DllBase);
|
|
printf("0x%04x: %-40s = 0x%lx\n",
|
|
offsetof(struct NtLdrDataTableEntry, EntryPoint), "EntryPoint",
|
|
dll->EntryPoint);
|
|
printf("0x%04x: %-40s = 0x%x\n",
|
|
offsetof(struct NtLdrDataTableEntry, SizeOfImage), "SizeOfImage",
|
|
dll->SizeOfImage);
|
|
printf("0x%04x: %-40s = \"%s\"\n",
|
|
offsetof(struct NtLdrDataTableEntry, FullDllName), "FullDllName",
|
|
GetString(&dll->FullDllName));
|
|
printf("0x%04x: %-40s = \"%s\"\n",
|
|
offsetof(struct NtLdrDataTableEntry, BaseDllName), "BaseDllName",
|
|
GetString(&dll->BaseDllName));
|
|
printf("0x%04x: %-40s = 0x%x\n",
|
|
offsetof(struct NtLdrDataTableEntry, Flags), "Flags", dll->Flags);
|
|
printf("0x%04x: %-40s = %hu\n",
|
|
offsetof(struct NtLdrDataTableEntry, Load_Count), "Load_Count",
|
|
dll->Load_Count);
|
|
printf("0x%04x: %-40s = %hu\n",
|
|
offsetof(struct NtLdrDataTableEntry, TlsIndex), "TlsIndex",
|
|
dll->TlsIndex);
|
|
/* /\* union { *\/ */
|
|
/* /\* struct NtLinkedList HashLinks; *\/ */
|
|
/* /\* struct { *\/ */
|
|
/* /\* void *SectionPointer; *\/ */
|
|
/* /\* uint32_t CheckSum; *\/ */
|
|
/* /\* }; *\/ */
|
|
/* /\* }; *\/ */
|
|
/* /\* union { *\/ */
|
|
/* /\* void *LoadedImports; *\/ */
|
|
/* /\* uint32_t TimeDateStamp; *\/ */
|
|
/* /\* }; *\/ */
|
|
/* printf("0x%04x: %-40s = 0x%lx\n", */
|
|
/* offsetof(struct NtLdrDataTableEntry,
|
|
* EntryPointActivationContext), */
|
|
/* "EntryPointActivationContext",
|
|
* dll->EntryPointActivationContext); */
|
|
/* printf("0x%04x: %-40s = 0x%lx\n", */
|
|
/* offsetof(struct NtLdrDataTableEntry, PatchInformation), */
|
|
/* "PatchInformation", dll->PatchInformation); */
|
|
/* /\* struct NtLinkedList ForwarderLinks; *\/ */
|
|
/* /\* struct NtLinkedList ServiceTagLinks; *\/ */
|
|
/* /\* struct NtLinkedList StaticLinks; *\/ */
|
|
/* printf("0x%04x: %-40s = 0x%lx\n", */
|
|
/* offsetof(struct NtLdrDataTableEntry, ContextInformation), */
|
|
/* "ContextInformation", dll->ContextInformation); */
|
|
/* printf("0x%04x: %-40s = 0x%lx\n", */
|
|
/* offsetof(struct NtLdrDataTableEntry, OriginalBase),
|
|
* "OriginalBase", */
|
|
/* dll->OriginalBase); */
|
|
/* printf("0x%04x: %-40s = %ld\n", */
|
|
/* offsetof(struct NtLdrDataTableEntry, LoadTime), "LoadTime", */
|
|
/* dll->LoadTime); */
|
|
printf("\n");
|
|
} while ((ldr = ldr->Next) && ldr != head);
|
|
}
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
showcrashreports();
|
|
if (IsLinux()) {
|
|
return NextBestThing();
|
|
}
|
|
if (!IsWindows()) {
|
|
fprintf(stderr, "error: this tool is intended for windows\n");
|
|
return 1;
|
|
}
|
|
PrintStartupInfo();
|
|
PrintSystemInfo();
|
|
PrintStdioInfo();
|
|
PrintTeb();
|
|
PrintPeb();
|
|
PrintPebLdr();
|
|
PrintModulesLoadOrder();
|
|
PrintModulesMemoryOrder();
|
|
return 0;
|
|
}
|