1
0
mirror of https://github.com/rbmm/SC synced 2026-06-08 17:03:41 +00:00
Files
rbmm bc7e3e123d ++
2025-02-08 16:01:22 +02:00

439 lines
7.0 KiB
C++

#include "stdafx.h"
#include "map.h"
#include "file.h"
BOOL IMP_HELP::Init(PVOID hmod)
{
ULONG s;
if (PIMAGE_IMPORT_DESCRIPTOR piid = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(
hmod, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &s))
{
if (s /= sizeof(IMAGE_IMPORT_DESCRIPTOR))
{
_M_n = s, _M_piid = piid, _M_hmod = hmod;
return TRUE;
}
}
return FALSE;
}
PCSTR IMP_HELP::GetName(ULONG rva, DWORD FirstThunk, void** pFunction, PIMAGE_THUNK_DATA pThunk)
{
while (void* Function = *pFunction++)
{
IMAGE_THUNK_DATA Thunk = *pThunk++;
if (rva == FirstThunk)
{
_M_pFunction = pFunction;
_M_pThunk = pThunk;
if (IMAGE_SNAP_BY_ORDINAL(Thunk.u1.Ordinal))
{
if (0 < sprintf_s(_M_buf, _countof(_M_buf), "#%u", (ULONG)IMAGE_ORDINAL(Thunk.u1.Ordinal)))
{
return _M_buf;
}
return 0;
}
return (PCSTR)reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(
RtlOffsetToPointer(_M_hmod, Thunk.u1.AddressOfData))->Name;
}
FirstThunk += sizeof(PVOID);
}
_M_pFunction = 0;
_M_pThunk = 0;
return 0;
}
PCSTR GetNameFormat(PCSTR str, PCSTR name, ULONG* pn)
{
*pn = 0;
if (strcmp(name, str))
{
#ifdef _X86_
BOOL f = FALSE;
switch (*name++)
{
case '@':
f = TRUE;
case '_':
if (PCSTR pc = strchr(name, '@'))
{
if (!memcmp(name, str, pc - name))
{
ULONG n = strtoul(pc + 1, const_cast<PSTR*>(&pc), 10);
if (!*pc && !(n & 3))
{
*pn = n;
// __fastcall : __stdcall
return f ? "createFuncF %hs, %hs, %u\r\n" : "createFuncS %hs, %hs, %u\r\n";
}
}
}
else if (!strcmp(name, str))
{
// __cdecl
return "createFuncC %hs, %hs\r\n";
}
break;
}
#endif
return 0;
}
// name == str
return "createFunc %hs, %hs\r\n";
}
PCSTR IMP_HELP::GetName(ULONG rva)
{
PVOID hmod = _M_hmod;
ULONG n = _M_n;
PIMAGE_IMPORT_DESCRIPTOR piid = _M_piid;
if (void** pFunction = _M_pFunction)
{
if (PCSTR name = GetName(rva, RtlPointerToOffset(hmod, pFunction), pFunction, _M_pThunk))
{
return name;
}
}
do
{
DWORD Name = piid->Name;
if (!Name)
{
return 0;
}
if (DWORD FirstThunk = piid->FirstThunk)
{
if (rva < FirstThunk)
{
continue;
}
if (DWORD OriginalFirstThunk = piid->OriginalFirstThunk)
{
if (PCSTR name = GetName(rva, FirstThunk,
(void**)RtlOffsetToPointer(hmod, FirstThunk),
(PIMAGE_THUNK_DATA)RtlOffsetToPointer(hmod, OriginalFirstThunk)))
{
return name;
}
}
}
} while (piid++, --n);
return 0;
}
NTSTATUS IMP_HELP::ProcessMAP(
PCWSTR pszImp,
PSTR pcsz,
ULONG iSection,
ULONG ofs,
ULONG_PTR Va,
ULONG s)
{
PVOID hmod = _M_hmod;
PSTR buf = pcsz, psz = buf;
ULONG64 u;
BOOL f = FALSE;
ULONG_PTR ImageBase = 0;
__0:
PSTR pcszLine = pcsz;
static const char plai[] = " Preferred load address is ";
if (!f && !memcmp(pcsz, plai, _countof(plai) - 1))
{
if (ImageBase)
{
return STATUS_BAD_DATA;
}
u = _strtoui64(pcsz + _countof(plai) - 1, const_cast<char**>(&pcsz), 16);
if (!u || '\r' != *pcsz++ || '\n' != *pcsz++)
{
return STATUS_BAD_DATA;
}
ImageBase = (ULONG_PTR)u;
Va += ImageBase;
DbgPrint("ImageBase = %p, Va = %p\r\n", ImageBase, Va);
goto __0;
}
ULONG i = strtoul(pcsz, const_cast<char**>(&pcsz), 16);
if (':' != *pcsz)
{
__1:
if (!(pcsz = strchr(pcsz, '\r')) || '\n' != *++pcsz)
{
return STATUS_BAD_DATA;
}
++pcsz;
goto __0;
}
if (i != iSection)
{
goto __1;
}
i = strtoul(pcsz + 1, const_cast<char**>(&pcsz), 16);
if (' ' != *pcsz)
{
return STATUS_BAD_DATA;
}
if (i != ofs)
{
goto __1;
}
if (f)
{
pcsz = pcszLine;
}
else
{
i = strtoul(pcsz + 1, &pcsz, 16);
// <iSection>:<ofs> <s>H .idata$5 DATA
if ('H' != *pcsz || s != i)
{
return STATUS_BAD_DATA;
}
f = TRUE;
goto __1;
}
//////////////////////////////////////////////////////////////////////////
NTSTATUS status;
__loop:
void** ppfn = (void**)RtlOffsetToPointer(hmod, Va - ImageBase);
void* pfn = *ppfn;
i = strtoul(pcsz, const_cast<char**>(&pcsz), 16);
if (':' != *pcsz || iSection != i)
{
return STATUS_BAD_DATA;
}
i = strtoul(pcsz + 1, const_cast<char**>(&pcsz), 16);
if (' ' != *pcsz || ofs != i)
{
//while (!IsDebuggerPresent()) Sleep(1000); __debugbreak();
// zero end IAT
do
{
if (*ppfn++)
{
DbgPrint("##!! ofs(%p) != i(%p) !!##\r\n", ofs, i);
return STATUS_BAD_DATA;
}
} while (s -= sizeof(PVOID));
__ok:
status = SaveToFile(pszImp, buf, RtlPointerToOffset(buf, psz), TRUE);
return 0 > status ? status : STATUS_MORE_PROCESSING_REQUIRED;
}
ofs += sizeof(PVOID);
BOOL __imp_ = FALSE;
__space:
switch (*pcsz++)
{
case ' ':
goto __space;
default:
return STATUS_BAD_DATA;
case '_':
if (memcmp(pcsz, "_imp_", 5))
{
return STATUS_BAD_DATA;
}
pcsz += 5;
__imp_ = TRUE;
case '\\':
INT k = -1;
PCSTR name = pcsz;
while (' ' < *pcsz) pcsz++;
*pcsz++ = 0;
if (!strcmp(name, "__chkstk") || !strcmp(name, "__alloca_probe"))
{
DbgPrint("!!!! %hs\\%hs imported !!!!!\r\n", "__chkstk", "__alloca_probe");
return STATUS_BAD_DATA;
}
u = _strtoui64(pcsz, const_cast<char**>(&pcsz), 16);
if (Va != u)
{
return STATUS_BAD_DATA;
}
Va += sizeof(PVOID);
PCSTR pszLib = 0;
__00:
switch (*pcsz)
{
case 0:
return STATUS_BAD_DATA;
case ':':
*pcsz++ = 0;
goto __01;
default:
if (!pszLib)
{
pszLib = pcsz;
}
case ' ':
pcsz++;
goto __00;
}
__01:
PCSTR pszDLL = pcsz;
__02:
switch (*pcsz++)
{
case 0:
case ':':
return STATUS_BAD_DATA;
default:
goto __02;
case '\r':
pcsz[-1] = 0;
break;
}
if ('\n' != *pcsz++)
{
return STATUS_BAD_DATA;
}
ULONG cb = RtlPointerToOffset(psz, name);
if (__imp_)
{
__imp_ = FALSE;
if (!pfn)
{
DbgPrint("##!! pfn !!## at %p\r\n", u);
return STATUS_BAD_DATA;
}
if (PCSTR str = GetName((ULONG)(u - ImageBase)))
{
ULONG np;
if (PCSTR fmt = GetNameFormat(str, name, &np))
{
k = sprintf_s(psz, cb, fmt, pszLib, str, np);
}
else
{
k = sprintf_s(psz, cb, "createFunc? %hs, %hs, '%hs'\r\n", pszLib, name, str);
}
}
else
{
return STATUS_BAD_DATA;
}
}
else
{
if (pfn)
{
DbgPrint("##!! pfn=%p !!## at %p\r\n", pfn, u);
return STATUS_BAD_DATA;
}
if (!_stricmp(pszDLL, "ntdll.dll"))
{
pszDLL = "";
}
k = sprintf_s(psz, cb, "\r\nHMOD %hs, <%hs>\r\n\r\n", pszLib, pszDLL);
}
if (0 >= k)
{
return STATUS_INTERNAL_ERROR;
}
psz += k;
if (s -= sizeof(PVOID))
{
goto __loop;
}
goto __ok;
}
}
NTSTATUS IMP_HELP::ProcessMAP(
PCWSTR pszImp,
PCWSTR pszMap,
ULONG iSection,
ULONG ofs,
ULONG_PTR Va,
ULONG s)
{
PBYTE pb;
ULONG cb;
DbgPrint("ProcessMAP(%04x:%08x %p [%x])...\r\n", iSection, ofs, Va, s);
NTSTATUS status = ReadFromFile(pszMap, &pb, &cb, 0, 1);
if (0 <= status)
{
pb[cb - 1] = 0;
status = ProcessMAP(pszImp, (PSTR)pb, iSection, ofs, Va, s);
delete[] pb;
}
return status;
}