Skip to content

Commit

Permalink
First submit
Browse files Browse the repository at this point in the history
  • Loading branch information
Ex-Origin committed Aug 27, 2020
1 parent 0cceb20 commit 92be17e
Show file tree
Hide file tree
Showing 5 changed files with 391 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ modules.order
Module.symvers
Mkfile.old
dkms.conf

*.zip
*.tar.gz
36 changes: 36 additions & 0 deletions README.md
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.
81 changes: 81 additions & 0 deletions ldd.c
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;
}
136 changes: 136 additions & 0 deletions ldd64.c
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;
}
135 changes: 135 additions & 0 deletions ldd86.c
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;
}

0 comments on commit 92be17e

Please sign in to comment.