Skip to content

Commit

Permalink
Optimize parse
Browse files Browse the repository at this point in the history
  • Loading branch information
llccd committed Oct 4, 2024
1 parent ad3157a commit 7f821b8
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 41 deletions.
2 changes: 1 addition & 1 deletion RDPWrapOffsetFinder/Patch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ int SingleUserPatch(ZydisDecoder* decoder, size_t RVA, size_t base, size_t targe
"SingleUserCode.x64=mov_eax_1_nop_%d\n", IP - base, instruction.length - 5);
return 1;
}
if (decoder->stack_width == ZYDIS_STACK_WIDTH_64 && instruction.mnemonic == ZYDIS_MNEMONIC_CMP &&
if (instruction.mnemonic == ZYDIS_MNEMONIC_CMP &&
instruction.length <= 8 && operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY &&
(operands[0].mem.base == ZYDIS_REGISTER_RBP || operands[0].mem.base == ZYDIS_REGISTER_RSP) &&
(operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && operands[1].imm.value.u == 1 ||
Expand Down
74 changes: 38 additions & 36 deletions RDPWrapOffsetFinder_nosym/RDPWrapOffsetFinder_nosym.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,6 @@ class range {
}
};

PIMAGE_SECTION_HEADER findSection(PIMAGE_NT_HEADERS64 pNT, const char* str)
{
auto pSection = IMAGE_FIRST_SECTION(pNT);

for (size_t i = 0; i < pNT->FileHeader.NumberOfSections; i++)
if (CSTR_EQUAL == CompareStringA(LOCALE_INVARIANT, 0, (char*)pSection[i].Name, -1, str, -1))
return pSection + i;

return NULL;
}

size_t pattenMatch(size_t base, PIMAGE_SECTION_HEADER pSection, const void *str, size_t size)
{
size_t rdata = base + pSection->VirtualAddress;
Expand Down Expand Up @@ -222,42 +211,53 @@ int main(int argc, char** argv)
PVOID OldValue;
Wow64DisableWow64FsRedirection(&OldValue);
#endif // _WIN64
auto hFile = CreateFileA(szTermsrv, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
auto hMod = LoadLibraryExA(szTermsrv, NULL, LOAD_LIBRARY_AS_DATAFILE);
#ifndef _WIN64
Wow64RevertWow64FsRedirection(OldValue);
#endif // _WIN64
if (hFile == INVALID_HANDLE_VALUE) return -1;
auto hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY | SEC_IMAGE_NO_EXECUTE, 0, 0, NULL);
if (!hMap) return -6;
auto base = (size_t)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
if (!base) return -7;
auto pDos = (PIMAGE_DOS_HEADER)base;
auto pNT = (PIMAGE_NT_HEADERS64)(base + pDos->e_lfanew);
auto text = findSection(pNT, ".text");
auto rdata = findSection(pNT, ".rdata");
if (!rdata) rdata = text;

auto CDefPolicy_Query = pattenMatch(base, rdata, Query, sizeof(Query) - 1);
auto GetInstanceOfTSLicense = pattenMatch(base, rdata, InstanceOfLicense, sizeof(InstanceOfLicense) - 1);
auto IsSingleSessionPerUserEnabled = pattenMatch(base, rdata, SingleSessionEnabled, sizeof(SingleSessionEnabled) - 1);
auto IsSingleSessionPerUser = pattenMatch(base, rdata, "IsSingleSessionPerUser", sizeof("IsSingleSessionPerUser"));
if (!memcmp((void*)(base + IsSingleSessionPerUser - 8), "CUtils::", 8)) IsSingleSessionPerUser -= 8;
auto IsLicenseTypeLocalOnly = pattenMatch(base, rdata, LocalOnly, sizeof(LocalOnly) - 1);
auto bRemoteConnAllowed = pattenMatch(base, rdata, AllowRemote, sizeof(AllowRemote));
if (!hMod) return -1;
auto base2 = (size_t)hMod & ~3;
auto pDos = (PIMAGE_DOS_HEADER)base2;
auto pNT = (PIMAGE_NT_HEADERS64)(base2 + pDos->e_lfanew);
auto text = IMAGE_FIRST_SECTION(pNT);
PIMAGE_SECTION_HEADER rdata = NULL;

PIMAGE_DATA_DIRECTORY pImportDirectory;
if (pNT->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
DWORD SizeOfImage;
if (pNT->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
pImportDirectory = pNT->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_IMPORT;
else
SizeOfImage = pNT->OptionalHeader.SizeOfImage;
}
else {
pImportDirectory = ((PIMAGE_NT_HEADERS32)pNT)->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_IMPORT;
SizeOfImage = ((PIMAGE_NT_HEADERS32)pNT)->OptionalHeader.SizeOfImage;
}

auto base = (size_t)VirtualAlloc(NULL, SizeOfImage, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
for (size_t i = 0; i < pNT->FileHeader.NumberOfSections; i++) {
memcpy((void*)(base + text[i].VirtualAddress), (void*)(base2 + text[i].PointerToRawData), text[i].Misc.VirtualSize);
if (!rdata && CSTR_EQUAL == CompareStringA(LOCALE_INVARIANT, 0, (char*)text[i].Name, -1, ".rdata", -1))
rdata = text + i;
}

if (!rdata) rdata = text;

auto pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(base + pImportDirectory->VirtualAddress);
auto import_msvcrt = findImportImage(pImportDescriptor, base, "msvcrt.dll");
if (!import_msvcrt) return -2;

size_t memset_addr, VerifyVersion_addr = -1;
auto import_krnl32 = findImportImage(pImportDescriptor, base, "api-ms-win-core-kernel32-legacy-l1-1-1.dll");
if (!import_krnl32) import_krnl32 = findImportImage(pImportDescriptor, base, "KERNEL32.dll");


auto CDefPolicy_Query = pattenMatch(base, rdata, Query, sizeof(Query) - 1);
auto GetInstanceOfTSLicense = pattenMatch(base, rdata, InstanceOfLicense, sizeof(InstanceOfLicense) - 1);
auto IsSingleSessionPerUserEnabled = pattenMatch(base, rdata, SingleSessionEnabled, sizeof(SingleSessionEnabled) - 1);
auto IsSingleSessionPerUser = pattenMatch(base, rdata, "IsSingleSessionPerUser", sizeof("IsSingleSessionPerUser"));
if (!memcmp((void*)(base + IsSingleSessionPerUser - 8), "CUtils::", 8)) IsSingleSessionPerUser -= 8;
auto IsLicenseTypeLocalOnly = pattenMatch(base, rdata, LocalOnly, sizeof(LocalOnly) - 1);
auto bRemoteConnAllowed = pattenMatch(base, rdata, AllowRemote, sizeof(AllowRemote));

size_t CDefPolicy_Query_addr = 0, GetInstanceOfTSLicense_addr = 0, IsSingleSessionPerUserEnabled_addr = 0,
IsSingleSessionPerUser_addr = 0, IsLicenseTypeLocalOnly_addr = 0, bRemoteConnAllowed_xref;
DWORD CSLQuery_Initialize_addr = 0, CSLQuery_Initialize_len = 0x11000;
Expand Down Expand Up @@ -331,7 +331,8 @@ int main(int argc, char** argv)
target = (size_t)operands[0].imm.value.u - ImageBase;
else if (instruction.mnemonic == ZYDIS_MNEMONIC_MOV && operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
(operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instruction.length == 5 ||
operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instruction.length >= 7 && operands[0].mem.base == ZYDIS_REGISTER_EBP))
operands[0].type == ZYDIS_OPERAND_TYPE_MEMORY && instruction.length >= 7 &&
(operands[0].mem.base == ZYDIS_REGISTER_EBP || operands[0].mem.base == ZYDIS_REGISTER_ESP)))
target = (size_t)operands[1].imm.value.u - ImageBase;
else goto nxt;

Expand All @@ -351,6 +352,7 @@ int main(int argc, char** argv)
}
else goto nxt;
if (visited.empty()) visited.add(addr, j);
while (!jmpAddr.empty()) jmpAddr.pop();
if (CDefPolicy_Query_addr && GetInstanceOfTSLicense_addr && IsSingleSessionPerUserEnabled_addr &&
IsSingleSessionPerUser_addr && IsLicenseTypeLocalOnly_addr && CSLQuery_Initialize_addr) goto fin;
goto out;
Expand Down Expand Up @@ -384,9 +386,9 @@ int main(int argc, char** argv)
fin:;
}

auto hResInfo = FindResourceW((HMODULE)base, MAKEINTRESOURCEW(1), MAKEINTRESOURCEW(16));
auto hResInfo = FindResourceW(hMod, MAKEINTRESOURCEW(1), MAKEINTRESOURCEW(16));
if (!hResInfo) return -4;
auto hResData = (PVS_VERSIONINFO)LoadResource((HMODULE)base, hResInfo);
auto hResData = (PVS_VERSIONINFO)LoadResource(hMod, hResInfo);
if (!hResData) return -5;

printf("[%hu.%hu.%hu.%hu]\n", HIWORD(hResData->Value.dwFileVersionMS), LOWORD(hResData->Value.dwFileVersionMS),
Expand Down
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ This project depends on [zydis](https://github.com/zyantific/zydis), you needed

- Windows 8 Consumer Preview (SLPolicyFunc=New_Win8SL_CP) is currently not supported

- 32bit versions are not widely tested and may return wrong result
- PDB symbol of `termsrv.dll` is needed. If the program outputs "Symbol not found", check your Internet connection to Microsoft symbol server. You can manually set environment variable `_NT_SYMBOL_PATH` to use a symbol proxy

- PDB symbol of termsrv.dll is needed. If the program outputs nothing, check your Internet connection to Microsoft symbol server. You can manually set environment variable `_NT_SYMBOL_PATH` to use a symbol proxy

- If symbol is not available, you can try the `_nosymbol` version which manually search pattens. `_nosymbol` version only supports 64bit system
- If the required symbol is not available, you can try the `_nosymbol` version which manually search pattens. Using the `_nosymbol` version with 32bit binaries is not widely tested and may return wrong results

0 comments on commit 7f821b8

Please sign in to comment.