-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
391 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,3 +50,6 @@ modules.order | |
Module.symvers | ||
Mkfile.old | ||
dkms.conf | ||
|
||
*.zip | ||
*.tar.gz |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
|
||
## ldd-win | ||
|
||
A similar Linux ldd command for EXE files. | ||
|
||
The target program will stop at `EntryPoint` with the control of `ldd.exe`, then `ldd.exe` will read dll information from this program's PEB. | ||
|
||
``` | ||
E:\>ldd main.exe | ||
ldd64.exe main.exe | ||
0x00007ff7e7d70000 E:\main.exe | ||
0x00007ffc231c0000 C:\Windows\SYSTEM32\ntdll.dll | ||
0x00007ffc22580000 C:\Windows\System32\KERNEL32.DLL | ||
0x00007ffc20c00000 C:\Windows\System32\KERNELBASE.dll | ||
E:\>ldd main2.exe | ||
0x00400000 E:\main2.exe | ||
0x77480000 C:\Windows\SYSTEM32\ntdll.dll | ||
0x75890000 C:\Windows\System32\KERNEL32.DLL | ||
0x770a0000 C:\Windows\System32\KERNELBASE.dll | ||
0x74da0000 C:\Windows\System32\OLEAUT32.dll | ||
0x74ea0000 C:\Windows\System32\msvcp_win.dll | ||
0x75260000 C:\Windows\System32\ucrtbase.dll | ||
0x767d0000 C:\Windows\System32\combase.dll | ||
0x75fe0000 C:\Windows\System32\RPCRT4.dll | ||
0x74c50000 C:\Windows\System32\SspiCli.dll | ||
0x74c40000 C:\Windows\System32\CRYPTBASE.dll | ||
0x77040000 C:\Windows\System32\bcryptPrimitives.dll | ||
0x74fa0000 C:\Windows\System32\sechost.dll | ||
0x74a30000 C:\Windows\SYSTEM32\VCRUNTIME140.dll | ||
0x72bf0000 C:\Windows\SYSTEM32\MSVCP140.dll | ||
``` | ||
|
||
Email: [email protected] | ||
|
||
If you have any questions, please give a mail. |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
#include <Windows.h> | ||
#include <stdio.h> | ||
|
||
#define ASSERT(expression) \ | ||
{ \ | ||
if (!(expression)) \ | ||
{ \ | ||
fprintf(stderr, "\"" #expression "\" failed with error code %d in %s:%d (function: %s)\n", GetLastError(), __FILE__, __LINE__, __func__); \ | ||
ExitProcess(EXIT_FAILURE); \ | ||
} \ | ||
} | ||
|
||
int StrNCat(char str[], char* append, int strLength) | ||
{ | ||
int length, i; | ||
|
||
length = strlen(str); | ||
for (i = length; i < (strLength - 1) && *append; i++) | ||
{ | ||
str[i] = *append; | ||
append++; | ||
} | ||
|
||
if (i < (strLength - 1)) | ||
return 0; | ||
else | ||
return 1; | ||
} | ||
|
||
int main(int argc, char** argv) | ||
{ | ||
HANDLE StdoutHandle, StderrHandle, FileHandle; | ||
IMAGE_DOS_HEADER ImageDosHeader; | ||
IMAGE_NT_HEADERS ImageNtHeaders; | ||
DWORD result; | ||
|
||
STARTUPINFO si; | ||
PROCESS_INFORMATION pi; | ||
|
||
char buf[0x1000]; | ||
|
||
StdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); | ||
StderrHandle = GetStdHandle(STD_ERROR_HANDLE); | ||
if (argc < 2) | ||
{ | ||
WriteFile(StderrHandle, "Usage: ldd FILE\n", 16, &result, NULL); | ||
ExitProcess(EXIT_FAILURE); | ||
} | ||
|
||
ASSERT((FileHandle = CreateFileA(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE); | ||
ASSERT(ReadFile(FileHandle, &ImageDosHeader, sizeof(ImageDosHeader), &result, NULL) != 0); | ||
ASSERT(SetFilePointer(FileHandle, ImageDosHeader.e_lfanew, NULL, FILE_BEGIN) != INVALID_SET_FILE_POINTER); | ||
ASSERT(ReadFile(FileHandle, &ImageNtHeaders, sizeof(ImageNtHeaders), &result, NULL) != 0); | ||
|
||
ZeroMemory(&si, sizeof(si)); | ||
si.cb = sizeof(si); | ||
ZeroMemory(&pi, sizeof(pi)); | ||
ZeroMemory(buf, sizeof(buf)); | ||
|
||
if (ImageNtHeaders.FileHeader.Machine == IMAGE_FILE_MACHINE_I386) | ||
{ | ||
StrNCat(buf, "ldd86.exe ", sizeof(buf)); | ||
ASSERT(StrNCat(buf, argv[1], sizeof(buf)) == 0); | ||
ASSERT(CreateProcessA(NULL, buf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == TRUE); | ||
} | ||
else if (ImageNtHeaders.FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) | ||
{ | ||
StrNCat(buf, "ldd64.exe ", sizeof(buf)); | ||
ASSERT(StrNCat(buf, argv[1], sizeof(buf)) == 0); | ||
ASSERT(CreateProcessA(NULL, buf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == TRUE); | ||
} | ||
else | ||
{ | ||
fprintf(stderr, "Unrecognized file\n"); | ||
ExitProcess(EXIT_FAILURE); | ||
} | ||
|
||
ASSERT(WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED); | ||
|
||
return 0; | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
#include <Windows.h> | ||
#include <winnt.h> | ||
#include <winternl.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
#define ASSERT(expression) \ | ||
{ \ | ||
if (!(expression)) \ | ||
{ \ | ||
fprintf(stderr, "\"" #expression "\" failed with error code %d in %s:%d (function: %s)\n", GetLastError(), __FILE__, __LINE__, __func__); \ | ||
ExitProcess(EXIT_FAILURE); \ | ||
} \ | ||
} | ||
|
||
#define TRAP_INSTRUCT "\xcc" | ||
|
||
int main(int argc, char** argv) | ||
{ | ||
CHAR buf[0x200], OutputBuf[0x1000]; | ||
IMAGE_DOS_HEADER ImageDosHeader; | ||
IMAGE_NT_HEADERS ImageNtHeaders; | ||
HANDLE StdoutHandle, StderrHandle; | ||
HANDLE FileHandle; | ||
size_t EntryPoint, ImageBaseAddress, PebAddress, PEB_LDR_DATA, InMemoryOrderModuleList, address, next, head, result; | ||
NTSTATUS(__stdcall * NtQueryInformationProcessHook) | ||
(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); | ||
PROCESS_BASIC_INFORMATION Information; | ||
DEBUG_EVENT DebugEv; | ||
CHAR* ImageFile; | ||
|
||
STARTUPINFO si; | ||
PROCESS_INFORMATION pi; | ||
|
||
int i; | ||
|
||
StdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); | ||
StderrHandle = GetStdHandle(STD_ERROR_HANDLE); | ||
if (argc < 2) | ||
{ | ||
WriteFile(StderrHandle, "Usage: ldd FILE\n", 16, (LPDWORD)&result, NULL); | ||
ExitProcess(EXIT_FAILURE); | ||
} | ||
|
||
result = 0; | ||
ASSERT((FileHandle = CreateFileA(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE); | ||
ASSERT(ReadFile(FileHandle, &ImageDosHeader, sizeof(ImageDosHeader), (LPDWORD)&result, NULL) != 0); | ||
ASSERT(SetFilePointer(FileHandle, ImageDosHeader.e_lfanew, NULL, FILE_BEGIN) != INVALID_SET_FILE_POINTER); | ||
result = 0; | ||
ASSERT(ReadFile(FileHandle, &ImageNtHeaders, sizeof(ImageNtHeaders), (LPDWORD)&result, NULL) != 0); | ||
|
||
EntryPoint = ImageNtHeaders.OptionalHeader.AddressOfEntryPoint; | ||
|
||
ZeroMemory(&si, sizeof(si)); | ||
si.cb = sizeof(si); | ||
ZeroMemory(&pi, sizeof(pi)); | ||
ASSERT(CreateProcessA(NULL, argv[1], NULL, NULL, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | CREATE_SUSPENDED, NULL, NULL, &si, &pi) == TRUE); | ||
ASSERT(DebugSetProcessKillOnExit(TRUE) != 0); | ||
NtQueryInformationProcessHook = (NTSTATUS(__stdcall*)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG))GetProcAddress(LoadLibraryA("ntdll.dll"), "NtQueryInformationProcess"); | ||
ASSERT(NtQueryInformationProcessHook != NULL); | ||
ASSERT(NtQueryInformationProcessHook(pi.hProcess, ProcessBasicInformation, &Information, sizeof(Information), NULL) == 0); | ||
PebAddress = (size_t)Information.PebBaseAddress; | ||
|
||
ASSERT(ReadProcessMemory(pi.hProcess, (CHAR*)PebAddress + (sizeof(PVOID) * 2), &ImageBaseAddress, sizeof(PVOID), &result) != 0); | ||
ASSERT(WriteProcessMemory(pi.hProcess, (CHAR*)ImageBaseAddress + EntryPoint, TRAP_INSTRUCT, sizeof(TRAP_INSTRUCT), &result) != 0); | ||
ASSERT(result == sizeof(TRAP_INSTRUCT)); | ||
ResumeThread(pi.hThread); | ||
|
||
while (TRUE) | ||
{ | ||
WaitForDebugEvent(&DebugEv, INFINITE); | ||
// Process the debugging event code. | ||
if (DebugEv.dwDebugEventCode == EXCEPTION_DEBUG_EVENT) | ||
{ | ||
ASSERT(DebugEv.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT); | ||
|
||
if ((size_t)DebugEv.u.Exception.ExceptionRecord.ExceptionAddress == ImageBaseAddress + EntryPoint) | ||
; | ||
break; | ||
} | ||
ASSERT(ContinueDebugEvent(DebugEv.dwProcessId, DebugEv.dwThreadId, DBG_CONTINUE) != 0); | ||
} | ||
|
||
ASSERT(ReadProcessMemory(pi.hProcess, (CHAR*)PebAddress + (sizeof(PVOID) * 3), &PEB_LDR_DATA, sizeof(PVOID), &result) != 0); | ||
ASSERT(result == sizeof(PVOID)); | ||
|
||
ASSERT(ReadProcessMemory(pi.hProcess, (CHAR*)PEB_LDR_DATA + (sizeof(PVOID) * 4), &InMemoryOrderModuleList, sizeof(PVOID), &result) != 0); | ||
ASSERT(result == sizeof(PVOID)); | ||
|
||
ASSERT(ReadProcessMemory(pi.hProcess, (CHAR*)InMemoryOrderModuleList, buf, 0x50, &result) != 0); | ||
ASSERT(result == 0x50); | ||
|
||
head = InMemoryOrderModuleList; | ||
|
||
next = *(size_t*)(buf + 0); | ||
ImageFile = *(char**)(buf + 0x40); | ||
address = *(size_t*)(buf + 0x20); | ||
|
||
for (i = 0; TRUE; i++) | ||
{ | ||
ASSERT(ReadProcessMemory(pi.hProcess, ImageFile + i * 2, OutputBuf + i, 1, &result) != 0); | ||
ASSERT(result == 1); | ||
|
||
if (OutputBuf[i] == '\0') | ||
break; | ||
} | ||
printf(" 0x%016llx %s\n", address, OutputBuf); | ||
|
||
while (next != head) | ||
{ | ||
ASSERT(ReadProcessMemory(pi.hProcess, (CHAR*)next, buf, 0x50, &result) != 0); | ||
ASSERT(result == 0x50); | ||
|
||
next = *(size_t*)(buf + 0); | ||
ImageFile = *(char**)(buf + 0x40); | ||
address = *(size_t*)(buf + 0x20); | ||
|
||
if (ImageFile == 0 || address == 0) | ||
{ | ||
break; | ||
} | ||
|
||
for (i = 0; TRUE; i++) | ||
{ | ||
ASSERT(ReadProcessMemory(pi.hProcess, ImageFile + i * 2, OutputBuf + i, 1, &result) != 0); | ||
ASSERT(result == 1); | ||
|
||
if (OutputBuf[i] == '\0') | ||
break; | ||
} | ||
printf(" 0x%016llx %s\n", address, OutputBuf); | ||
} | ||
TerminateProcess(pi.hProcess, 0); | ||
|
||
return 0; | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
#include <Windows.h> | ||
#include <winnt.h> | ||
#include <winternl.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
#define ASSERT(expression) \ | ||
{ \ | ||
if (!(expression)) \ | ||
{ \ | ||
fprintf(stderr, "\"" #expression "\" failed with error code %d in %s:%d (function: %s)\n", GetLastError(), __FILE__, __LINE__, __func__); \ | ||
ExitProcess(EXIT_FAILURE); \ | ||
} \ | ||
} | ||
|
||
#define TRAP_INSTRUCT "\xcc" | ||
|
||
int main(int argc, char** argv) | ||
{ | ||
CHAR buf[0x200], OutputBuf[0x1000]; | ||
IMAGE_DOS_HEADER ImageDosHeader; | ||
IMAGE_NT_HEADERS ImageNtHeaders; | ||
HANDLE StdoutHandle, StderrHandle; | ||
DWORD result; | ||
HANDLE FileHandle; | ||
DWORD EntryPoint, ImageBaseAddress, PebAddress, PEB_LDR_DATA, InMemoryOrderModuleList, address, next, head; | ||
NTSTATUS(__stdcall * NtQueryInformationProcessHook) | ||
(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); | ||
PROCESS_BASIC_INFORMATION Information; | ||
DEBUG_EVENT DebugEv; | ||
CHAR* ImageFile; | ||
|
||
STARTUPINFO si; | ||
PROCESS_INFORMATION pi; | ||
|
||
int i; | ||
|
||
StdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); | ||
StderrHandle = GetStdHandle(STD_ERROR_HANDLE); | ||
if (argc < 2) | ||
{ | ||
WriteFile(StderrHandle, "Usage: ldd FILE\n", 16, &result, NULL); | ||
ExitProcess(EXIT_FAILURE); | ||
} | ||
|
||
ASSERT((FileHandle = CreateFileA(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE); | ||
ASSERT(ReadFile(FileHandle, &ImageDosHeader, sizeof(ImageDosHeader), &result, NULL) != 0); | ||
ASSERT(SetFilePointer(FileHandle, ImageDosHeader.e_lfanew, NULL, FILE_BEGIN) != INVALID_SET_FILE_POINTER); | ||
ASSERT(ReadFile(FileHandle, &ImageNtHeaders, sizeof(ImageNtHeaders), &result, NULL) != 0); | ||
|
||
EntryPoint = ImageNtHeaders.OptionalHeader.AddressOfEntryPoint; | ||
|
||
ZeroMemory(&si, sizeof(si)); | ||
si.cb = sizeof(si); | ||
ZeroMemory(&pi, sizeof(pi)); | ||
ASSERT(CreateProcessA(NULL, argv[1], NULL, NULL, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | CREATE_SUSPENDED, NULL, NULL, &si, &pi) == TRUE); | ||
ASSERT(DebugSetProcessKillOnExit(TRUE) != 0); | ||
NtQueryInformationProcessHook = (NTSTATUS(__stdcall*)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG))GetProcAddress(LoadLibraryA("ntdll.dll"), "NtQueryInformationProcess"); | ||
ASSERT(NtQueryInformationProcessHook != NULL); | ||
ASSERT(NtQueryInformationProcessHook(pi.hProcess, ProcessBasicInformation, &Information, sizeof(Information), NULL) == 0); | ||
PebAddress = (DWORD)Information.PebBaseAddress; | ||
|
||
ASSERT(ReadProcessMemory(pi.hProcess, (CHAR*)PebAddress + (sizeof(PVOID) * 2), &ImageBaseAddress, sizeof(PVOID), &result) != 0); | ||
ASSERT(WriteProcessMemory(pi.hProcess, (CHAR*)ImageBaseAddress + EntryPoint, TRAP_INSTRUCT, sizeof(TRAP_INSTRUCT), &result) != 0); | ||
ASSERT(result == sizeof(TRAP_INSTRUCT)); | ||
ResumeThread(pi.hThread); | ||
|
||
while (TRUE) | ||
{ | ||
WaitForDebugEvent(&DebugEv, INFINITE); | ||
// Process the debugging event code. | ||
if (DebugEv.dwDebugEventCode == EXCEPTION_DEBUG_EVENT) | ||
{ | ||
ASSERT(DebugEv.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT); | ||
|
||
if ((DWORD)DebugEv.u.Exception.ExceptionRecord.ExceptionAddress == ImageBaseAddress + EntryPoint) | ||
; | ||
break; | ||
} | ||
ASSERT(ContinueDebugEvent(DebugEv.dwProcessId, DebugEv.dwThreadId, DBG_CONTINUE) != 0); | ||
} | ||
|
||
ASSERT(ReadProcessMemory(pi.hProcess, (CHAR*)PebAddress + (sizeof(PVOID) * 3), &PEB_LDR_DATA, sizeof(PVOID), &result) != 0); | ||
ASSERT(result == sizeof(PVOID)); | ||
|
||
ASSERT(ReadProcessMemory(pi.hProcess, (CHAR*)PEB_LDR_DATA + (sizeof(PVOID) * 5), &InMemoryOrderModuleList, sizeof(PVOID), &result) != 0); | ||
ASSERT(result == sizeof(PVOID)); | ||
|
||
ASSERT(ReadProcessMemory(pi.hProcess, (CHAR*)InMemoryOrderModuleList, buf, 0x30, &result) != 0); | ||
ASSERT(result == 0x30); | ||
|
||
head = InMemoryOrderModuleList; | ||
|
||
next = *(DWORD*)(buf + 0); | ||
ImageFile = *(char**)(buf + 0x20); | ||
address = *(DWORD*)(buf + 0x10); | ||
|
||
for (i = 0; TRUE; i++) | ||
{ | ||
ASSERT(ReadProcessMemory(pi.hProcess, ImageFile + i * 2, OutputBuf + i, 1, &result) != 0); | ||
ASSERT(result == 1); | ||
|
||
if (OutputBuf[i] == '\0') | ||
break; | ||
} | ||
printf(" 0x%08lx %s\n", address, OutputBuf); | ||
|
||
while (next != head) | ||
{ | ||
ASSERT(ReadProcessMemory(pi.hProcess, (CHAR*)next, buf, 0x30, &result) != 0); | ||
ASSERT(result == 0x30); | ||
|
||
next = *(DWORD*)(buf + 0); | ||
ImageFile = *(char**)(buf + 0x20); | ||
address = *(DWORD*)(buf + 0x10); | ||
|
||
if (ImageFile == 0 || address == 0) | ||
{ | ||
break; | ||
} | ||
|
||
for (i = 0; TRUE; i++) | ||
{ | ||
ASSERT(ReadProcessMemory(pi.hProcess, ImageFile + i * 2, OutputBuf + i, 1, &result) != 0); | ||
ASSERT(result == 1); | ||
|
||
if (OutputBuf[i] == '\0') | ||
break; | ||
} | ||
printf(" 0x%08lx %s\n", address, OutputBuf); | ||
} | ||
TerminateProcess(pi.hProcess, 0); | ||
|
||
return 0; | ||
} |