-
Notifications
You must be signed in to change notification settings - Fork 419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Not work with x64 independent code #9
Comments
Hmm, did you launch the 64 bit app with runshc32.exe? It is a version for 32 bit binaries only.Try launching it with runshc64.exe rather than runshc32.exe and let me know if it helps. In the meanwhile I will check your code... |
My mistake is in the description. |
Ok, thank you for the clarification. Sometimes users commit such mistakes, so I just wanted to start by making sure it is not the case. |
I compiled your code as multi-threaded (flag |
You example working. Maybe differences in the compiler options? |
I generated my sln with the help of CMake, using this cmake_minimum_required (VERSION 2.8)
project (test_case1)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set (srcs
main.cpp
)
set (hdrs
)
add_executable ( ${PROJECT_NAME} ${hdrs} ${srcs}) And the main.cpp #include <Windows.h>
#include <winternl.h>
#include <iostream>
#define ROTR32(value, shift) (((DWORD) value >> (BYTE) shift) | ((DWORD) value << (32 - (BYTE) shift)))
typedef struct _MY_PEB_LDR_DATA {
ULONG Length;
BOOL Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
} MY_PEB_LDR_DATA, *PMY_PEB_LDR_DATA;
typedef struct _MY_LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
} MY_LDR_DATA_TABLE_ENTRY, *PMY_LDR_DATA_TABLE_ENTRY;
typedef HMODULE(WINAPI* FuncLoadLibraryA) (LPCSTR lpFileName);
typedef int(WINAPI* FuncMessageBoxA)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
HMODULE GetProcAddressByHash(_In_ DWORD dwModuleFunctionHash)
{
PPEB PebAddress;
PMY_PEB_LDR_DATA pLdr;
PMY_LDR_DATA_TABLE_ENTRY pDataTableEntry;
PVOID pModuleBase;
PIMAGE_NT_HEADERS pNTHeader;
DWORD dwExportDirRVA;
PIMAGE_EXPORT_DIRECTORY pExportDir;
PLIST_ENTRY pNextModule;
DWORD dwNumFunctions;
USHORT usOrdinalTableIndex;
PDWORD pdwFunctionNameBase;
PCSTR pFunctionName;
UNICODE_STRING BaseDllName;
DWORD dwModuleHash;
DWORD dwFunctionHash;
PCSTR pTempChar;
DWORD i;
#if defined(_WIN64)
PebAddress = (PPEB)__readgsqword(0x60);
#elif defined(_M_ARM)
// I can assure you that this is not a mistake. The C compiler improperly emits the proper opcodes
// necessary to get the PEB.Ldr address
PebAddress = (PPEB)((ULONG_PTR)_MoveFromCoprocessor(15, 0, 13, 0, 2) + 0);
__emit(0x00006B1B);
#else
PebAddress = (PPEB)__readfsdword(0x30);
#endif
pLdr = (PMY_PEB_LDR_DATA)PebAddress->Ldr;
pNextModule = pLdr->InLoadOrderModuleList.Flink;
pDataTableEntry = (PMY_LDR_DATA_TABLE_ENTRY)pNextModule;
while (pDataTableEntry->DllBase != NULL)
{
dwModuleHash = 0;
pModuleBase = pDataTableEntry->DllBase;
BaseDllName = pDataTableEntry->BaseDllName;
pNTHeader = (PIMAGE_NT_HEADERS)((ULONG_PTR)pModuleBase + ((PIMAGE_DOS_HEADER)pModuleBase)->e_lfanew);
dwExportDirRVA = pNTHeader->OptionalHeader.DataDirectory[0].VirtualAddress;
// Get the next loaded module entry
pDataTableEntry = (PMY_LDR_DATA_TABLE_ENTRY)pDataTableEntry->InLoadOrderLinks.Flink;
// If the current module does not export any functions, move on to the next module.
if (dwExportDirRVA == 0)
{
continue;
}
// Calculate the module hash
for (i = 0; i < BaseDllName.MaximumLength; i++)
{
pTempChar = ((PCSTR)BaseDllName.Buffer + i);
dwModuleHash = ROTR32(dwModuleHash, 13);
if (*pTempChar >= 0x61)
{
dwModuleHash += *pTempChar - 0x20;
}
else
{
dwModuleHash += *pTempChar;
}
}
pExportDir = (PIMAGE_EXPORT_DIRECTORY)((ULONG_PTR)pModuleBase + dwExportDirRVA);
dwNumFunctions = pExportDir->NumberOfNames;
pdwFunctionNameBase = (PDWORD)((PCHAR)pModuleBase + pExportDir->AddressOfNames);
for (i = 0; i < dwNumFunctions; i++)
{
dwFunctionHash = 0;
pFunctionName = (PCSTR)(*pdwFunctionNameBase + (ULONG_PTR)pModuleBase);
pdwFunctionNameBase++;
pTempChar = pFunctionName;
do
{
dwFunctionHash = ROTR32(dwFunctionHash, 13);
dwFunctionHash += *pTempChar;
pTempChar++;
} while (*(pTempChar - 1) != 0);
dwFunctionHash += dwModuleHash;
if (dwFunctionHash == dwModuleFunctionHash)
{
usOrdinalTableIndex = *(PUSHORT)(((ULONG_PTR)pModuleBase + pExportDir->AddressOfNameOrdinals) + (2 * i));
return (HMODULE)((ULONG_PTR)pModuleBase + *(PDWORD)(((ULONG_PTR)pModuleBase + pExportDir->AddressOfFunctions) + (4 * usOrdinalTableIndex)));
}
}
}
// All modules have been exhausted and the function was not found.
return NULL;
}
// this string need to add .reloc table to x64 .exe file
const char* data = "reloc_fix";
VOID CodeRun(VOID)
{
char module[] = { 'u', 's', 'e', 'r', '3', '2', '.', 'd', 'l', 'l', 0 };
FuncLoadLibraryA MyLoadLibraryA = (FuncLoadLibraryA)GetProcAddressByHash(0x0726774C);
MyLoadLibraryA((LPCSTR)module);
FuncMessageBoxA MyMessageBoxA = (FuncMessageBoxA)GetProcAddressByHash(0x07568345);
MyMessageBoxA(0, 0, 0, 0);
}
int main()
{
CodeRun();
return 0;
} |
Maybe problem that i use custom entrypoint and /NODEFAULTLIB ? |
Possibly... I am gonna check in details how exactly it affects the loading process... I will let you know what I found. |
Thanks you. |
Thanks to your testcase I found some bugs in the stub, and I fixed them. It should work now. You can download the latest build from the build server: x64bit build |
Now all okey. |
Hello
I tried to convert the PE file without imports (base-independent file)
If the file is built in x86 mode, then no problem, it is launched through runshc32.exe
But if x64, then it fails and crashes. I don’t understand what’s the matter. This seems to be a bug.
Source code of .exe file (entrypoint - CodeRun function):
The text was updated successfully, but these errors were encountered: