2016-09-08 13:45:52 +08:00
|
|
|
|
#ifndef _GDIPP_EXE
|
|
|
|
|
#include "settings.h"
|
|
|
|
|
#include "override.h"
|
|
|
|
|
#include <tlhelp32.h>
|
|
|
|
|
#include <shlwapi.h> //DLLVERSIONINFO
|
|
|
|
|
#include "undocAPI.h"
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
#include <dwrite_1.h>
|
|
|
|
|
#include <dwrite_2.h>
|
|
|
|
|
#include <dwrite_3.h>
|
2018-08-02 11:07:50 +08:00
|
|
|
|
#include <locale>
|
2016-09-08 13:45:52 +08:00
|
|
|
|
#include "wow64ext.h"
|
|
|
|
|
#include <VersionHelpers.h>
|
2019-02-28 16:57:42 +08:00
|
|
|
|
#include "crc32.h"
|
2016-09-08 13:45:52 +08:00
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
// win2k以降
|
2016-09-08 13:45:52 +08:00
|
|
|
|
//#pragma comment(linker, "/subsystem:windows,5.0")
|
2016-09-08 14:13:00 +08:00
|
|
|
|
#ifndef _WIN64
|
2018-10-18 15:29:38 +08:00
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
#pragma comment(lib, "wow64ext_dbg.lib")
|
|
|
|
|
#else
|
2016-09-08 13:45:52 +08:00
|
|
|
|
#pragma comment(lib, "wow64ext.lib")
|
2016-09-08 14:13:00 +08:00
|
|
|
|
#endif
|
2018-10-18 15:29:38 +08:00
|
|
|
|
#endif
|
2016-09-08 13:45:52 +08:00
|
|
|
|
|
|
|
|
|
EXTERN_C LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
|
|
|
|
|
{
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//何もしない
|
2016-09-08 13:45:52 +08:00
|
|
|
|
return CallNextHookEx(NULL, code, wParam, lParam);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EXTERN_C HRESULT WINAPI GdippDllGetVersion(DLLVERSIONINFO* pdvi)
|
|
|
|
|
{
|
|
|
|
|
if (!pdvi || pdvi->cbSize < sizeof(DLLVERSIONINFO)) {
|
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const UINT cbSize = pdvi->cbSize;
|
|
|
|
|
ZeroMemory(pdvi, cbSize);
|
|
|
|
|
pdvi->cbSize = cbSize;
|
|
|
|
|
|
|
|
|
|
HRSRC hRsrc = FindResource(GetDLLInstance(), MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
|
|
|
|
|
if (!hRsrc) {
|
|
|
|
|
return E_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGLOBAL hGlobal = LoadResource(GetDLLInstance(), hRsrc);
|
|
|
|
|
if (!hGlobal) {
|
|
|
|
|
return E_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const WORD* lpwPtr = (const WORD*)LockResource(hGlobal);
|
|
|
|
|
if (lpwPtr[1] != sizeof(VS_FIXEDFILEINFO)) {
|
|
|
|
|
return E_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const VS_FIXEDFILEINFO* pvffi = (const VS_FIXEDFILEINFO*)(lpwPtr + 20);
|
|
|
|
|
if (pvffi->dwSignature != VS_FFI_SIGNATURE ||
|
|
|
|
|
pvffi->dwStrucVersion != VS_FFI_STRUCVERSION) {
|
|
|
|
|
return E_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//8.0.2006.1027
|
|
|
|
|
// -> Major: 8, Minor: 2006, Build: 1027
|
|
|
|
|
pdvi->dwMajorVersion = HIWORD(pvffi->dwFileVersionMS);
|
|
|
|
|
pdvi->dwMinorVersion = LOWORD(pvffi->dwFileVersionMS) * 10 + HIWORD(pvffi->dwFileVersionLS);
|
|
|
|
|
pdvi->dwBuildNumber = LOWORD(pvffi->dwFileVersionLS);
|
|
|
|
|
pdvi->dwPlatformID = DLLVER_PLATFORM_NT;
|
|
|
|
|
|
|
|
|
|
if (pdvi->cbSize < sizeof(DLLVERSIONINFO2)) {
|
|
|
|
|
return S_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DLLVERSIONINFO2* pdvi2 = (DLLVERSIONINFO2*)pdvi;
|
|
|
|
|
pdvi2->ullVersion = MAKEDLLVERULL(pdvi->dwMajorVersion, pdvi->dwMinorVersion, pdvi->dwBuildNumber, 2);
|
|
|
|
|
return S_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif //!_GDIPP_EXE
|
|
|
|
|
|
|
|
|
|
extern LONG interlock;
|
|
|
|
|
extern LONG g_bHookEnabled;
|
|
|
|
|
#include "gdiPlusFlat2.h"
|
|
|
|
|
|
|
|
|
|
#ifdef USE_DETOURS
|
2023-08-21 15:59:22 +08:00
|
|
|
|
//detours
|
2016-09-08 13:45:52 +08:00
|
|
|
|
#include "detours.h"
|
2023-08-21 15:59:22 +08:00
|
|
|
|
//
|
2023-08-22 17:48:13 +08:00
|
|
|
|
#define HOOK_MANUALLY(rettype, name, argtype, arglist) ;
|
|
|
|
|
#define HOOK_DEFINE(rettype, name, argtype, arglist) \
|
2016-09-08 13:45:52 +08:00
|
|
|
|
DetourDetach(&(PVOID&)ORIG_##name, IMPL_##name);
|
2023-08-21 15:59:22 +08:00
|
|
|
|
LONG hook_term()
|
2016-09-08 13:45:52 +08:00
|
|
|
|
{
|
|
|
|
|
DetourTransactionBegin();
|
|
|
|
|
DetourUpdateThread(GetCurrentThread());
|
|
|
|
|
|
|
|
|
|
#include "hooklist.h"
|
|
|
|
|
|
|
|
|
|
LONG error = DetourTransactionCommit();
|
|
|
|
|
|
|
|
|
|
if (error != NOERROR) {
|
|
|
|
|
TRACE(_T("hook_term error: %#x\n"), error);
|
|
|
|
|
}
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
#undef HOOK_DEFINE
|
2023-08-21 15:59:22 +08:00
|
|
|
|
#undef HOOK_MANUALLY
|
|
|
|
|
|
2016-09-08 13:45:52 +08:00
|
|
|
|
#else
|
|
|
|
|
#include "easyhook.h"
|
2023-08-22 17:48:13 +08:00
|
|
|
|
#define HOOK_MANUALLY(rettype, name, argtype, arglist) ;
|
|
|
|
|
#define HOOK_DEFINE(rettype, name, argtype, arglist) \
|
2016-09-08 13:45:52 +08:00
|
|
|
|
ORIG_##name = name;
|
|
|
|
|
#pragma optimize("s", on)
|
|
|
|
|
static LONG hook_term()
|
|
|
|
|
{
|
|
|
|
|
#include "hooklist.h"
|
|
|
|
|
LhUninstallAllHooks();
|
|
|
|
|
return LhWaitForPendingRemovals();
|
|
|
|
|
}
|
|
|
|
|
#pragma optimize("", on)
|
|
|
|
|
#undef HOOK_DEFINE
|
|
|
|
|
#undef HOOK_MANUALLY
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
HMODULE GetSelfModuleHandle()
|
|
|
|
|
{
|
|
|
|
|
MEMORY_BASIC_INFORMATION mbi;
|
|
|
|
|
|
|
|
|
|
return ((::VirtualQuery(GetSelfModuleHandle, &mbi, sizeof(mbi)) != 0)
|
|
|
|
|
? (HMODULE) mbi.AllocationBase : NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EXTERN_C void WINAPI CreateControlCenter(IControlCenter** ret)
|
|
|
|
|
{
|
|
|
|
|
*ret = (IControlCenter*)new CControlCenter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EXTERN_C void WINAPI ReloadConfig()
|
|
|
|
|
{
|
|
|
|
|
CControlCenter::ReloadConfig();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern HINSTANCE g_dllInstance;
|
|
|
|
|
EXTERN_C void SafeUnload()
|
|
|
|
|
{
|
|
|
|
|
static BOOL bInited = false;
|
|
|
|
|
if (bInited)
|
2020-12-06 17:00:05 +08:00
|
|
|
|
return; //防重入
|
2016-09-08 13:45:52 +08:00
|
|
|
|
bInited = true;
|
|
|
|
|
while (CThreadCounter::Count())
|
|
|
|
|
Sleep(0);
|
|
|
|
|
CCriticalSectionLock * lock = new CCriticalSectionLock;
|
|
|
|
|
BOOL last;
|
|
|
|
|
if (last=InterlockedExchange(&g_bHookEnabled, FALSE)) {
|
|
|
|
|
if (hook_term()!=NOERROR)
|
|
|
|
|
{
|
|
|
|
|
InterlockedExchange(&g_bHookEnabled, last);
|
|
|
|
|
bInited = false;
|
|
|
|
|
delete lock;
|
|
|
|
|
ExitThread(ERROR_ACCESS_DENIED);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
delete lock;
|
|
|
|
|
while (CThreadCounter::Count())
|
|
|
|
|
Sleep(10);
|
|
|
|
|
Sleep(0);
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
Sleep(10);
|
|
|
|
|
} while (CThreadCounter::Count()); //double check for xp
|
|
|
|
|
|
|
|
|
|
bInited = false;
|
|
|
|
|
FreeLibraryAndExitThread(g_dllInstance, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-20 16:59:09 +08:00
|
|
|
|
void ChangeFileName(LPWSTR lpSrc, int nSize, LPCWSTR lpNewFileName) {
|
|
|
|
|
for (int i = nSize; i > 0; --i){
|
|
|
|
|
if (lpSrc[i] == L'\\') {
|
|
|
|
|
lpSrc[i + 1] = L'\0';
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
wcscat(lpSrc, lpNewFileName);
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-02 11:07:50 +08:00
|
|
|
|
std::string WstringToString(const std::wstring str)
|
|
|
|
|
{// wstringתstring
|
|
|
|
|
unsigned len = str.size() * 4;
|
|
|
|
|
setlocale(LC_CTYPE, "");
|
|
|
|
|
char *p = new char[len];
|
|
|
|
|
wcstombs(p, str.c_str(), len);
|
|
|
|
|
std::string str1(p);
|
|
|
|
|
delete[] p;
|
|
|
|
|
return str1;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-28 16:57:42 +08:00
|
|
|
|
// make a unique name with fullname + crc32_of_fullname + familyname +stylename
|
|
|
|
|
std::wstring MakeUniqueFontName(const std::wstring strFullName, const std::wstring strFamilyName, const std::wstring strStyleName)
|
|
|
|
|
{
|
|
|
|
|
return strFullName + to_wstring(crc32::getCrc32(0, strFullName.c_str(), strFullName.length() * sizeof(WCHAR))) + strFamilyName + strStyleName;
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-08 13:45:52 +08:00
|
|
|
|
#ifndef Assert
|
|
|
|
|
#include <crtdbg.h>
|
|
|
|
|
#define Assert _ASSERTE
|
|
|
|
|
#endif //!Assert
|
|
|
|
|
|
|
|
|
|
#include "array.h"
|
|
|
|
|
#include <strsafe.h>
|
|
|
|
|
#include <shlwapi.h>
|
|
|
|
|
#include "dll.h"
|
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//kernel32専用GetProcAddressモドキ
|
2016-09-08 13:45:52 +08:00
|
|
|
|
FARPROC K32GetProcAddress(LPCSTR lpProcName)
|
|
|
|
|
{
|
|
|
|
|
#ifndef _WIN64
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//序数渡しには対応しない
|
2016-09-08 13:45:52 +08:00
|
|
|
|
Assert(!IS_INTRESOURCE(lpProcName));
|
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//kernel32のベースアドレス取得
|
2016-09-08 13:45:52 +08:00
|
|
|
|
LPBYTE pBase = (LPBYTE)GetModuleHandleA("kernel32.dll");
|
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//この辺は100%成功するはずなのでエラーチェックしない
|
2016-09-08 13:45:52 +08:00
|
|
|
|
PIMAGE_DOS_HEADER pdosh = (PIMAGE_DOS_HEADER)pBase;
|
|
|
|
|
Assert(pdosh->e_magic == IMAGE_DOS_SIGNATURE);
|
|
|
|
|
PIMAGE_NT_HEADERS pnth = (PIMAGE_NT_HEADERS)(pBase + pdosh->e_lfanew);
|
|
|
|
|
Assert(pnth->Signature == IMAGE_NT_SIGNATURE);
|
|
|
|
|
|
|
|
|
|
const DWORD offs = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
|
|
|
|
const DWORD size = pnth->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
|
|
|
|
|
if (offs == 0 || size == 0) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PIMAGE_EXPORT_DIRECTORY pdir = (PIMAGE_EXPORT_DIRECTORY)(pBase + offs);
|
|
|
|
|
DWORD* pFunc = (DWORD*)(pBase + pdir->AddressOfFunctions);
|
|
|
|
|
WORD* pOrd = (WORD*)(pBase + pdir->AddressOfNameOrdinals);
|
|
|
|
|
DWORD* pName = (DWORD*)(pBase + pdir->AddressOfNames);
|
|
|
|
|
|
|
|
|
|
for(DWORD i=0; i<pdir->NumberOfFunctions; i++) {
|
|
|
|
|
for(DWORD j=0; j<pdir->NumberOfNames; j++) {
|
|
|
|
|
if(pOrd[j] != i)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if(strcmp((LPCSTR)pBase + pName[j], lpProcName) != 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
return (FARPROC)(pBase + pFunc[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
#else
|
|
|
|
|
Assert(!IS_INTRESOURCE(lpProcName));
|
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//kernel32のベースアドレス取得
|
2016-09-08 13:45:52 +08:00
|
|
|
|
WCHAR sysdir[MAX_PATH];
|
|
|
|
|
GetWindowsDirectory(sysdir, MAX_PATH);
|
2020-12-06 17:00:05 +08:00
|
|
|
|
if (GetModuleHandle(_T("kernelbase.dll"))) //查看自己是否加载了Kernelbase.dll文件,存在则说明是win7系统
|
2016-09-08 13:45:52 +08:00
|
|
|
|
wcscat(sysdir, L"\\SysWow64\\kernelbase.dll");
|
|
|
|
|
else
|
2020-12-06 18:38:08 +08:00
|
|
|
|
wcscat(sysdir, L"\\SysWow64\\kernel32.dll"); //不存在就是vista
|
2016-09-08 13:45:52 +08:00
|
|
|
|
HANDLE hFile = CreateFile(sysdir, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
|
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
|
|
|
return NULL;
|
|
|
|
|
DWORD dwSize = GetFileSize(hFile, NULL);
|
2020-12-06 17:00:05 +08:00
|
|
|
|
BYTE* pMem = new BYTE[dwSize]; //分配内存
|
|
|
|
|
ReadFile(hFile, pMem, dwSize, &dwSize, NULL);//读取文件
|
2016-09-08 13:45:52 +08:00
|
|
|
|
CloseHandle(hFile);
|
|
|
|
|
|
|
|
|
|
CMemLoadDll MemDll;
|
|
|
|
|
MemDll.MemLoadLibrary(pMem, dwSize, false, false);
|
|
|
|
|
delete[] pMem;
|
2020-12-06 18:38:08 +08:00
|
|
|
|
return FARPROC((DWORD_PTR)MemDll.MemGetProcAddress(lpProcName)-MemDll.GetImageBase()); //返回偏移值
|
2016-09-08 13:45:52 +08:00
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-17 09:07:13 +08:00
|
|
|
|
typedef struct _UNICODE_STRING64 {
|
|
|
|
|
USHORT Length;
|
|
|
|
|
USHORT MaximumLength;
|
|
|
|
|
DWORD64 Buffer;
|
|
|
|
|
} UNICODE_STRING64, *PUNICODE_STRING64;
|
2016-09-08 13:45:52 +08:00
|
|
|
|
|
|
|
|
|
#include <pshpack1.h>
|
|
|
|
|
class opcode_data {
|
|
|
|
|
private:
|
|
|
|
|
BYTE code[0x100];
|
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//注: dllpathをWORD境界にしないと場合によっては正常に動作しない
|
2016-09-08 13:45:52 +08:00
|
|
|
|
WCHAR dllpath[MAX_PATH];
|
2016-11-17 09:07:13 +08:00
|
|
|
|
UNICODE_STRING64 uniDllPath;
|
|
|
|
|
DWORD64 hDumyDllHandle;
|
2016-09-08 13:45:52 +08:00
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
opcode_data()
|
|
|
|
|
{
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//int 03hで埋める
|
2016-09-08 13:45:52 +08:00
|
|
|
|
FillMemory(this, sizeof(*this), 0xcc);
|
|
|
|
|
}
|
2020-12-06 18:38:08 +08:00
|
|
|
|
bool initWow64(LPDWORD remoteaddr, LONG orgEIP) //Wow64初始化
|
2016-09-08 13:45:52 +08:00
|
|
|
|
{
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//WORD境界チェック
|
2016-09-08 13:45:52 +08:00
|
|
|
|
C_ASSERT((offsetof(opcode_data, dllpath) & 1) == 0);
|
|
|
|
|
|
|
|
|
|
register BYTE* p = code;
|
|
|
|
|
|
|
|
|
|
#define emit_(t,x) *(t* UNALIGNED)p = (t)(x); p += sizeof(t)
|
|
|
|
|
#define emit_db(b) emit_(BYTE, b)
|
|
|
|
|
#define emit_dw(w) emit_(WORD, w)
|
|
|
|
|
#define emit_dd(d) emit_(DWORD, d)
|
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//なぜかGetProcAddressでLoadLibraryWのアドレスが正しく取れないことがあるので
|
|
|
|
|
//kernel32のヘッダから自前で取得する
|
2016-09-08 13:45:52 +08:00
|
|
|
|
FARPROC pfn = K32GetProcAddress("LoadLibraryExW");
|
|
|
|
|
if(!pfn)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
emit_db(0x60); //pushad
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
mov eax,fs:[0x30]
|
|
|
|
|
mov eax,[eax+0x0c]
|
|
|
|
|
mov esi,[eax+0x1c]
|
|
|
|
|
lodsd
|
2020-12-06 18:38:08 +08:00
|
|
|
|
move ax,[eax+$08]//这个时候eax中保存的就是k32的基址了
|
|
|
|
|
在win7获得的是KernelBase.dll的地址
|
2016-09-08 13:45:52 +08:00
|
|
|
|
*/
|
|
|
|
|
emit_db(0x64);
|
|
|
|
|
emit_db(0xA1);
|
|
|
|
|
emit_db(0x30);
|
|
|
|
|
emit_db(00);
|
|
|
|
|
emit_db(00);
|
|
|
|
|
emit_db(00);
|
|
|
|
|
emit_db(0x8B);
|
|
|
|
|
emit_db(0x40);
|
|
|
|
|
emit_db(0x0C);
|
|
|
|
|
emit_db(0x8B);
|
|
|
|
|
emit_db(0x70);
|
|
|
|
|
emit_db(0x1C);
|
|
|
|
|
emit_db(0xAD);
|
|
|
|
|
emit_db(0x8B);
|
|
|
|
|
emit_db(0x40);
|
|
|
|
|
emit_db(0x08); //use assemble to fetch kernel base
|
|
|
|
|
|
|
|
|
|
emit_dw(0x006A); //push 0
|
|
|
|
|
emit_dw(0x006A); //push 0
|
|
|
|
|
emit_db(0x68); //push dllpath
|
|
|
|
|
emit_dd((LONG)remoteaddr + offsetof(opcode_data, dllpath));
|
|
|
|
|
emit_db(0x05); //add eax, LoadLibraryExW offset
|
|
|
|
|
emit_dd(pfn);
|
|
|
|
|
emit_dw(0xD0FF); //call eax
|
|
|
|
|
|
|
|
|
|
emit_db(0x61); //popad
|
|
|
|
|
emit_db(0xE9); //jmp original_EIP
|
|
|
|
|
emit_dd(orgEIP - (LONG)remoteaddr - (p - code) - sizeof(LONG));
|
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
// gdi++.dllのパス
|
2016-12-20 16:59:09 +08:00
|
|
|
|
int nSize = GetModuleFileNameW(GetDLLInstance(), dllpath, MAX_PATH);
|
|
|
|
|
if (nSize) {
|
|
|
|
|
ChangeFileName(dllpath, nSize, L"MTBootStrap.dll");
|
|
|
|
|
}
|
|
|
|
|
return !!nSize;
|
2016-09-08 13:45:52 +08:00
|
|
|
|
}
|
2020-12-06 18:38:08 +08:00
|
|
|
|
bool init32(LPDWORD remoteaddr, LONG orgEIP) //32位程序初始化
|
2016-09-08 13:45:52 +08:00
|
|
|
|
{
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//WORD境界チェック
|
2016-09-08 13:45:52 +08:00
|
|
|
|
C_ASSERT((offsetof(opcode_data, dllpath) & 1) == 0);
|
|
|
|
|
|
|
|
|
|
register BYTE* p = code;
|
|
|
|
|
|
|
|
|
|
#define emit_(t,x) *(t* UNALIGNED)p = (t)(x); p += sizeof(t)
|
|
|
|
|
#define emit_db(b) emit_(BYTE, b)
|
|
|
|
|
#define emit_dw(w) emit_(WORD, w)
|
|
|
|
|
#define emit_dd(d) emit_(DWORD, d)
|
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//なぜかGetProcAddressでLoadLibraryWのアドレスが正しく取れないことがあるので
|
|
|
|
|
//kernel32のヘッダから自前で取得する
|
2016-09-08 13:45:52 +08:00
|
|
|
|
FARPROC pfn = K32GetProcAddress("LoadLibraryW");
|
|
|
|
|
if(!pfn)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
emit_db(0x60); //pushad
|
|
|
|
|
#if _DEBUG
|
|
|
|
|
emit_dw(0xC033); //xor eax, eax
|
|
|
|
|
emit_db(0x50); //push eax
|
|
|
|
|
emit_db(0x50); //push eax
|
|
|
|
|
emit_db(0x68); //push dllpath
|
|
|
|
|
emit_dd((LONG)remoteaddr + offsetof(opcode_data, dllpath));
|
|
|
|
|
emit_db(0x50); //push eax
|
|
|
|
|
emit_db(0xB8); //mov eax, MessageBoxW
|
|
|
|
|
emit_dd((LONG)MessageBoxW);
|
|
|
|
|
emit_dw(0xD0FF); //call eax
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
emit_db(0x68); //push dllpath
|
|
|
|
|
emit_dd((LONG)remoteaddr + offsetof(opcode_data, dllpath));
|
|
|
|
|
emit_db(0xB8); //mov eax, LoadLibraryW
|
|
|
|
|
emit_dd(pfn);
|
|
|
|
|
emit_dw(0xD0FF); //call eax
|
|
|
|
|
|
|
|
|
|
emit_db(0x61); //popad
|
|
|
|
|
emit_db(0xE9); //jmp original_EIP
|
|
|
|
|
emit_dd(orgEIP - (LONG)remoteaddr - (p - code) - sizeof(LONG));
|
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
// gdi++.dllのパス
|
2016-12-20 16:59:09 +08:00
|
|
|
|
int nSize = GetModuleFileNameW(GetDLLInstance(), dllpath, MAX_PATH);
|
|
|
|
|
if (nSize) {
|
|
|
|
|
ChangeFileName(dllpath, nSize, L"MTBootStrap.dll");
|
|
|
|
|
}
|
|
|
|
|
return !!nSize;
|
2016-09-08 13:45:52 +08:00
|
|
|
|
}
|
2016-09-23 10:13:41 +08:00
|
|
|
|
bool init64From32(DWORD64 remoteaddr, DWORD64 orgEIP)
|
2016-09-08 13:45:52 +08:00
|
|
|
|
{
|
|
|
|
|
C_ASSERT((offsetof(opcode_data, dllpath) & 1) == 0);
|
|
|
|
|
|
|
|
|
|
register BYTE* p = code;
|
|
|
|
|
|
|
|
|
|
#define emit_(t,x) *(t* UNALIGNED)p = (t)(x); p += sizeof(t)
|
|
|
|
|
#define emit_db(b) emit_(BYTE, b)
|
|
|
|
|
#define emit_dw(w) emit_(WORD, w)
|
|
|
|
|
#define emit_dd(d) emit_(DWORD, d)
|
|
|
|
|
#define emit_ddp(dp) emit_(DWORD64, dp)
|
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//なぜかGetProcAddressでLoadLibraryWのアドレスが正しく取れないことがあるので
|
|
|
|
|
//kernel32のヘッダから自前で取得する
|
2016-09-08 13:45:52 +08:00
|
|
|
|
WCHAR x64Addr[30] = { 0 };
|
|
|
|
|
if (!GetEnvironmentVariable(L"MACTYPE_X64ADDR", x64Addr, 29)) return false;
|
|
|
|
|
DWORD64 pfn = wcstoull(x64Addr, NULL, 10);
|
|
|
|
|
//DWORD64 pfn = getenv("MACTYPE_X64ADDR"); //GetProcAddress64(GetModuleHandle64(L"kernelbase.dll"), "LoadLibraryW");
|
2016-09-09 12:37:10 +08:00
|
|
|
|
if (!pfn)
|
2016-09-08 13:45:52 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
emit_db(0x50); //push rax
|
|
|
|
|
emit_db(0x51); //push rcx
|
|
|
|
|
emit_db(0x52); //push rdx
|
|
|
|
|
emit_db(0x53); //push rbx
|
|
|
|
|
emit_dd(0x28ec8348); //sub rsp,28h
|
|
|
|
|
emit_db(0x48); //mov rcx, dllpath
|
|
|
|
|
emit_db(0xB9);
|
|
|
|
|
emit_ddp((DWORD64)remoteaddr + offsetof(opcode_data, dllpath));
|
|
|
|
|
emit_db(0x48); //mov rsi, LoadLibraryW
|
|
|
|
|
emit_db(0xBE);
|
|
|
|
|
emit_ddp(pfn);
|
|
|
|
|
//emit_db(0x48);
|
|
|
|
|
emit_db(0xFF); //call rdi
|
|
|
|
|
emit_db(0xD6);
|
|
|
|
|
|
|
|
|
|
emit_dd(0x28c48348); //add rsp,28h
|
|
|
|
|
emit_db(0x5B);
|
|
|
|
|
emit_db(0x5A);
|
|
|
|
|
emit_db(0x59);
|
|
|
|
|
emit_db(0x58); //popad
|
|
|
|
|
|
|
|
|
|
emit_db(0x48); //mov rdi, orgRip
|
|
|
|
|
emit_db(0xBE);
|
|
|
|
|
emit_ddp(orgEIP);
|
|
|
|
|
emit_db(0xFF); //jmp rdi
|
|
|
|
|
emit_db(0xE6);
|
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
// gdi++.dllのパス
|
2016-09-08 13:45:52 +08:00
|
|
|
|
|
2016-12-20 16:59:09 +08:00
|
|
|
|
int nSize = GetModuleFileNameW(GetDLLInstance(), dllpath, MAX_PATH);
|
|
|
|
|
if (nSize) {
|
|
|
|
|
ChangeFileName(dllpath, nSize, L"MTBootStrap64.dll");
|
|
|
|
|
}
|
|
|
|
|
return !!nSize;
|
2016-09-09 12:37:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
2016-09-23 10:13:41 +08:00
|
|
|
|
bool init64From32(DWORD64 remoteaddr, DWORD64 orgEIP, DWORD dwLoaderOffset)
|
2016-09-09 12:37:10 +08:00
|
|
|
|
{
|
|
|
|
|
C_ASSERT((offsetof(opcode_data, dllpath) & 1) == 0);
|
|
|
|
|
|
2016-12-20 16:59:09 +08:00
|
|
|
|
int nSize = GetModuleFileNameW(GetDLLInstance(), dllpath, MAX_PATH);
|
|
|
|
|
if (nSize) {
|
|
|
|
|
ChangeFileName(dllpath, nSize, L"MTBootStrap64.dll");
|
|
|
|
|
}
|
|
|
|
|
if (!nSize)
|
2016-11-17 09:07:13 +08:00
|
|
|
|
return false;
|
|
|
|
|
uniDllPath.Length = wcslen(dllpath)*sizeof(WCHAR);
|
|
|
|
|
uniDllPath.MaximumLength = uniDllPath.Length+2;
|
|
|
|
|
uniDllPath.Buffer = remoteaddr + (DWORD64)offsetof(opcode_data, dllpath); //prepare PUNICODE_STRING for remote process
|
2016-09-09 12:37:10 +08:00
|
|
|
|
register BYTE* p = code;
|
|
|
|
|
|
|
|
|
|
#define emit_(t,x) *(t* UNALIGNED)p = (t)(x); p += sizeof(t)
|
|
|
|
|
#define emit_db(b) emit_(BYTE, b)
|
|
|
|
|
#define emit_dw(w) emit_(WORD, w)
|
|
|
|
|
#define emit_dd(d) emit_(DWORD, d)
|
|
|
|
|
#define emit_ddp(dp) emit_(DWORD64, dp)
|
|
|
|
|
|
2016-11-17 09:07:13 +08:00
|
|
|
|
//get ntdll.dll imagebase
|
2016-09-09 12:37:10 +08:00
|
|
|
|
//credit to http://www.52pojie.cn/thread-162625-1-1.html
|
|
|
|
|
/*asm:
|
|
|
|
|
mov rsi, [gs:60h] ; peb from teb
|
|
|
|
|
mov rsi, [rsi+18h] ;_peb_ldr_data from peb
|
2016-11-17 09:07:13 +08:00
|
|
|
|
mov rsi, [rsi+30h] ;InInitializationOrderModuleList.Flink, ntdll.dll
|
|
|
|
|
;mov rsi, [rsi] ;kernelbase.dll
|
2016-09-09 12:37:10 +08:00
|
|
|
|
;mov rsi, [rsi] ;kernel32.dll (not used for win7+)
|
|
|
|
|
mov rsi, [rsi+10h]
|
|
|
|
|
*/
|
2016-11-17 09:07:13 +08:00
|
|
|
|
|
|
|
|
|
// emit_db(0xEB);
|
|
|
|
|
// emit_db(0xFE); // make a dead loop
|
2016-09-09 12:37:10 +08:00
|
|
|
|
emit_db(0x65);
|
|
|
|
|
emit_db(0x48);
|
|
|
|
|
emit_db(0x8B);
|
|
|
|
|
emit_db(0x34);
|
|
|
|
|
emit_db(0x25);
|
|
|
|
|
emit_db(0x60);
|
|
|
|
|
emit_db(0x00);
|
|
|
|
|
emit_db(0x00);
|
|
|
|
|
emit_db(0x00);
|
|
|
|
|
emit_db(0x48);
|
|
|
|
|
emit_db(0x8B);
|
|
|
|
|
emit_db(0x76);
|
|
|
|
|
emit_db(0x18);
|
|
|
|
|
emit_db(0x48);
|
|
|
|
|
emit_db(0x8B);
|
|
|
|
|
emit_db(0x76);
|
|
|
|
|
emit_db(0x30);
|
2016-11-17 09:07:13 +08:00
|
|
|
|
// emit_db(0x48);
|
|
|
|
|
// emit_db(0x8B);
|
|
|
|
|
// emit_db(0x36);
|
2016-09-09 12:37:10 +08:00
|
|
|
|
emit_db(0x48);
|
|
|
|
|
emit_db(0x8B);
|
|
|
|
|
emit_db(0x76);
|
|
|
|
|
emit_db(0x10);
|
2016-11-17 09:07:13 +08:00
|
|
|
|
//rsi = ntdll.dll baseaddress
|
2016-09-08 13:45:52 +08:00
|
|
|
|
|
2016-09-09 12:37:10 +08:00
|
|
|
|
emit_db(0x50); //push rax
|
|
|
|
|
emit_db(0x51); //push rcx
|
|
|
|
|
emit_db(0x52); //push rdx
|
|
|
|
|
emit_db(0x53); //push rbx
|
|
|
|
|
emit_dd(0x28ec8348); //sub rsp,28h
|
2016-11-17 09:07:13 +08:00
|
|
|
|
emit_db(0x48);
|
2016-09-09 12:37:10 +08:00
|
|
|
|
emit_db(0x31);
|
2016-11-17 09:07:13 +08:00
|
|
|
|
emit_db(0xc9); //xor rcx, rcx
|
|
|
|
|
emit_db(0x48);
|
2016-09-09 12:37:10 +08:00
|
|
|
|
emit_db(0x31);
|
2016-11-17 09:07:13 +08:00
|
|
|
|
emit_db(0xd2); //xor rdx, rdx
|
|
|
|
|
emit_db(0x49);
|
|
|
|
|
emit_db(0xB8);
|
|
|
|
|
emit_ddp((DWORD64)remoteaddr + offsetof(opcode_data, uniDllPath));//mov r8, uniDllPath
|
|
|
|
|
emit_db(0x49);
|
|
|
|
|
emit_db(0xB9);
|
|
|
|
|
emit_ddp((DWORD64)remoteaddr + offsetof(opcode_data, hDumyDllHandle));//mov r9, hDumyDllHandle
|
|
|
|
|
//emit_db(0x48); //mov rsi, LdrLoadDll
|
2016-09-09 12:37:10 +08:00
|
|
|
|
//emit_db(0xBE);
|
|
|
|
|
emit_db(0x48);
|
|
|
|
|
emit_db(0x81);
|
2016-11-17 09:07:13 +08:00
|
|
|
|
emit_db(0xC6); //add rsi, offset LdrLoadDll
|
2016-09-09 12:37:10 +08:00
|
|
|
|
emit_dd(dwLoaderOffset);
|
|
|
|
|
//emit_db(0x48);
|
|
|
|
|
emit_db(0xFF); //call rsi
|
|
|
|
|
emit_db(0xD6);
|
|
|
|
|
|
|
|
|
|
emit_dd(0x28c48348); //add rsp,28h
|
|
|
|
|
emit_db(0x5B);
|
|
|
|
|
emit_db(0x5A);
|
|
|
|
|
emit_db(0x59);
|
|
|
|
|
emit_db(0x58); //popad
|
|
|
|
|
|
|
|
|
|
emit_db(0x48); //mov rdi, orgRip
|
|
|
|
|
emit_db(0xBE);
|
|
|
|
|
emit_ddp(orgEIP);
|
|
|
|
|
emit_db(0xFF); //jmp rdi
|
|
|
|
|
emit_db(0xE6);
|
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
// gdi++.dllのパス
|
2016-09-09 12:37:10 +08:00
|
|
|
|
|
2016-12-20 16:59:09 +08:00
|
|
|
|
return !!nSize;
|
2016-09-08 13:45:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool init(DWORD_PTR* remoteaddr, DWORD_PTR orgEIP)
|
|
|
|
|
{
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//WORD境界チェック
|
2016-09-08 13:45:52 +08:00
|
|
|
|
C_ASSERT((offsetof(opcode_data, dllpath) & 1) == 0);
|
|
|
|
|
|
|
|
|
|
register BYTE* p = code;
|
|
|
|
|
#undef emit_ddp
|
|
|
|
|
|
|
|
|
|
#define emit_(t,x) *(t* UNALIGNED)p = (t)(x); p += sizeof(t)
|
|
|
|
|
#define emit_db(b) emit_(BYTE, b)
|
|
|
|
|
#define emit_dw(w) emit_(WORD, w)
|
|
|
|
|
#define emit_dd(d) emit_(DWORD, d)
|
|
|
|
|
#define emit_ddp(dp) emit_(DWORD_PTR, dp)
|
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//なぜかGetProcAddressでLoadLibraryWのアドレスが正しく取れないことがあるので
|
|
|
|
|
//kernel32のヘッダから自前で取得する
|
2016-09-08 13:45:52 +08:00
|
|
|
|
FARPROC pfn = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
|
|
|
|
|
//if(!pfn)
|
|
|
|
|
// return false;
|
2016-09-27 12:53:23 +08:00
|
|
|
|
//emit_db(0xEB);
|
|
|
|
|
//emit_db(0xFE); // make a dead loop
|
2016-09-08 13:45:52 +08:00
|
|
|
|
|
|
|
|
|
emit_db(0x50); //push rax
|
|
|
|
|
emit_db(0x51); //push rcx
|
|
|
|
|
emit_db(0x52); //push rdx
|
|
|
|
|
emit_db(0x53); //push rbx
|
2016-12-20 16:59:09 +08:00
|
|
|
|
/*
|
2016-09-27 12:53:23 +08:00
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
emit_dd(0x28ec8348);
|
|
|
|
|
emit_db(0x48);
|
|
|
|
|
emit_db(0x31);
|
|
|
|
|
emit_db(0xD0); //xor rax,rax
|
|
|
|
|
emit_db(0x48);
|
|
|
|
|
emit_db(0x31);
|
|
|
|
|
emit_db(0xC9); //xor rcx,rcx
|
|
|
|
|
emit_db(0x48);
|
|
|
|
|
emit_db(0x31);
|
|
|
|
|
emit_db(0xD2); //xor rdx,rdx
|
|
|
|
|
emit_db(0x45);
|
|
|
|
|
emit_db(0x31);
|
|
|
|
|
emit_db(0xC0); //xor r8d,r8d
|
|
|
|
|
emit_db(0x45);
|
|
|
|
|
emit_db(0x31);
|
|
|
|
|
emit_db(0xC9); //xor r9d,r9d
|
|
|
|
|
|
|
|
|
|
emit_db(0x48); //mov rsi, MessageBoxW
|
|
|
|
|
emit_db(0xBE);
|
|
|
|
|
emit_ddp((DWORD_PTR)MessageBoxW);
|
|
|
|
|
emit_db(0xFF);
|
|
|
|
|
emit_db(0xD6);
|
|
|
|
|
emit_dd(0x28c48348);
|
2016-12-20 16:59:09 +08:00
|
|
|
|
#endif*/
|
2016-09-27 12:53:23 +08:00
|
|
|
|
/*
|
|
|
|
|
//Debug function2, Sleep for 10sec.
|
|
|
|
|
emit_dd(0x28ec8348);
|
|
|
|
|
emit_db(0x48); //mov rsi, MessageBoxW
|
|
|
|
|
emit_db(0xBE);
|
|
|
|
|
emit_ddp((DWORD_PTR)Sleep);
|
|
|
|
|
emit_db(0x48); emit_db(0xc7); emit_db(0xc1); emit_db(0x10); emit_db(0x27); emit_db(0x00); emit_db(0x00);
|
|
|
|
|
emit_db(0xFF);
|
|
|
|
|
emit_db(0xD6);
|
|
|
|
|
emit_dd(0x28c48348);
|
|
|
|
|
*/
|
2016-09-08 13:45:52 +08:00
|
|
|
|
emit_dd(0x28ec8348); //sub rsp,28h
|
|
|
|
|
emit_db(0x48); //mov rcx, dllpath
|
|
|
|
|
emit_db(0xB9);
|
|
|
|
|
emit_ddp((DWORD_PTR)remoteaddr + offsetof(opcode_data, dllpath));
|
|
|
|
|
emit_db(0x48); //mov rsi, LoadLibraryW
|
|
|
|
|
emit_db(0xBE);
|
|
|
|
|
emit_ddp(pfn);
|
|
|
|
|
//emit_db(0x48);
|
|
|
|
|
emit_db(0xFF); //call rdi
|
|
|
|
|
emit_db(0xD6);
|
|
|
|
|
|
|
|
|
|
emit_dd(0x28c48348); //add rsp,28h
|
|
|
|
|
emit_db(0x5B);
|
|
|
|
|
emit_db(0x5A);
|
|
|
|
|
emit_db(0x59);
|
|
|
|
|
emit_db(0x58); //popad
|
|
|
|
|
|
|
|
|
|
emit_db(0x48); //mov rdi, orgRip
|
|
|
|
|
emit_db(0xBE);
|
|
|
|
|
emit_ddp(orgEIP);
|
|
|
|
|
emit_db(0xFF); //jmp rdi
|
|
|
|
|
emit_db(0xE6);
|
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
// gdi++.dllのパス
|
2016-12-20 16:59:09 +08:00
|
|
|
|
int nSize = GetModuleFileNameW(GetDLLInstance(), dllpath, MAX_PATH);
|
|
|
|
|
if (nSize) {
|
|
|
|
|
ChangeFileName(dllpath, nSize, L"MTBootStrap64.dll");
|
|
|
|
|
}
|
|
|
|
|
return !!nSize;
|
2016-09-08 13:45:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
#include <poppack.h>
|
|
|
|
|
|
2020-12-06 18:38:08 +08:00
|
|
|
|
// 安全的取得真实系统信息
|
2016-09-08 13:45:52 +08:00
|
|
|
|
VOID SafeGetNativeSystemInfo(__out LPSYSTEM_INFO lpSystemInfo)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == lpSystemInfo) return;
|
|
|
|
|
typedef VOID(WINAPI *LPFN_GetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo);
|
|
|
|
|
LPFN_GetNativeSystemInfo fnGetNativeSystemInfo = (LPFN_GetNativeSystemInfo)GetProcAddress(GetModuleHandle(_T("kernel32")), "GetNativeSystemInfo");;
|
|
|
|
|
if (NULL != fnGetNativeSystemInfo)
|
|
|
|
|
{
|
|
|
|
|
fnGetNativeSystemInfo(lpSystemInfo);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
GetSystemInfo(lpSystemInfo);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-06 17:00:05 +08:00
|
|
|
|
// 获取操作系统位数
|
2016-09-08 13:45:52 +08:00
|
|
|
|
int GetSystemBits()
|
|
|
|
|
{
|
|
|
|
|
SYSTEM_INFO si;
|
|
|
|
|
SafeGetNativeSystemInfo(&si);
|
|
|
|
|
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||
|
|
|
|
|
si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
|
|
|
|
|
{
|
|
|
|
|
return 64;
|
|
|
|
|
}
|
|
|
|
|
return 32;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool bIsOS64 = GetSystemBits() == 64; // check if running in a x64 system.
|
|
|
|
|
|
|
|
|
|
#ifdef _M_IX86
|
2020-12-06 18:38:08 +08:00
|
|
|
|
// 止めているプロセスにLoadLibraryするコードを注入
|
2016-09-08 13:45:52 +08:00
|
|
|
|
EXTERN_C BOOL WINAPI GdippInjectDLL(const PROCESS_INFORMATION* ppi)
|
|
|
|
|
{
|
|
|
|
|
BOOL bIsX64Proc = false;
|
|
|
|
|
if (bIsOS64 && IsWow64Process(ppi->hProcess, &bIsX64Proc) && !bIsX64Proc)
|
|
|
|
|
{
|
|
|
|
|
//x86 process launches a x64 process
|
|
|
|
|
_CONTEXT64 ctx = { 0 };
|
|
|
|
|
ctx.ContextFlags = CONTEXT_CONTROL;
|
|
|
|
|
if (!GetThreadContext64(ppi->hThread, &ctx))
|
|
|
|
|
return false;
|
2016-09-09 12:37:10 +08:00
|
|
|
|
static bool bTryLoadDll64 = false;
|
|
|
|
|
static DWORD dwLoaderOffset = 0;
|
|
|
|
|
if (!bTryLoadDll64) {
|
|
|
|
|
bTryLoadDll64 = true;
|
|
|
|
|
GetEnvironmentVariable(L"MACTYPE_X64ADDR", NULL, 0);
|
|
|
|
|
if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
|
2016-11-17 09:07:13 +08:00
|
|
|
|
DWORD64 hNtdll = 0;
|
|
|
|
|
hNtdll = GetModuleHandle64(L"ntdll.dll");
|
|
|
|
|
if (hNtdll) {
|
|
|
|
|
DWORD64 pfnLdrAddr = GetProcAddress64(hNtdll, "LdrLoadDll");
|
2016-09-09 12:37:10 +08:00
|
|
|
|
if (pfnLdrAddr) {
|
2016-11-17 09:07:13 +08:00
|
|
|
|
dwLoaderOffset = (DWORD)(pfnLdrAddr - hNtdll);
|
2016-09-09 12:37:10 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-08 13:45:52 +08:00
|
|
|
|
opcode_data local;
|
|
|
|
|
DWORD64 remote = VirtualAllocEx64(ppi->hProcess, NULL, sizeof(opcode_data), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
|
|
|
|
if (!remote)
|
|
|
|
|
return false;
|
2016-09-23 10:13:41 +08:00
|
|
|
|
bool basmIniter = dwLoaderOffset ? local.init64From32(remote, ctx.Rip, dwLoaderOffset) : local.init64From32(remote, ctx.Rip);
|
2016-09-09 12:37:10 +08:00
|
|
|
|
if (!basmIniter || !WriteProcessMemory64(ppi->hProcess, remote, &local, sizeof(opcode_data), NULL)) {
|
2016-09-08 13:45:52 +08:00
|
|
|
|
VirtualFreeEx64(ppi->hProcess, remote, 0, MEM_RELEASE);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//FlushInstructionCache64(ppi->hProcess, remote, sizeof(opcode_data));
|
|
|
|
|
//FARPROC a=(FARPROC)remote;
|
|
|
|
|
//a();
|
|
|
|
|
ctx.Rip = (DWORD64)remote;
|
|
|
|
|
return !!SetThreadContext64(ppi->hThread, &ctx);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
CONTEXT ctx = { 0 };
|
|
|
|
|
ctx.ContextFlags = CONTEXT_CONTROL;
|
|
|
|
|
if (!GetThreadContext(ppi->hThread, &ctx))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
opcode_data local;
|
|
|
|
|
opcode_data* remote = (opcode_data*)VirtualAllocEx(ppi->hProcess, NULL, sizeof(opcode_data), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
|
|
|
|
if (!remote)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!local.init32((LPDWORD)remote, ctx.Eip)
|
|
|
|
|
|| !WriteProcessMemory(ppi->hProcess, remote, &local, sizeof(opcode_data), NULL)) {
|
|
|
|
|
VirtualFreeEx(ppi->hProcess, remote, 0, MEM_RELEASE);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FlushInstructionCache(ppi->hProcess, remote, sizeof(opcode_data));
|
|
|
|
|
ctx.Eip = (DWORD)remote;
|
|
|
|
|
return !!SetThreadContext(ppi->hThread, &ctx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
EXTERN_C BOOL WINAPI GdippInjectDLL(const PROCESS_INFORMATION* ppi)
|
|
|
|
|
{
|
|
|
|
|
BOOL bWow64 = false;
|
|
|
|
|
IsWow64Process(ppi->hProcess, &bWow64);
|
|
|
|
|
if (bWow64)
|
|
|
|
|
{
|
|
|
|
|
WOW64_CONTEXT ctx = { 0 };
|
|
|
|
|
ctx.ContextFlags = CONTEXT_CONTROL;
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//CREATE_SUSPENDEDなので基本的に成功するはず
|
2016-09-08 13:45:52 +08:00
|
|
|
|
if(!Wow64GetThreadContext(ppi->hThread, &ctx))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
opcode_data local;
|
|
|
|
|
LPVOID remote = VirtualAllocEx(ppi->hProcess, NULL, sizeof(opcode_data), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
|
|
|
|
if(!remote)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if(!local.initWow64((LPDWORD)remote, ctx.Eip)
|
|
|
|
|
|| !WriteProcessMemory(ppi->hProcess, remote, &local, sizeof(opcode_data), NULL)) {
|
|
|
|
|
VirtualFreeEx(ppi->hProcess, remote, 0, MEM_RELEASE);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FlushInstructionCache(ppi->hProcess, remote, sizeof(opcode_data));
|
|
|
|
|
//FARPROC a=(FARPROC)remote;
|
|
|
|
|
//a();
|
|
|
|
|
ctx.Eip = (DWORD)remote;
|
|
|
|
|
return !!Wow64SetThreadContext(ppi->hThread, &ctx);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
CONTEXT ctx = { 0 };
|
|
|
|
|
ctx.ContextFlags = CONTEXT_CONTROL;
|
2020-12-06 18:38:08 +08:00
|
|
|
|
//CREATE_SUSPENDEDなので基本的に成功するはず
|
2016-09-08 13:45:52 +08:00
|
|
|
|
if(!GetThreadContext(ppi->hThread, &ctx))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
opcode_data local;
|
|
|
|
|
LPVOID remote = VirtualAllocEx(ppi->hProcess, NULL, sizeof(opcode_data), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
|
|
|
|
if(!remote)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if(!local.init((DWORD_PTR*)remote, ctx.Rip)
|
|
|
|
|
|| !WriteProcessMemory(ppi->hProcess, remote, &local, sizeof(opcode_data), NULL)) {
|
|
|
|
|
VirtualFreeEx(ppi->hProcess, remote, 0, MEM_RELEASE);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FlushInstructionCache(ppi->hProcess, remote, sizeof(opcode_data));
|
|
|
|
|
//FARPROC a=(FARPROC)remote;
|
|
|
|
|
//a();
|
|
|
|
|
ctx.Rip = (DWORD_PTR)remote;
|
|
|
|
|
return !!SetThreadContext(ppi->hThread, &ctx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
template <typename _TCHAR>
|
|
|
|
|
int strlendb(const _TCHAR* psz)
|
|
|
|
|
{
|
|
|
|
|
const _TCHAR* p = psz;
|
|
|
|
|
while (*p) {
|
|
|
|
|
for (; *p; p++);
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
return p - psz + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename _TCHAR>
|
|
|
|
|
_TCHAR* strdupdb(const _TCHAR* psz, int pad)
|
|
|
|
|
{
|
|
|
|
|
int len = strlendb(psz);
|
|
|
|
|
_TCHAR* p = (_TCHAR*)calloc(sizeof(_TCHAR), len + pad);
|
|
|
|
|
if(p) {
|
|
|
|
|
memcpy(p, psz, sizeof(_TCHAR) * len);
|
|
|
|
|
}
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool MultiSzToArray(LPWSTR p, CArray<LPWSTR>& arr)
|
|
|
|
|
{
|
|
|
|
|
for (; *p; ) {
|
|
|
|
|
LPWSTR cp = _wcsdup(p);
|
|
|
|
|
if(!cp || !arr.Add(cp)) {
|
|
|
|
|
free(cp);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
for (; *p; p++);
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LPWSTR ArrayToMultiSz(CArray<LPWSTR>& arr)
|
|
|
|
|
{
|
|
|
|
|
size_t cch = 1;
|
|
|
|
|
for (int i=0; i<arr.GetSize(); i++) {
|
|
|
|
|
cch += wcslen(arr[i]) + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LPWSTR pmsz = (LPWSTR)calloc(sizeof(WCHAR), cch);
|
|
|
|
|
if (!pmsz)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
LPWSTR p = pmsz;
|
|
|
|
|
for (int i=0; i<arr.GetSize(); i++) {
|
|
|
|
|
StringCchCopyExW(p, cch, arr[i], &p, &cch, STRSAFE_NO_TRUNCATION);
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
*p = 0;
|
|
|
|
|
return pmsz;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool AddPathEnv(CArray<LPWSTR>& arr, LPWSTR dir, int dirlen)
|
|
|
|
|
{
|
|
|
|
|
for (int i=0; i<arr.GetSize(); i++) {
|
|
|
|
|
LPWSTR env = arr[i];
|
|
|
|
|
if (_wcsnicmp(env, L"PATH=", 5)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LPWSTR p = env + 5;
|
|
|
|
|
LPWSTR pp = p;
|
|
|
|
|
for (; ;) {
|
|
|
|
|
for (; *p && *p != L';'; p++);
|
|
|
|
|
int len = p - pp;
|
|
|
|
|
if (len == dirlen && !_wcsnicmp(pp, dir, dirlen)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (!*p)
|
|
|
|
|
break;
|
|
|
|
|
pp = p + 1;
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t cch = wcslen(env) + MAX_PATH + 4;
|
|
|
|
|
env = (LPWSTR)realloc(env, sizeof(WCHAR) * cch);
|
|
|
|
|
if(env) {
|
|
|
|
|
StringCchCatW(env, cch, L";");
|
|
|
|
|
StringCchCatW(env, cch, dir);
|
|
|
|
|
arr[i] = env;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t cch = dirlen + sizeof("PATH=") + 1;
|
|
|
|
|
LPWSTR p = (LPWSTR)calloc(sizeof(WCHAR), cch);
|
|
|
|
|
if(p) {
|
|
|
|
|
StringCchCopyW(p, cch, L"PATH=");
|
|
|
|
|
StringCchCatW(p, cch, dir);
|
|
|
|
|
if (arr.Add(p)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
free(p);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool AddX64Env(CArray<LPWSTR>& arr)
|
|
|
|
|
{
|
2016-09-09 12:37:10 +08:00
|
|
|
|
FARPROC k32 = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW");
|
2016-09-08 13:45:52 +08:00
|
|
|
|
WCHAR szAddr[20] = { 0 };
|
|
|
|
|
_ui64tow((DWORD64)k32, szAddr, 10);
|
|
|
|
|
//wsprintf(szAddr, L"%Ld", (DWORD_PTR)k32);
|
|
|
|
|
size_t cch = wcslen(szAddr) + sizeof("MACTYPE_X64ADDR=") + 1;
|
|
|
|
|
LPWSTR p = (LPWSTR)calloc(sizeof(WCHAR), cch);
|
|
|
|
|
if (p) {
|
|
|
|
|
StringCchCopyW(p, cch, L"MACTYPE_X64ADDR=");
|
|
|
|
|
StringCchCatW(p, cch, szAddr);
|
|
|
|
|
if (arr.Add(p)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
free(p);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EXTERN_C LPWSTR WINAPI GdippEnvironment(DWORD& dwCreationFlags, LPVOID lpEnvironment)
|
|
|
|
|
{
|
2016-09-27 16:03:16 +08:00
|
|
|
|
#ifndef _WIN64
|
|
|
|
|
return NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
2016-09-08 13:45:52 +08:00
|
|
|
|
TCHAR dir[MAX_PATH];
|
|
|
|
|
int dirlen = GetModuleFileName(GetDLLInstance(), dir, MAX_PATH);
|
|
|
|
|
LPTSTR lpfilename=dir+dirlen;
|
|
|
|
|
while (lpfilename>dir && *lpfilename!=_T('\\') && *lpfilename!=_T('/')) --lpfilename;
|
|
|
|
|
*lpfilename = 0;
|
|
|
|
|
dirlen = wcslen(dir);
|
|
|
|
|
|
|
|
|
|
LPWSTR pEnvW = NULL;
|
|
|
|
|
if (lpEnvironment) {
|
|
|
|
|
if (dwCreationFlags & CREATE_UNICODE_ENVIRONMENT) {
|
|
|
|
|
pEnvW = strdupdb((LPCWSTR)lpEnvironment, MAX_PATH + 1);
|
|
|
|
|
} else {
|
|
|
|
|
int alen = strlendb((LPCSTR)lpEnvironment);
|
|
|
|
|
int wlen = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpEnvironment, alen, NULL, 0) + 1;
|
|
|
|
|
pEnvW = (LPWSTR)calloc(sizeof(WCHAR), wlen + MAX_PATH + 1);
|
|
|
|
|
if (pEnvW) {
|
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpEnvironment, alen, pEnvW, wlen);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
LPWSTR block = (LPWSTR)GetEnvironmentStringsW();
|
|
|
|
|
if (block) {
|
|
|
|
|
pEnvW = strdupdb(block, MAX_PATH + 1);
|
|
|
|
|
FreeEnvironmentStrings(block);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!pEnvW) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CArray<LPWSTR> envs;
|
|
|
|
|
bool ret = MultiSzToArray(pEnvW, envs);
|
|
|
|
|
free(pEnvW);
|
|
|
|
|
pEnvW = NULL;
|
|
|
|
|
|
2016-09-27 16:03:16 +08:00
|
|
|
|
/*if (ret) {
|
2016-09-08 13:45:52 +08:00
|
|
|
|
ret = AddPathEnv(envs, dir, dirlen);
|
2016-09-27 16:03:16 +08:00
|
|
|
|
}*/
|
2016-09-08 13:45:52 +08:00
|
|
|
|
#ifdef _WIN64
|
|
|
|
|
{
|
|
|
|
|
GetEnvironmentVariableW(L"MACTYPE_X64ADDR", NULL, 0);
|
|
|
|
|
if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
|
|
|
|
|
ret = AddX64Env(envs);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if (ret) {
|
|
|
|
|
pEnvW = ArrayToMultiSz(envs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i=0; i<envs.GetSize(); free(envs[i++]));
|
|
|
|
|
|
|
|
|
|
if (!pEnvW) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
{
|
|
|
|
|
LPWSTR tmp = strdupdb(pEnvW, 0);
|
|
|
|
|
LPWSTR tmpe = tmp + strlendb(tmp);
|
|
|
|
|
PathRemoveFileSpec(dir);
|
|
|
|
|
for (LPWSTR z=tmp; z<tmpe; z++)if(!*z)*z=L'\n';
|
|
|
|
|
StringCchCatW(dir,MAX_PATH,L"\\");
|
|
|
|
|
StringCchCatW(dir,MAX_PATH,L"gdienv.txt");
|
|
|
|
|
HANDLE hf = CreateFileW(dir,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
|
|
|
|
|
if(hf) {
|
|
|
|
|
DWORD cb;
|
|
|
|
|
WORD w = 0xfeff;
|
|
|
|
|
WriteFile(hf,&w, sizeof(WORD), &cb, 0);
|
|
|
|
|
WriteFile(hf,tmp, sizeof(WCHAR) * (tmpe - tmp), &cb, 0);
|
|
|
|
|
SetEndOfFile(hf);
|
|
|
|
|
CloseHandle(hf);
|
|
|
|
|
free(tmp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
|
|
|
|
|
return pEnvW;
|
|
|
|
|
}
|
2022-07-18 17:53:24 +08:00
|
|
|
|
|
|
|
|
|
void DebugOut(const WCHAR* szFormat, ...) {
|
|
|
|
|
#ifdef TRACE
|
|
|
|
|
va_list args;
|
|
|
|
|
va_start(args, szFormat);
|
|
|
|
|
WCHAR buffer[1024] = { 0 };
|
|
|
|
|
vswprintf(buffer, szFormat, args);
|
|
|
|
|
std::wstring fullmsg = L"[MTCore] " + std::wstring(buffer);
|
|
|
|
|
OutputDebugString(fullmsg.c_str());
|
|
|
|
|
#endif
|
|
|
|
|
}
|