Merge pull request #10 from physics-sp/find-import-addresses

find all import addresses dinamically
This commit is contained in:
batsec
2021-08-13 09:32:15 +01:00
committed by GitHub
7 changed files with 168 additions and 81 deletions
+12
View File
@@ -6,6 +6,18 @@
#define LOAD_MEMORY 0x00000003
#define NO_LINK 0x00010000
typedef LPVOID(WINAPI* HEAPALLOC)(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
typedef HANDLE(WINAPI* GETPROCESSHEAP)(VOID);
typedef HANDLE(WINAPI* CREATEFILEW)(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
typedef LPVOID(WINAPI* VIRTUALALLOC)(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
typedef DWORD(WINAPI* GETFILESIZE)(HANDLE hFile, LPDWORD lpFileSizeHigh);
typedef BOOL(WINAPI* READFILE)(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
typedef BOOL(WINAPI* CLOSEHANDLE)(HANDLE hObject);
typedef BOOL(WINAPI* HEAPFREE)(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem);
typedef void(__cdecl* _WSPLITPATH)(const wchar_t* _FullPath, wchar_t* _Drive, wchar_t* _Dir, wchar_t* _Filename, wchar_t* _Ext);
typedef wchar_t*(_cdecl* WCSCPY)(wchar_t* Dest, const wchar_t* _Source);
typedef wchar_t* (__cdecl* WCSCAT)(wchar_t* _dst, const wchar_t* __src);
#pragma once
typedef struct _DARKMODULE {
BOOL bSuccess;
+2
View File
@@ -7,6 +7,8 @@
typedef BOOL(WINAPI * DLLMAIN)(HINSTANCE, DWORD, LPVOID);
typedef HMODULE(WINAPI* LOADLIBRARYA)(LPCSTR);
typedef BOOL(WINAPI* VIRTUALPROTECT)(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect);
typedef BOOL(WINAPI* FLUSHINSTRUCTIONCACHE)(HANDLE hProcess, LPCVOID lpBaseAddress, SIZE_T dwSize);
BOOL IsValidPE(PBYTE pbData);
BOOL MapSections(PDARKMODULE pdModule);
+9 -1
View File
@@ -10,6 +10,14 @@
typedef NTSTATUS(WINAPI* LDRGETPROCADDRESS)(HMODULE, PANSI_STRING, WORD, PVOID*);
typedef VOID(WINAPI* RTLRBINSERTNODEEX)(_In_ PRTL_RB_TREE Tree, _In_opt_ PRTL_BALANCED_NODE Parent, _In_ BOOLEAN Right, _Out_ PRTL_BALANCED_NODE Node);
typedef VOID(NTAPI* RTLINITUNICODESTRING)(PUNICODE_STRING DestinationString, PCWSTR SourceString);
typedef NTSTATUS(NTAPI* NTQUERYSYSTEMTIME)(PLARGE_INTEGER SystemTime);
typedef NTSTATUS(NTAPI* RTLHASHUNICODESTRING)(UNICODE_STRING* String, BOOLEAN CaseInSensitive, ULONG HashAlgorithm, ULONG* HashValue);
typedef SIZE_T(NTAPI* RTLCOMPAREMEMORY)(const VOID* Source1, const VOID* Source2, SIZE_T Length);
typedef int(__cdecl* _WCSNICMP)(const wchar_t* _Str1, const wchar_t* _Str2, size_t _MaxCount);
typedef int(__cdecl* STRCMP)(const char* _Str1, const char* _Str2);
typedef size_t(__cdecl* MBSTOWCS)(wchar_t* Dest, const char* _Source, size_t _MaxCount);
typedef int(__cdecl* _WCSICMP)(const wchar_t* _Str1, const wchar_t* _Str2);
#ifdef _WIN64
#define PEB_OFFSET 0x60
@@ -36,6 +44,6 @@ NTSYSAPI VOID NTAPI RtlRbInsertNodeEx(_In_ PRTL_RB_TREE Tree, _In_opt_ PRTL_BALA
HMODULE IsModulePresent(LPCWSTR lpwName);
HMODULE IsModulePresentA(char* Name);
BOOL LinkModuleToPEB(PDARKMODULE pdModule);
FARPROC GetFunctionAddress(HMODULE hModule, char* ProcName);
PVOID GetFunctionAddress(HMODULE hModule, char* ProcName);
BOOL LocalLdrGetProcedureAddress(HMODULE hLibrary, PANSI_STRING ProcName, WORD Ordinal, PVOID* FunctionAddress);
BOOL _LocalLdrGetProcedureAddress(HMODULE hLibrary, PANSI_STRING ProcName, WORD Ordinal, PVOID* FunctionAddress);
+45 -28
View File
@@ -6,6 +6,12 @@ BOOL ParseFileName(
LPWSTR lpwFileName
)
{
HEAPALLOC pHeapAlloc = (HEAPALLOC)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "HeapAlloc");
GETPROCESSHEAP pGetProcessHeap = (GETPROCESSHEAP)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "GetProcessHeap");
_WSPLITPATH p_wsplitpath = (_WSPLITPATH)GetFunctionAddress(IsModulePresent(L"ucrtbased.dll"), "_wsplitpath");
WCSCPY pwcscpy = (WCSCPY)GetFunctionAddress(IsModulePresent(L"ucrtbased.dll"), "wcscpy");
WCSCAT pwcscat = (WCSCAT)GetFunctionAddress(IsModulePresent(L"ucrtbased.dll"), "wcscat");
if (lpwFileName == NULL)
{
pdModule->ErrorMsg = L"Invalid filename";
@@ -14,26 +20,26 @@ BOOL ParseFileName(
pdModule->LocalDLLName = lpwFileName;
HANDLE hHeap = GetProcessHeap();
HANDLE hHeap = pGetProcessHeap();
if (!hHeap)
{
pdModule->ErrorMsg = L"Failed to find valid heap";
return FALSE;
}
pdModule->CrackedDLLName = (PWCHAR)HeapAlloc(
pdModule->CrackedDLLName = (PWCHAR)pHeapAlloc(
hHeap,
HEAP_ZERO_MEMORY,
MAX_PATH * 2
);
PWCHAR lpwExt = (PWCHAR)HeapAlloc(
PWCHAR lpwExt = (PWCHAR)pHeapAlloc(
hHeap,
HEAP_ZERO_MEMORY,
MAX_PATH
);
PWCHAR lpwFilename = (PWCHAR)HeapAlloc(
PWCHAR lpwFilename = (PWCHAR)pHeapAlloc(
hHeap,
HEAP_ZERO_MEMORY,
MAX_PATH
@@ -45,7 +51,7 @@ BOOL ParseFileName(
return FALSE;
}
_wsplitpath(
p_wsplitpath(
lpwFileName,
NULL,
NULL,
@@ -59,12 +65,12 @@ BOOL ParseFileName(
return FALSE;
}
PCHAR lpCpy = (PCHAR)wcscpy(
PCHAR lpCpy = (PCHAR)pwcscpy(
pdModule->CrackedDLLName,
lpwFilename
);
PCHAR lpCat = (PCHAR)wcscat(
PCHAR lpCat = (PCHAR)pwcscat(
pdModule->CrackedDLLName,
lpwExt
);
@@ -82,7 +88,14 @@ BOOL ReadFileToBuffer(
PDARKMODULE pdModule
)
{
HANDLE hFile = CreateFileW(
HEAPALLOC pHeapAlloc = (HEAPALLOC)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "HeapAlloc");
CREATEFILEW pCreateFileW = (CREATEFILEW)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "CreateFileW");
VIRTUALALLOC pVirtualAlloc = (VIRTUALALLOC)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "VirtualAlloc");
GETFILESIZE pGetFileSize = (GETFILESIZE)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "GetFileSize");
READFILE pReadFile = (READFILE)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "ReadFile");
CLOSEHANDLE pCloseHandle = (CLOSEHANDLE)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "CloseHandle");
HANDLE hFile = pCreateFileW(
pdModule->LocalDLLName,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
@@ -98,7 +111,7 @@ BOOL ReadFileToBuffer(
return FALSE;
}
DWORD dwSize = GetFileSize(
DWORD dwSize = pGetFileSize(
hFile,
NULL
);
@@ -109,7 +122,7 @@ BOOL ReadFileToBuffer(
return FALSE;
}
pdModule->pbDllData = VirtualAlloc(
pdModule->pbDllData = pVirtualAlloc(
NULL,
dwSize,
MEM_COMMIT | MEM_RESERVE,
@@ -122,7 +135,7 @@ BOOL ReadFileToBuffer(
return FALSE;
}
if (!ReadFile(
if (!pReadFile(
hFile,
pdModule->pbDllData,
dwSize,
@@ -133,7 +146,7 @@ BOOL ReadFileToBuffer(
return FALSE;
}
if (!CloseHandle(hFile))
if (!pCloseHandle(hFile))
{
pdModule->ErrorMsg = L"Failed to close handle on DLL file";
return FALSE;
@@ -150,7 +163,11 @@ PDARKMODULE DarkLoadLibrary(
LPCWSTR lpwName
)
{
PDARKMODULE dModule = (DARKMODULE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DARKMODULE));
HEAPALLOC pHeapAlloc = (HEAPALLOC)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "HeapAlloc");
GETPROCESSHEAP pGetProcessHeap = (GETPROCESSHEAP)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "GetProcessHeap");
WCSCAT pwcscat = (WCSCAT)GetFunctionAddress(IsModulePresent(L"ucrtbased.dll"), "wcscat");
PDARKMODULE dModule = (DARKMODULE*)pHeapAlloc(pGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DARKMODULE));
if (!dModule)
return NULL;
@@ -210,36 +227,36 @@ PDARKMODULE DarkLoadLibrary(
// make sure the PE we are about to load is valid
if (!IsValidPE(dModule->pbDllData))
{
dModule->ErrorMsg = (wchar_t*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
dModule->ErrorMsg = (wchar_t*)pHeapAlloc(pGetProcessHeap(), HEAP_ZERO_MEMORY, 500);
if (!dModule->ErrorMsg)
goto Cleanup;
wcscat(dModule->ErrorMsg, L"Data is an invalid PE: ");
wcscat(dModule->ErrorMsg, lpwName);
pwcscat(dModule->ErrorMsg, L"Data is an invalid PE: ");
pwcscat(dModule->ErrorMsg, lpwName);
goto Cleanup;
}
// map the sections into memory
if (!MapSections(dModule))
{
dModule->ErrorMsg = (wchar_t*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
dModule->ErrorMsg = (wchar_t*)pHeapAlloc(pGetProcessHeap(), HEAP_ZERO_MEMORY, 500);
if (!dModule->ErrorMsg)
goto Cleanup;
wcscat(dModule->ErrorMsg, L"Failed to map sections: ");
wcscat(dModule->ErrorMsg, lpwName);
pwcscat(dModule->ErrorMsg, L"Failed to map sections: ");
pwcscat(dModule->ErrorMsg, lpwName);
goto Cleanup;
}
// handle the import tables
if (!ResolveImports(dModule))
{
dModule->ErrorMsg = (wchar_t*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
dModule->ErrorMsg = (wchar_t*)pHeapAlloc(pGetProcessHeap(), HEAP_ZERO_MEMORY, 500);
if (!dModule->ErrorMsg)
goto Cleanup;
wcscat(dModule->ErrorMsg, L"Failed to resolve imports: ");
wcscat(dModule->ErrorMsg, lpwName);
pwcscat(dModule->ErrorMsg, L"Failed to resolve imports: ");
pwcscat(dModule->ErrorMsg, lpwName);
goto Cleanup;
}
@@ -248,12 +265,12 @@ PDARKMODULE DarkLoadLibrary(
{
if (!LinkModuleToPEB(dModule))
{
dModule->ErrorMsg = (wchar_t*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
dModule->ErrorMsg = (wchar_t*)pHeapAlloc(pGetProcessHeap(), HEAP_ZERO_MEMORY, 500);
if (!dModule->ErrorMsg)
goto Cleanup;
wcscat(dModule->ErrorMsg, L"Failed to link module to PEB: ");
wcscat(dModule->ErrorMsg, lpwName);
pwcscat(dModule->ErrorMsg, L"Failed to link module to PEB: ");
pwcscat(dModule->ErrorMsg, lpwName);
goto Cleanup;
}
}
@@ -261,12 +278,12 @@ PDARKMODULE DarkLoadLibrary(
// trigger tls callbacks, set permissions and call the entry point
if (!BeginExecution(dModule))
{
dModule->ErrorMsg = (wchar_t*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
dModule->ErrorMsg = (wchar_t*)pHeapAlloc(pGetProcessHeap(), HEAP_ZERO_MEMORY, 500);
if (!dModule->ErrorMsg)
goto Cleanup;
wcscat(dModule->ErrorMsg, L"Failed to execute: ");
wcscat(dModule->ErrorMsg, lpwName);
pwcscat(dModule->ErrorMsg, L"Failed to execute: ");
pwcscat(dModule->ErrorMsg, lpwName);
goto Cleanup;
}
+10 -8
View File
@@ -32,6 +32,8 @@ BOOL MapSections(
PIMAGE_BASE_RELOCATION pRelocation;
PIMAGE_SECTION_HEADER pSectionHeader;
VIRTUALALLOC pVirtualAlloc = (VIRTUALALLOC)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "VirtualAlloc");
pNtHeaders = RVA(
PIMAGE_NT_HEADERS,
pdModule->pbDllData,
@@ -68,7 +70,7 @@ BOOL MapSections(
return FALSE;
}
#else
pdModule->ModuleBase = (ULONG_PTR)VirtualAlloc(
pdModule->ModuleBase = (ULONG_PTR)pVirtualAlloc(
(LPVOID)(pNtHeaders->OptionalHeader.ImageBase),
(SIZE_T)pNtHeaders->OptionalHeader.SizeOfImage,
MEM_RESERVE | MEM_COMMIT,
@@ -77,7 +79,7 @@ BOOL MapSections(
if (!pdModule->ModuleBase)
{
pdModule->ModuleBase = (ULONG_PTR)VirtualAlloc(
pdModule->ModuleBase = (ULONG_PTR)pVirtualAlloc(
0,
(SIZE_T)pNtHeaders->OptionalHeader.SizeOfImage,
MEM_RESERVE | MEM_COMMIT,
@@ -167,10 +169,7 @@ BOOL ResolveImports(
PIMAGE_THUNK_DATA pFirstThunk, pOrigFirstThunk;
BOOL ok;
LOADLIBRARYA pLoadLibraryA = (LOADLIBRARYA)GetFunctionAddress(
IsModulePresentA("Kernel32.dll"),
"LoadLibraryA"
);
LOADLIBRARYA pLoadLibraryA = (LOADLIBRARYA)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "LoadLibraryA");
STRING aString = { 0 };
@@ -359,6 +358,9 @@ BOOL BeginExecution(
PIMAGE_SECTION_HEADER pSectionHeader;
//PIMAGE_RUNTIME_FUNCTION_ENTRY pFuncEntry;
VIRTUALPROTECT pVirtualProtect = (VIRTUALPROTECT)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "VirtualProtect");
FLUSHINSTRUCTIONCACHE pFlushInstructionCache = (FLUSHINSTRUCTIONCACHE)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "FlushInstructionCache");
DLLMAIN DllMain = NULL;
pNtHeaders = RVA(
@@ -406,7 +408,7 @@ BOOL BeginExecution(
return FALSE;
}
#else
VirtualProtect(
pVirtualProtect(
(LPVOID)(pdModule->ModuleBase + pSectionHeader->VirtualAddress),
pSectionHeader->SizeOfRawData,
dwProtect,
@@ -417,7 +419,7 @@ BOOL BeginExecution(
}
// flush the instruction cache
FlushInstructionCache((HANDLE)-1, NULL, 0);
pFlushInstructionCache((HANDLE)-1, NULL, 0);
// execute the TLS callbacks
pDataDir = &pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS];
+7 -4
View File
@@ -8,8 +8,11 @@ typedef DWORD (WINAPI * _ThisIsAFunction) (LPCWSTR);
VOID main()
{
GETPROCESSHEAP pGetProcessHeap = (GETPROCESSHEAP)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "GetProcessHeap");
HEAPFREE pHeapFree = (HEAPFREE)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "HeapFree");
PDARKMODULE DarkModule = DarkLoadLibrary(
LOAD_LOCAL_FILE | NO_LINK,
LOAD_LOCAL_FILE,
L"TestDLL.dll",
NULL,
0,
@@ -19,8 +22,8 @@ VOID main()
if (!DarkModule->bSuccess)
{
printf("load failed: %S\n", DarkModule->ErrorMsg);
HeapFree(GetProcessHeap(), 0, DarkModule->ErrorMsg);
HeapFree(GetProcessHeap(), 0, DarkModule);
pHeapFree(pGetProcessHeap(), 0, DarkModule->ErrorMsg);
pHeapFree(pGetProcessHeap(), 0, DarkModule);
return;
}
@@ -28,7 +31,7 @@ VOID main()
(HMODULE)DarkModule->ModuleBase,
"CallThisFunction"
);
HeapFree(GetProcessHeap(), 0, DarkModule);
pHeapFree(pGetProcessHeap(), 0, DarkModule);
if (!ThisIsAFunction)
{
+83 -40
View File
@@ -2,8 +2,9 @@
ULONG LdrHashEntry(UNICODE_STRING UniName, BOOL XorHash) {
ULONG ulRes = 0;
RTLHASHUNICODESTRING pRtlHashUnicodeString = (RTLHASHUNICODESTRING)GetFunctionAddress(IsModulePresent(L"ntdll.dll"), "RtlHashUnicodeString");
RtlHashUnicodeString(
pRtlHashUnicodeString(
&UniName,
TRUE,
0,
@@ -25,6 +26,8 @@ PLDR_DATA_TABLE_ENTRY2 FindLdrTableEntry(
PPEB2 pPeb;
PLDR_DATA_TABLE_ENTRY2 pCurEntry;
PLIST_ENTRY pListHead, pListEntry;
_WCSNICMP p_wcsnicmp = (_WCSNICMP)GetFunctionAddress(IsModulePresent(L"ucrtbased.dll"), "_wcsnicmp");
pPeb = (PPEB2)READ_MEMLOC(PEB_OFFSET);
@@ -38,12 +41,11 @@ PLDR_DATA_TABLE_ENTRY2 FindLdrTableEntry(
do
{
pCurEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY2, InLoadOrderLinks);
pListEntry = pListEntry->Flink;
INT BaseName1 = _wcsnicmp(BaseName, pCurEntry->BaseDllName.Buffer, (pCurEntry->BaseDllName.Length / sizeof(wchar_t)) - 4);
INT BaseName2 = _wcsnicmp(BaseName, pCurEntry->BaseDllName.Buffer, pCurEntry->BaseDllName.Length / sizeof(wchar_t));
INT BaseName1 = p_wcsnicmp(BaseName, pCurEntry->BaseDllName.Buffer, (pCurEntry->BaseDllName.Length / sizeof(wchar_t)) - 4);
INT BaseName2 = p_wcsnicmp(BaseName, pCurEntry->BaseDllName.Buffer, pCurEntry->BaseDllName.Length / sizeof(wchar_t));
if (!BaseName1 || !BaseName2)
{
@@ -62,6 +64,9 @@ PRTL_RB_TREE FindModuleBaseAddressIndex()
PRTL_BALANCED_NODE pNode = NULL;
PRTL_RB_TREE pModBaseAddrIndex = NULL;
RTLCOMPAREMEMORY pRtlCompareMemory = (RTLCOMPAREMEMORY)GetFunctionAddress(IsModulePresent(L"ntdll.dll"), "RtlCompareMemory");
STRCMP pstrcmp = (STRCMP)GetFunctionAddress(IsModulePresent(L"ntdll.dll"), "strcmp");
PLDR_DATA_TABLE_ENTRY2 pLdrEntry = FindLdrTableEntry(L"ntdll.dll");
pNode = &pLdrEntry->BaseAddressIndexNode;
@@ -86,7 +91,7 @@ PRTL_RB_TREE FindModuleBaseAddressIndex()
for (INT i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++)
{
if (!strcmp(".data", (LPCSTR)pSection->Name))
if (!pstrcmp(".data", (LPCSTR)pSection->Name))
{
stBegin = (SIZE_T)pLdrEntry->DllBase + pSection->VirtualAddress;
dwLen = pSection->Misc.VirtualSize;
@@ -100,7 +105,7 @@ PRTL_RB_TREE FindModuleBaseAddressIndex()
for (DWORD i = 0; i < dwLen - sizeof(SIZE_T); ++stBegin, ++i)
{
SIZE_T stRet = RtlCompareMemory(
SIZE_T stRet = pRtlCompareMemory(
(PVOID)stBegin,
(PVOID)&pNode,
sizeof(SIZE_T)
@@ -134,7 +139,7 @@ BOOL AddBaseAddressEntry(
PVOID lpBaseAddr
)
{
RTLRBINSERTNODEEX pRtlRbInsertNodeEx = (RTLRBINSERTNODEEX)GetFunctionAddress(IsModulePresent(L"ntdll.dll"), "RtlRbInsertNodeEx");
PRTL_RB_TREE pModBaseAddrIndex = FindModuleBaseAddressIndex();
if (!pModBaseAddrIndex)
@@ -175,10 +180,6 @@ BOOL AddBaseAddressEntry(
}
} while (TRUE);
RTLRBINSERTNODEEX pRtlRbInsertNodeEx = (RTLRBINSERTNODEEX)GetFunctionAddress(
IsModulePresent(L"ntdll.dll"),
"RtlRbInsertNodeEx"
);
pRtlRbInsertNodeEx(pModBaseAddrIndex, &pLdrNode->BaseAddressIndexNode, bRight, &pLdrEntry->BaseAddressIndexNode);
return TRUE;
@@ -306,8 +307,10 @@ HMODULE IsModulePresentA(
char* Name
)
{
MBSTOWCS pmbstowcs = (MBSTOWCS)GetFunctionAddress(IsModulePresent(L"ucrtbased.dll"), "mbstowcs");
wchar_t wtext[500];
mbstowcs(wtext, Name, strlen(Name) + 1);
pmbstowcs(wtext, Name, strlen(Name) + 1);
return IsModulePresent(wtext);
}
@@ -333,10 +336,23 @@ HMODULE IsModulePresent(
pLdrTbl = (PLDR_DATA_TABLE_ENTRY2)ucModPtrOff;
if (!_wcsicmp(
pLdrTbl->BaseDllName.Buffer,
(PWSTR)lpwName)
)
BOOL match = TRUE;
for (int i = 0; i < pLdrTbl->BaseDllName.Length/2; i++)
{
char a, b;
a = pLdrTbl->BaseDllName.Buffer[i];
b = lpwName[i];
if (a >= 'A' && a <= 'Z')
a += 32;
if (b >= 'A' && b <= 'Z')
b += 32;
if (a != b)
{
match = FALSE;
break;
}
}
if (match)
{
// already loaded, so return the base address
return (HMODULE)pLdrTbl->DllBase;
@@ -348,7 +364,7 @@ HMODULE IsModulePresent(
return (HMODULE)NULL;
}
FARPROC GetFunctionAddress(
PVOID GetFunctionAddress(
HMODULE hModule,
char* ProcName
)
@@ -454,6 +470,37 @@ BOOL LocalLdrGetProcedureAddress(
return *FunctionAddress != NULL;
}
BOOL my_strncmp(char* s1, char* s2, size_t n)
{
BOOL match = TRUE;
for (size_t i = 0; i < n; i++)
{
if (s1[i] != s2[i])
{
match = FALSE;
break;
}
}
return match;
}
size_t my_strlen(char* s)
{
size_t size = -1;
while (s[++size]);
return size;
}
void my_strncpy(char* dst, char* src, size_t size)
{
for (size_t i = 0; i < size; i++)
{
dst[i] = src[i];
if (!src[i])
break;
}
}
BOOL _LocalLdrGetProcedureAddress(
HMODULE hLibrary,
PANSI_STRING ProcName,
@@ -492,7 +539,7 @@ BOOL _LocalLdrGetProcedureAddress(
&pNtHeaders->OptionalHeader,
pNtHeaders->FileHeader.SizeOfOptionalHeader + i * IMAGE_SIZEOF_SECTION_HEADER
);
if (strncmp(".text", pSecHeader->Name, 6) == 0)
if (my_strncmp(".text", pSecHeader->Name, 6))
{
startValidSection = RVA(
PVOID,
@@ -538,9 +585,9 @@ BOOL _LocalLdrGetProcedureAddress(
hLibrary,
*pRVA
);
if (strlen(functionName) != ProcName->Length)
if (my_strlen(functionName) != ProcName->Length)
continue;
if (strncmp(functionName, ProcName->Buffer, ProcName->Length) == 0)
if (my_strncmp(functionName, ProcName->Buffer, ProcName->Length))
{
// found it
found = TRUE;
@@ -583,7 +630,7 @@ BOOL _LocalLdrGetProcedureAddress(
if (startValidSection > FunctionPtr || FunctionPtr > endValidSection)
{
// this is not a pointer to a function, but a reference to another library with the real address
size_t full_length = strlen((char*)FunctionPtr);
size_t full_length = my_strlen((char*)FunctionPtr);
int lib_length = 0;
for (int j = 0; j < full_length; j++)
{
@@ -597,15 +644,9 @@ BOOL _LocalLdrGetProcedureAddress(
{
size_t func_length = full_length - lib_length - 1;
char* libname = HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
lib_length + 5
);
if (!libname)
return FALSE;
strncpy(libname, (char*)FunctionPtr, lib_length);
strncpy(libname + lib_length, ".dll", 5);
char libname[256];
my_strncpy(libname, (char*)FunctionPtr, lib_length);
my_strncpy(libname + lib_length, ".dll", 5);
char* funcname = (char*)FunctionPtr + lib_length + 1;
STRING funcname_s = { 0 };
FILL_STRING(
@@ -615,7 +656,6 @@ BOOL _LocalLdrGetProcedureAddress(
PVOID lib_addr = IsModulePresentA(libname);
if (lib_addr == NULL || lib_addr == hLibrary)
{
HeapFree(GetProcessHeap(), 0, libname); libname = NULL;
return FALSE;
}
@@ -630,10 +670,8 @@ BOOL _LocalLdrGetProcedureAddress(
if (!ok)
{
printf("LocalLdrGetProcedureAddress: failed to resolve address of: %s!%s\n", libname, funcname);
HeapFree(GetProcessHeap(), 0, libname); libname = NULL;
return FALSE;
}
HeapFree(GetProcessHeap(), 0, libname); libname = NULL;
}
}
*FunctionAddress = FunctionPtr;
@@ -652,6 +690,11 @@ BOOL LinkModuleToPEB(
UNICODE_STRING FullDllName, BaseDllName;
PLDR_DATA_TABLE_ENTRY2 pLdrEntry = NULL;
GETPROCESSHEAP pGetProcessHeap = (GETPROCESSHEAP)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "GetProcessHeap");
HEAPALLOC pHeapAlloc = (HEAPALLOC)GetFunctionAddress(IsModulePresent(L"Kernel32.dll"), "HeapAlloc");
RTLINITUNICODESTRING pRtlInitUnicodeString = (RTLINITUNICODESTRING)GetFunctionAddress(IsModulePresent(L"ntdll.dll"), "RtlInitUnicodeString");
NTQUERYSYSTEMTIME pNtQuerySystemTime = (NTQUERYSYSTEMTIME)GetFunctionAddress(IsModulePresent(L"ntdll.dll"), "NtQuerySystemTime");
pNtHeaders = RVA(
PIMAGE_NT_HEADERS,
pdModule->pbDllData,
@@ -659,19 +702,19 @@ BOOL LinkModuleToPEB(
);
// convert the names to unicode
RtlInitUnicodeString(
pRtlInitUnicodeString(
&FullDllName,
pdModule->LocalDLLName
);
RtlInitUnicodeString(
pRtlInitUnicodeString(
&BaseDllName,
pdModule->CrackedDLLName
);
// link the entry to the PEB
pLdrEntry = (PLDR_DATA_TABLE_ENTRY2)HeapAlloc(
GetProcessHeap(),
pLdrEntry = (PLDR_DATA_TABLE_ENTRY2)pHeapAlloc(
pGetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(LDR_DATA_TABLE_ENTRY2)
);
@@ -682,7 +725,7 @@ BOOL LinkModuleToPEB(
}
// start setting the values in the entry
NtQuerySystemTime(&pLdrEntry->LoadTime);
pNtQuerySystemTime(&pLdrEntry->LoadTime);
// do the obvious ones
pLdrEntry->ReferenceCount = 1;
@@ -718,8 +761,8 @@ BOOL LinkModuleToPEB(
pLdrEntry->Flags = LDRP_IMAGE_DLL | LDRP_ENTRY_INSERTED | LDRP_ENTRY_PROCESSED | LDRP_PROCESS_ATTACH_CALLED;
// set the correct values in the Ddag node struct
pLdrEntry->DdagNode = (PLDR_DDAG_NODE)HeapAlloc(
GetProcessHeap(),
pLdrEntry->DdagNode = (PLDR_DDAG_NODE)pHeapAlloc(
pGetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(LDR_DDAG_NODE)
);