Last active
April 29, 2024 21:37
-
-
Save rbmm/5d90a2cc4d716825c12f57475993450b to your computer and use it in GitHub Desktop.
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
PVOID AccessResource(_In_ PVOID hmod, _In_ PCWSTR pri[], _In_ DWORD level, _Out_opt_ PDWORD pcb) | |
{ | |
if (pcb) *pcb = 0; | |
if (!level) return 0; | |
DWORD size; | |
PVOID resBase = RtlImageDirectoryEntryToData(hmod, FALSE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size); | |
PIMAGE_RESOURCE_DIRECTORY pird = (PIMAGE_RESOURCE_DIRECTORY)resBase; | |
PIMAGE_RESOURCE_DIRECTORY_ENTRY pirde, _pirde; | |
PIMAGE_RESOURCE_DATA_ENTRY pde = 0; | |
DWORD Offset; | |
do | |
{ | |
if (!pird) return 0; | |
pirde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pird + 1); | |
DWORD a = 0, b = pird->NumberOfNamedEntries, o; | |
PCWSTR Id = *pri++; | |
BOOL Named = TRUE; | |
if (IS_INTRESOURCE(Id)) | |
{ | |
Named = FALSE; | |
pirde += pird->NumberOfNamedEntries; | |
b = pird->NumberOfIdEntries; | |
} | |
if (!b || ((ULONG_PTR)(pirde + b) - (ULONG_PTR)resBase) >= size) return 0; | |
do | |
{ | |
int i; | |
_pirde = &pirde[o = (a + b) >> 1]; | |
if (Named) | |
{ | |
if (!_pirde->NameIsString) return 0; | |
PIMAGE_RESOURCE_DIR_STRING_U pu = (PIMAGE_RESOURCE_DIR_STRING_U) | |
RtlOffsetToPointer(resBase, _pirde->NameOffset); | |
UNICODE_STRING us1, us2 = { pu->Length * sizeof(WCHAR), us2.Length, pu->NameString }; | |
RtlInitUnicodeString(&us1, Id); | |
i = RtlCompareUnicodeString(&us1, &us2, FALSE); | |
} | |
else | |
{ | |
if (_pirde->NameIsString) return 0; | |
i = Id ? (ULONG)(ULONG_PTR)Id - _pirde->Id : 0; | |
} | |
if (!i) break; | |
if (i < 0) b = o; else a = o + 1; | |
} while(a < b); | |
if (b <= a) return 0; | |
if (_pirde->DataIsDirectory) | |
{ | |
Offset = _pirde->OffsetToDirectory; | |
if ((size <= Offset) || | |
(size - Offset < sizeof (IMAGE_RESOURCE_DIRECTORY))) return 0; | |
pird = (PIMAGE_RESOURCE_DIRECTORY)RtlOffsetToPointer(resBase, Offset); | |
} | |
else | |
{ | |
Offset = _pirde->OffsetToData; | |
if ((size <= Offset) || | |
(size - Offset < sizeof (IMAGE_RESOURCE_DATA_ENTRY))) return 0; | |
pde = (PIMAGE_RESOURCE_DATA_ENTRY )RtlOffsetToPointer(resBase, Offset); | |
pird = 0; | |
} | |
} while(--level); | |
if (!pde) return 0; | |
*pcb = pde->Size; | |
return RtlAddressInSectionTable(RtlImageNtHeader(hmod), hmod, pde->OffsetToData); | |
} | |
struct _MI | |
{ | |
HANDLE hFile; // IDebugDataSpaces* pDataSpace | |
ULONG_PTR ImageBase; | |
ULONG ImageSize; | |
BOOL bFail; | |
}; | |
#include "../inc/rtlframe.h" | |
typedef struct RTL_FRAME<_MI> MI; | |
LONG NTAPI OnVex(::PEXCEPTION_POINTERS pep) | |
{ | |
::PEXCEPTION_RECORD ExceptionRecord = pep->ExceptionRecord; | |
if (STATUS_ACCESS_VIOLATION == ExceptionRecord->ExceptionCode && | |
1 < ExceptionRecord->NumberParameters && | |
0 == ExceptionRecord->ExceptionInformation[0]) | |
{ | |
if (_MI* p = MI::get()) | |
{ | |
ULONG_PTR addr = ExceptionRecord->ExceptionInformation[1]; | |
union { | |
ULONG_PTR offset; | |
LARGE_INTEGER ByteOffset; | |
}; | |
ULONG_PTR ImageBase = p->ImageBase; | |
offset = addr - ImageBase; | |
if (offset < p->ImageSize) | |
{ | |
SIZE_T s = 1; | |
if (0 <= ZwAllocateVirtualMemory(NtCurrentProcess(), (void**)&addr, 0, &s, MEM_COMMIT, PAGE_READWRITE)) | |
{ | |
offset = addr - p->ImageBase; | |
IO_STATUS_BLOCK iosb; | |
// p->pDataSpace->ReadVirtual | |
if (0 > NtReadFile(p->hFile, 0, 0, 0, &iosb, (PBYTE)ImageBase + offset, (ULONG)s, &ByteOffset, 0)) | |
{ | |
p->bFail = TRUE; | |
} | |
return EXCEPTION_CONTINUE_EXECUTION; | |
} | |
} | |
} | |
} | |
return EXCEPTION_CONTINUE_SEARCH; | |
} | |
void checkmem(PBYTE pb, ULONG cb) | |
{ | |
if (cb) | |
{ | |
do | |
{ | |
if (*pb++) | |
{ | |
__nop(); | |
} | |
} while (--cb); | |
} | |
} | |
void yyy(PCWSTR pszFile) | |
{ | |
HANDLE hFile = CreateFile(pszFile, FILE_GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); | |
if (INVALID_HANDLE_VALUE != hFile) | |
{ | |
enum { fImageSize = 0x8000000}; | |
if (PVOID ImageBase = VirtualAlloc(0, fImageSize, MEM_RESERVE, PAGE_READWRITE)) | |
{ | |
MI m; | |
m.hFile = hFile; | |
m.ImageBase = (ULONG_PTR)ImageBase; | |
m.ImageSize = fImageSize; | |
m.bFail = FALSE; | |
if (PVOID h = AddVectoredExceptionHandler(TRUE, OnVex)) | |
{ | |
ULONG cb; | |
PCWSTR a[] = { RT_VERSION, MAKEINTRESOURCEW(1), MAKEINTRESOURCEW(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT)) }; | |
PCWSTR c[] = { RT_RCDATA, L"FUNCTIONEXTENTLIST", 0 }; | |
PCWSTR b[] = { RT_MESSAGETABLE, MAKEINTRESOURCEW(1), MAKEINTRESOURCEW(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT)) }; | |
PVOID pv; | |
if ((pv = AccessResource(ImageBase, a, _countof(a), &cb)) && !m.bFail) | |
{ | |
checkmem((PBYTE)pv, cb); | |
} | |
if ((pv = AccessResource(ImageBase, b, _countof(b), &cb)) && !m.bFail) | |
{ | |
checkmem((PBYTE)pv, cb); | |
} | |
if ((pv = AccessResource(ImageBase, c, _countof(c), &cb)) && !m.bFail) | |
{ | |
checkmem((PBYTE)pv, cb); | |
} | |
RemoveVectoredExceptionHandler(h); | |
} | |
VirtualFree(ImageBase, 0, MEM_RELEASE); | |
} | |
NtClose(hFile); | |
} | |
} | |
yyy(L"c:\\windows\\system32\\ntoskrnl.exe"); | |
// https://github.com/rbmm/LIB/blob/master/INC/rtlframe.h |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment