📄 ntload.cpp
字号:
#define WIN32_LEAN_AND_MEAN
#define UNICODE
#ifdef UNICODE
#define _UNICODE
#endif
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
//#define AH_STATIC_LINKING
#include <ApiHooks.h>
//#define PW_STATIC_LINKING
#include <PrcWorks.h>
#include <ntsecapi.h>
#include <MakeWin32.h>
typedef LONG (WINAPI *TLDLL)(LPVOID, DWORD, PUNICODE_STRING, PHANDLE);
typedef LONG (WINAPI *TNTPV)(LONG, PULONG*, PULONG, ULONG, PULONG);
typedef struct _NTLOAD {
WCHAR DllNameW[MAX_PATH];
UNICODE_STRING DllName;
TLDLL LdrLoadDll;
TNTPV NtProtectVirtualMemory;
WORD SubSystem;
} NTLOAD, *PNTLOAD;
HANDLE WINAPI NtLoadRC(PNTLOAD pNtLoad) {
WORD *SubSysAddr, SubSys;
ULONG *ntpvSubSysAddr, RegionSize = sizeof(SubSys), ntpvRegionSize = RegionSize, OldProt = 0;
_asm {
mov edx, fs:[0x30]
mov eax, [edx+8]
mov ecx, [eax+0x3c]
lea eax, [ecx+eax+0x5c]
mov SubSysAddr, eax
mov cx, word ptr [eax]
mov SubSys, cx
}
if(SubSys == 1) { //native
ntpvSubSysAddr = (PULONG)SubSysAddr;
if(pNtLoad->NtProtectVirtualMemory(-1, &ntpvSubSysAddr, &ntpvRegionSize, PAGE_READWRITE, &OldProt)>=0)
*SubSysAddr = pNtLoad->SubSystem;
}
HANDLE hDll = NULL;
if(pNtLoad->LdrLoadDll(NULL, 0, &pNtLoad->DllName, &hDll)<0)
if(OldProt)
*SubSysAddr = SubSys;
if(OldProt)
pNtLoad->NtProtectVirtualMemory(-1, &ntpvSubSysAddr, &ntpvRegionSize, OldProt, &OldProt);
return(hDll);
}
int _tmain(int argc, TCHAR** argv) {
if((int)GetVersion()<0)
_tprintf(_T("NtLoad works in Windows NT only!"));
else
if(argc < 3)
_tprintf(_T("Usage: NtLoad <ProcessName> <ModuleName> [C]onsole"));
else {
HINSTANCE hntdll;
DWORD WasEn;
typedef LONG (WINAPI *TRAP)(DWORD, BOOL, DWORD, DWORD*);
TRAP RAP;
if(hntdll = GetModuleHandle(_T("ntdll.dll")))
if(RAP = (TRAP)GetProcAddress(hntdll, "RtlAdjustPrivilege"))
RAP(20, TRUE, 0, &WasEn);
TCHAR ProcessName[MAX_PATH];
ExpandEnvironmentStrings(argv[1], ProcessName, MAX_PATH);
DWORD PID = ProcessName2PID(ProcessName);
if((PID == PW_PIDERROR) || (PID == PW_SESERROR))
_tprintf(_T("Process '%s' not found!"), argv[1]);
else
if(PID == PW_MEMERROR)
_tprintf(_T("Not enough memory!"));
else {
NTLOAD l_NtLoad;
l_NtLoad.SubSystem = 2; //gui is default
if(argc > 3)
if((argv[3][0] | ' ') == 'c')
l_NtLoad.SubSystem = 3; //cui //FIX: when native app is terminated, console is not freed
l_NtLoad.LdrLoadDll = (TLDLL)GetProcAddress(hntdll, "LdrLoadDll");
l_NtLoad.NtProtectVirtualMemory = (TNTPV)GetProcAddress(hntdll, "NtProtectVirtualMemory");
if(l_NtLoad.LdrLoadDll && l_NtLoad.NtProtectVirtualMemory) {
#ifdef UNICODE
l_NtLoad.DllName.Length = sizeof(WCHAR)*(ExpandEnvironmentStrings(argv[2], l_NtLoad.DllNameW, sizeof(l_NtLoad.DllNameW))-1);
#else
CHAR DllNameA[MAX_PATH];
ExpandEnvironmentStrings(argv[2], DllNameA, sizeof(DllNameA));
l_NtLoad.DllName.Length = sizeof(WCHAR)*swprintf(l_NtLoad.DllNameW, L"%hs", DllNameA);
#endif
l_NtLoad.DllName.MaximumLength = sizeof(l_NtLoad.DllNameW);
HANDLE hProc;
if(hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID)) {
DWORD RCresult = 0;
PRCINFO pRCI = GetDefaultRCInfo(); pRCI->RCFlags = RC_FL_OWNTIMEOUT;
PNTLOAD pNtLoad;
DWORD pfl = hGetProcFlags(hProc);
if(pfl & RC_PF_NATIVE) {//Target is native
if(GetSessionId(GetCurrentProcessId()) != GetSessionId(PID)) {
TCHAR ch;
do {
_tprintf(_T("\nCan't determine session id or session mismatch.\nAttach '%s' to this session? [Y/N]"), argv[1]);
ch = getch() | ' ';
} while((ch != 'y') && (ch != 'n'));
if(ch == 'n')
return(ch);
}
}
if(l_NtLoad.DllName.Buffer = (PWSTR)(pNtLoad =
(PNTLOAD)pRCI->RtlAllocMem(hProc, sizeof(l_NtLoad)))) {
if(WriteProcessMemory(hProc, pNtLoad, &l_NtLoad, sizeof(l_NtLoad), NULL)) {
RCresult = hRemoteExecute(NULL, hProc, 0, NtLoadRC,
(DWORD)_tmain-(DWORD)NtLoadRC+(sizeof(DWORD)-1),
pNtLoad);
if(RCresult == ErrorAHTimeOut) {
if(pRCI->ProcFlags & RC_PF_NATIVE) {// native thread was created
if(pfl & RC_PF_NATIVE) {//in native process
CreateWin32Process(hProc, pRCI->hThread, pRCI->ProcessId, pRCI->ThreadId, l_NtLoad.SubSystem);
}
CreateWin32Thread(pRCI->hThread, pRCI->ProcessId, pRCI->ThreadId);
}
ResumeThread(pRCI->hThread);
WaitForSingleObject(pRCI->hThread, INFINITE);
GetExitCodeThread(pRCI->hThread, &RCresult);
CloseHandle(pRCI->hThread);
if(pRCI->RCFlags & RC_FL_OWNFREE)
pRCI->RtlFreeMem(pRCI->hProcess, pRCI->ThreadBody);
if(pRCI->ProcFlags & RC_PF_NATIVE)
pRCI->RtlFreeMem(pRCI->hProcess, pRCI->ThreadStack);
CloseHandle(pRCI->hProcess);
if(RCresult && (RCresult < ErrorAHMin))
_tprintf(_T("'%s' loaded at 0x%.8X."), argv[2], RCresult);
else
_tprintf(_T("Loading '%s' failed with 0x%.8X!"), argv[2], RCresult);
}
else
_tprintf(_T("Can't prepare loading '%s'!"), argv[2]);
}
else
_tprintf(_T("Can't write to '%s' memory!"), argv[1]);
pRCI->RtlFreeMem(hProc, pNtLoad);
}
else
_tprintf(_T("Can't allocate memory in '%s'!"), argv[1]);
CloseHandle(hProc);
}
else
_tprintf(_T("Can't get ALL_ACCESS handle to '%s'!"), argv[1]);
}
else
_tprintf(_T("Can't retrieve used APIs!"));
}
}
return(getch());
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -