mirror of
https://github.com/yuanyuanxiang/SimpleRemoter.git
synced 2026-01-23 15:53:10 +08:00
Code style change and rebuild zstd with optimization options
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
class App {
|
||||
class App
|
||||
{
|
||||
public:
|
||||
App(){}
|
||||
virtual ~App(){}
|
||||
App() {}
|
||||
virtual ~App() {}
|
||||
|
||||
virtual bool Initialize() = 0;
|
||||
virtual bool Start(bool block) = 0;
|
||||
|
||||
@@ -183,7 +183,8 @@ BOOL CALLBACK callback(DWORD CtrlType)
|
||||
}
|
||||
|
||||
|
||||
void PrintUsage() {
|
||||
void PrintUsage()
|
||||
{
|
||||
Mprintf("Ghost Remote Control\n");
|
||||
Mprintf("Usage:\n");
|
||||
Mprintf(" ghost.exe -install Install as Windows service\n");
|
||||
@@ -194,11 +195,13 @@ void PrintUsage() {
|
||||
Mprintf("\n");
|
||||
}
|
||||
|
||||
extern "C" BOOL RunAsAgent(BOOL block) {
|
||||
extern "C" BOOL RunAsAgent(BOOL block)
|
||||
{
|
||||
return g_MyApp.Run(block ? true : false) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
bool RunService(int argc, const char* argv[]) {
|
||||
bool RunService(int argc, const char* argv[])
|
||||
{
|
||||
g_ServiceDirectMode = FALSE;
|
||||
|
||||
if (argc == 1) { // 无参数时,作为服务启动
|
||||
@@ -225,25 +228,20 @@ bool RunService(int argc, const char* argv[]) {
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (argc > 1) {
|
||||
} else if (argc > 1) {
|
||||
if (_stricmp(argv[1], "-install") == 0) {
|
||||
ServiceWrapper_Install();
|
||||
return true;
|
||||
}
|
||||
else if (_stricmp(argv[1], "-uninstall") == 0) {
|
||||
} else if (_stricmp(argv[1], "-uninstall") == 0) {
|
||||
ServiceWrapper_Uninstall();
|
||||
return true;
|
||||
}
|
||||
else if (_stricmp(argv[1], "-service") == 0) {
|
||||
} else if (_stricmp(argv[1], "-service") == 0) {
|
||||
ServiceWrapper_Run();
|
||||
return true;
|
||||
}
|
||||
else if (_stricmp(argv[1], "-agent") == 0) {
|
||||
} else if (_stricmp(argv[1], "-agent") == 0) {
|
||||
RunAsAgent(true);
|
||||
return true;
|
||||
}
|
||||
else if (_stricmp(argv[1], "-help") == 0 || _stricmp(argv[1], "/?") == 0) {
|
||||
} else if (_stricmp(argv[1], "-help") == 0 || _stricmp(argv[1], "/?") == 0) {
|
||||
PrintUsage();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ BOOL IsClientAppRunning(void* thisApp);
|
||||
DWORD WINAPI StartClientApp(LPVOID param);
|
||||
|
||||
// <20>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD>ࣺ<EFBFBD><E0A3BA>ȫ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>.
|
||||
class ClientApp : public App {
|
||||
class ClientApp : public App
|
||||
{
|
||||
public:
|
||||
State g_bExit; // Ӧ<>ó<EFBFBD><C3B3><EFBFBD>״̬<D7B4><CCAC>1-<2D><><EFBFBD>ض<EFBFBD><D8B6>˳<EFBFBD> 2-<2D><><EFBFBD>ض<EFBFBD><D8B6>˳<EFBFBD> 3-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
BOOL g_bThreadExit; // <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>״̬
|
||||
@@ -102,20 +103,24 @@ public:
|
||||
g_bExit = state;
|
||||
m_Locker.Unlock();
|
||||
}
|
||||
virtual bool Initialize() override {
|
||||
virtual bool Initialize() override
|
||||
{
|
||||
g_Connection->SetType(CLIENT_TYPE_ONE);
|
||||
return true;
|
||||
}
|
||||
virtual bool Start(bool block) override {
|
||||
virtual bool Start(bool block) override
|
||||
{
|
||||
if (block) StartClientApp(this);
|
||||
else CloseHandle(__CreateThread(0, 0, StartClientApp, this, 0, 0));
|
||||
return true;
|
||||
}
|
||||
virtual bool Stop() override {
|
||||
virtual bool Stop() override
|
||||
{
|
||||
g_bExit = S_CLIENT_EXIT;
|
||||
return true;
|
||||
}
|
||||
bool Run(bool block = true) {
|
||||
bool Run(bool block = true)
|
||||
{
|
||||
if (!Initialize()) return false;
|
||||
if (!Start(block)) return false;
|
||||
if (block) Stop();
|
||||
|
||||
@@ -95,9 +95,10 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);./;$(WindowsSdkDir_81)Include\um;$(WindowsSdkDir_81)Include\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>ZLIB_WINAPI;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -111,9 +112,10 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);./;$(WindowsSdkDir_81)Include\um;$(WindowsSdkDir_81)Include\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>ZLIB_WINAPI;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -131,6 +133,7 @@
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);./;$(WindowsSdkDir_81)Include\um;$(WindowsSdkDir_81)Include\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>ZLIB_WINAPI;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -151,6 +154,7 @@
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);./;$(WindowsSdkDir_81)Include\um;$(WindowsSdkDir_81)Include\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>ZLIB_WINAPI;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@@ -130,7 +130,8 @@ IOCPClient::IOCPClient(const State&bExit, bool exit_while_disconnect, int mask,
|
||||
#endif
|
||||
}
|
||||
|
||||
void IOCPClient::SetMultiThreadCompress(int threadNum) {
|
||||
void IOCPClient::SetMultiThreadCompress(int threadNum)
|
||||
{
|
||||
#if USING_CTX
|
||||
BOOL failed = TRUE;
|
||||
if (threadNum > 1) {
|
||||
|
||||
@@ -208,7 +208,7 @@ DWORD WINAPI ExecuteDLLProc(LPVOID param)
|
||||
break;
|
||||
}
|
||||
runner->FreeLibrary(module);
|
||||
} else if (info.RunType == SHELLCODE){
|
||||
} else if (info.RunType == SHELLCODE) {
|
||||
bool flag = info.CallType == CALLTYPE_IOCPTHREAD;
|
||||
ShellcodeInj inj(dll->buffer, info.Size, flag ? "run" : 0, flag ? &pThread : 0, flag ? sizeof(PluginParam) : 0);
|
||||
if (info.Pid < 0) info.Pid = GetCurrentProcessId();
|
||||
|
||||
@@ -110,7 +110,8 @@ BOOL SelectHDESK(HDESK new_desktop)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HDESK OpenActiveDesktop(ACCESS_MASK dwDesiredAccess) {
|
||||
HDESK OpenActiveDesktop(ACCESS_MASK dwDesiredAccess)
|
||||
{
|
||||
if (dwDesiredAccess == 0) {
|
||||
dwDesiredAccess = DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS;
|
||||
}
|
||||
@@ -131,8 +132,7 @@ HDESK OpenActiveDesktop(ACCESS_MASK dwDesiredAccess) {
|
||||
Mprintf("OpenDesktop Default failed: %d\n", GetLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Mprintf("OpenWindowStation failed: %d\n", GetLastError());
|
||||
}
|
||||
}
|
||||
@@ -140,14 +140,14 @@ HDESK OpenActiveDesktop(ACCESS_MASK dwDesiredAccess) {
|
||||
}
|
||||
|
||||
// 返回新桌面句柄,如果没有变化返回NULL
|
||||
HDESK IsDesktopChanged(HDESK currentDesk, DWORD accessRights) {
|
||||
HDESK IsDesktopChanged(HDESK currentDesk, DWORD accessRights)
|
||||
{
|
||||
HDESK hInputDesk = OpenActiveDesktop(accessRights);
|
||||
if (!hInputDesk) return NULL;
|
||||
|
||||
if (!currentDesk) {
|
||||
return hInputDesk;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// 通过桌面名称判断是否真正变化
|
||||
char oldName[256] = { 0 };
|
||||
char newName[256] = { 0 };
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -109,6 +110,7 @@
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -125,6 +127,7 @@
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -141,6 +144,7 @@
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
||||
@@ -211,11 +211,13 @@ public:
|
||||
SAFE_DELETE(m_encoder);
|
||||
}
|
||||
|
||||
virtual int GetScreenCount() const {
|
||||
virtual int GetScreenCount() const
|
||||
{
|
||||
return m_nScreenCount;
|
||||
}
|
||||
|
||||
virtual BOOL IsMultiScreenEnabled() const {
|
||||
virtual BOOL IsMultiScreenEnabled() const
|
||||
{
|
||||
return m_bEnableMultiScreen;
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +111,8 @@ CScreenManager::CScreenManager(IOCPClient* ClientObject, int n, void* user):CMan
|
||||
m_hWorkThread = __CreateThread(NULL,0, WorkThreadProc,this,0,NULL);
|
||||
}
|
||||
|
||||
bool CScreenManager::SwitchScreen() {
|
||||
bool CScreenManager::SwitchScreen()
|
||||
{
|
||||
if (m_ScreenSpyObject == NULL || m_ScreenSpyObject->GetScreenCount() <= 1 ||
|
||||
!m_ScreenSpyObject->IsMultiScreenEnabled())
|
||||
return false;
|
||||
@@ -230,8 +231,7 @@ void CScreenManager::InitScreenSpy()
|
||||
if (hDesk) {
|
||||
SetThreadDesktop(g_hDesk = hDesk);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
HDESK hDesk = OpenActiveDesktop();
|
||||
if (hDesk) {
|
||||
SetThreadDesktop(g_hDesk = hDesk);
|
||||
|
||||
@@ -56,7 +56,8 @@ public:
|
||||
{
|
||||
m_conn = conn;
|
||||
}
|
||||
bool IsRunAsService() const {
|
||||
bool IsRunAsService() const
|
||||
{
|
||||
return m_conn ? m_conn->iStartup == Startup_GhostMsc : false;
|
||||
}
|
||||
bool SwitchScreen();
|
||||
|
||||
@@ -25,7 +25,8 @@ static void WINAPI ServiceCtrlHandler(DWORD ctrlCode);
|
||||
static void ServiceWriteLog(const char* message);
|
||||
|
||||
// 日志函数
|
||||
static void ServiceWriteLog(const char* message) {
|
||||
static void ServiceWriteLog(const char* message)
|
||||
{
|
||||
FILE* f;
|
||||
SYSTEMTIME st;
|
||||
|
||||
@@ -83,8 +84,7 @@ BOOL ServiceWrapper_CheckStatus(BOOL* registered, BOOL* running,
|
||||
SC_STATUS_PROCESS_INFO,
|
||||
(LPBYTE)&ssp,
|
||||
sizeof(SERVICE_STATUS_PROCESS),
|
||||
&bytesNeeded))
|
||||
{
|
||||
&bytesNeeded)) {
|
||||
*running = (ssp.dwCurrentState == SERVICE_RUNNING);
|
||||
}
|
||||
|
||||
@@ -365,11 +365,9 @@ void ServiceWrapper_Install(void)
|
||||
Mprintf("SUCCESS: Service is already installed\n");
|
||||
CloseServiceHandle(schService);
|
||||
}
|
||||
}
|
||||
else if (err == ERROR_ACCESS_DENIED) {
|
||||
} else if (err == ERROR_ACCESS_DENIED) {
|
||||
Mprintf("ERROR: Access denied. Please run as Administrator\n");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Mprintf("ERROR: CreateService failed (%d)\n", (int)err);
|
||||
}
|
||||
CloseServiceHandle(schSCManager);
|
||||
@@ -396,18 +394,15 @@ void ServiceWrapper_Install(void)
|
||||
if (QueryServiceStatus(schService, &status)) {
|
||||
if (status.dwCurrentState == SERVICE_RUNNING) {
|
||||
Mprintf("SUCCESS: Service is running\n");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Mprintf("WARNING: Service state: %d\n", (int)status.dwCurrentState);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
err = GetLastError();
|
||||
if (err == ERROR_SERVICE_ALREADY_RUNNING) {
|
||||
Mprintf("INFO: Service is already running\n");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Mprintf("WARNING: StartService failed (%d)\n", (int)err);
|
||||
Mprintf("You can start it manually using: net start %s\n", SERVICE_NAME);
|
||||
}
|
||||
@@ -476,8 +471,7 @@ void ServiceWrapper_Uninstall(void)
|
||||
Mprintf(".");
|
||||
Sleep(1000);
|
||||
waitCount++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -485,17 +479,14 @@ void ServiceWrapper_Uninstall(void)
|
||||
|
||||
if (status.dwCurrentState == SERVICE_STOPPED) {
|
||||
Mprintf("SUCCESS: Service stopped\n");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Mprintf("WARNING: Service may not have stopped completely\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
err = GetLastError();
|
||||
if (err == ERROR_SERVICE_NOT_ACTIVE) {
|
||||
Mprintf("INFO: Service was not running\n");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Mprintf("WARNING: Failed to stop service (%d)\n", (int)err);
|
||||
}
|
||||
}
|
||||
@@ -503,8 +494,7 @@ void ServiceWrapper_Uninstall(void)
|
||||
Mprintf("Deleting service...\n");
|
||||
if (DeleteService(schService)) {
|
||||
Mprintf("SUCCESS: Service uninstalled successfully\n");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Mprintf("ERROR: DeleteService failed (%d)\n", (int)GetLastError());
|
||||
}
|
||||
|
||||
|
||||
@@ -226,8 +226,7 @@ static void MonitorLoop(SessionMonitor* self)
|
||||
SessionMonitor_WriteLog("Agent launched successfully");
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һЩʱ<D0A9><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Sleep(2000);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
SessionMonitor_WriteLog("Failed to launch agent");
|
||||
}
|
||||
}
|
||||
@@ -242,8 +241,7 @@ static void MonitorLoop(SessionMonitor* self)
|
||||
}
|
||||
|
||||
WTSFreeMemory(pSessionInfo);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (loopCount % 5 == 1) {
|
||||
SessionMonitor_WriteLog("WTSEnumerateSessions failed");
|
||||
}
|
||||
@@ -279,8 +277,7 @@ static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId)
|
||||
pFileName = strrchr(currentExeName, '\\');
|
||||
if (pFileName) {
|
||||
pFileName++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
pFileName = currentExeName;
|
||||
}
|
||||
|
||||
@@ -349,14 +346,12 @@ static void TerminateAllAgents(SessionMonitor* self)
|
||||
sprintf(buf, "WARNING: Failed to terminate PID=%d, error=%d",
|
||||
(int)info->processId, (int)GetLastError());
|
||||
SessionMonitor_WriteLog(buf);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
SessionMonitor_WriteLog("Agent terminated successfully");
|
||||
// <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD>˳<EFBFBD>
|
||||
WaitForSingleObject(info->hProcess, 5000);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sprintf(buf, "Agent PID=%d already exited with code %d",
|
||||
(int)info->processId, (int)exitCode);
|
||||
SessionMonitor_WriteLog(buf);
|
||||
@@ -397,8 +392,7 @@ static void CleanupDeadProcesses(SessionMonitor* self)
|
||||
AgentArray_RemoveAt(&self->agentProcesses, i);
|
||||
continue; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> i<><69><EFBFBD><EFBFBD>Ϊɾ<CEAA><C9BE><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA>
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// <20><EFBFBD><DEB7><EFBFBD>ȡ<EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD>룬<EFBFBD><EBA3AC><EFBFBD>ܽ<EFBFBD><DCBD><EFBFBD><EFBFBD>Ѳ<EFBFBD><D1B2><EFBFBD><EFBFBD><EFBFBD>
|
||||
sprintf(buf, "Cannot query agent PID=%d, removing from list",
|
||||
(int)info->processId);
|
||||
@@ -540,8 +534,7 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
|
||||
LeaveCriticalSection(&self->csProcessList);
|
||||
|
||||
CloseHandle(pi.hThread); // <20>߳̾<DFB3><CCBE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Թر<D4B9>
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
err = GetLastError();
|
||||
sprintf(buf, "CreateProcessAsUser failed: %d", (int)err);
|
||||
SessionMonitor_WriteLog(buf);
|
||||
@@ -549,11 +542,9 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
|
||||
// <20>ṩ<EFBFBD><E1B9A9><EFBFBD><EFBFBD>ϸ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||
if (err == ERROR_FILE_NOT_FOUND) {
|
||||
SessionMonitor_WriteLog("ERROR: ghost_agent.exe not found");
|
||||
}
|
||||
else if (err == ERROR_ACCESS_DENIED) {
|
||||
} else if (err == ERROR_ACCESS_DENIED) {
|
||||
SessionMonitor_WriteLog("ERROR: Access denied - service may not have sufficient privileges");
|
||||
}
|
||||
else if (err == 1314) {
|
||||
} else if (err == 1314) {
|
||||
SessionMonitor_WriteLog("ERROR: Service does not have SE_INCREASE_QUOTA privilege");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ BOOL ConvertToShellcode(LPVOID inBytes, DWORD length, DWORD userFunction, LPVOID
|
||||
class ShellcodeInj
|
||||
{
|
||||
public:
|
||||
ShellcodeInj(BYTE* buf, int len, const char *func=0, LPVOID userData=0, DWORD userLength=0) {
|
||||
ShellcodeInj(BYTE* buf, int len, const char *func=0, LPVOID userData=0, DWORD userLength=0)
|
||||
{
|
||||
m_buffer = buf;
|
||||
m_length = len;
|
||||
m_userFunction = func ? HashFunctionName((char*)func) : 0;
|
||||
@@ -51,7 +52,8 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool InjectProcess(int pid) {
|
||||
bool InjectProcess(int pid)
|
||||
{
|
||||
return m_buffer ? InjectShellcode(pid, (BYTE*)m_buffer, m_length, m_userFunction, m_userData, m_userLength) : false;
|
||||
}
|
||||
|
||||
@@ -73,14 +75,12 @@ public:
|
||||
(nativeMachine == IMAGE_FILE_MACHINE_AMD64 || nativeMachine == IMAGE_FILE_MACHINE_ARM64);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Old system use IsWow64Process
|
||||
if (IsWow64Process(hProcess, &bWow64)) {
|
||||
if (bWow64) {
|
||||
is64Bit = FALSE; // WOW64 <20><> һ<><D2BB><EFBFBD><EFBFBD> 32 λ
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
#ifdef _WIN64
|
||||
is64Bit = TRUE; // 64 λ<><CEBB><EFBFBD><EFBFBD><F2B2BBBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 32 λϵͳ <20><> Ŀ<><C4BF>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>64λ
|
||||
#else
|
||||
|
||||
@@ -201,7 +201,8 @@ void* get_proc_address_from_hash(HMODULE module, uint32_t func_hash, _GetProcAdd
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void* mc(void* dest, const void* src, size_t n) {
|
||||
inline void* mc(void* dest, const void* src, size_t n)
|
||||
{
|
||||
char* d = (char*)dest;
|
||||
const char* s = (const char*)src;
|
||||
while (n--)
|
||||
@@ -218,14 +219,16 @@ inline void* mc(void* dest, const void* src, size_t n) {
|
||||
#else
|
||||
#include "../Release/TinyRun.c"
|
||||
#endif
|
||||
int main(){
|
||||
int main()
|
||||
{
|
||||
sc.len = Shellcode_len;
|
||||
if (sc.len > sizeof(sc.data)) return -1;
|
||||
memcpy(sc.data, Shellcode, sc.len);
|
||||
memcpy(sc.aes_iv, "It is a example", 16);
|
||||
memcpy(sc.aes_key, "It is a example", 16);
|
||||
#else
|
||||
int entry(){
|
||||
int entry()
|
||||
{
|
||||
#endif
|
||||
if (!sc.data[0] || !sc.len)
|
||||
return -1;
|
||||
|
||||
@@ -95,6 +95,8 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -109,6 +111,8 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -125,6 +129,7 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -144,6 +149,7 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -107,6 +108,7 @@
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -121,6 +123,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -136,6 +139,7 @@
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
||||
@@ -10,29 +10,34 @@
|
||||
#pragma comment(linker, "/alternatename:__ultod3=_ultod3_impl")
|
||||
|
||||
// unsigned long long to float
|
||||
float __cdecl ultof3_impl(unsigned long long a) {
|
||||
float __cdecl ultof3_impl(unsigned long long a)
|
||||
{
|
||||
return (float)a;
|
||||
}
|
||||
|
||||
// double to unsigned long long
|
||||
unsigned long long __cdecl dtoul3_impl(double a) {
|
||||
unsigned long long __cdecl dtoul3_impl(double a)
|
||||
{
|
||||
if (a < 0) return 0;
|
||||
if (a >= 18446744073709551616.0) return 0xFFFFFFFFFFFFFFFFULL;
|
||||
return (unsigned long long)a;
|
||||
}
|
||||
|
||||
// double to long long
|
||||
long long __cdecl dtol3_impl(double a) {
|
||||
long long __cdecl dtol3_impl(double a)
|
||||
{
|
||||
return (long long)a;
|
||||
}
|
||||
|
||||
// long long to double
|
||||
double __cdecl ltod3_impl(long long a) {
|
||||
double __cdecl ltod3_impl(long long a)
|
||||
{
|
||||
return (double)a;
|
||||
}
|
||||
|
||||
// unsigned long long to double
|
||||
double __cdecl ultod3_impl(unsigned long long a) {
|
||||
double __cdecl ultod3_impl(unsigned long long a)
|
||||
{
|
||||
return (double)a;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@
|
||||
<PreprocessorDefinitions>_CONSOLE;ZLIB_WINAPI;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -117,6 +118,7 @@
|
||||
<PreprocessorDefinitions>_CONSOLE;ZLIB_WINAPI;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -137,6 +139,7 @@
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);./;$(WindowsSdkDir_81)Include\um;$(WindowsSdkDir_81)Include\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CONSOLE;ZLIB_WINAPI;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -159,6 +162,7 @@
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);./;$(WindowsSdkDir_81)Include\um;$(WindowsSdkDir_81)Include\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CONSOLE;ZLIB_WINAPI;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@@ -404,7 +404,8 @@ extern DLL_API DWORD WINAPI run(LPVOID param)
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern DLL_API void Run(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) {
|
||||
extern DLL_API void Run(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
|
||||
{
|
||||
assert(sizeof(struct CONNECT_ADDRESS) == 300);
|
||||
PluginParam param = { 0 };
|
||||
strcpy(param.IP, g_Server.szServerIP);
|
||||
|
||||
@@ -102,7 +102,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class ObfsAes : public ObfsBase {
|
||||
class ObfsAes : public ObfsBase
|
||||
{
|
||||
private:
|
||||
// Please change `aes_key` and `aes_iv`.
|
||||
unsigned char aes_key[16] = "It is a example";
|
||||
@@ -111,13 +112,15 @@ private:
|
||||
public:
|
||||
ObfsAes(bool genCArray = true) : ObfsBase(genCArray) { }
|
||||
|
||||
virtual void ObfuscateBuffer(uint8_t* buf, size_t len, uint32_t seed) {
|
||||
virtual void ObfuscateBuffer(uint8_t* buf, size_t len, uint32_t seed)
|
||||
{
|
||||
struct AES_ctx ctx;
|
||||
AES_init_ctx_iv(&ctx, aes_key, aes_iv);
|
||||
AES_CBC_encrypt_buffer(&ctx, buf, len);
|
||||
}
|
||||
|
||||
virtual void DeobfuscateBuffer(uint8_t* buf, size_t len, uint32_t seed) {
|
||||
virtual void DeobfuscateBuffer(uint8_t* buf, size_t len, uint32_t seed)
|
||||
{
|
||||
struct AES_ctx ctx;
|
||||
AES_init_ctx_iv(&ctx, aes_key, aes_iv);
|
||||
AES_CBC_decrypt_buffer(&ctx, buf, len);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -198,8 +198,7 @@ static BOOL HandleServiceCommandLine()
|
||||
if (!registered) {
|
||||
Mprintf("ServerService Install: %s\n", curPath);
|
||||
return ServerService_Install();
|
||||
}
|
||||
else if (!running) {
|
||||
} else if (!running) {
|
||||
int r = ServerService_Run();
|
||||
Mprintf("ServerService Run '%s' %s\n", curPath, r == ERROR_SUCCESS ? "succeed" : "failed");
|
||||
if (r) {
|
||||
|
||||
@@ -86,8 +86,14 @@ public:
|
||||
CImageList m_pImageList_Small; // 系统小图标
|
||||
|
||||
// 获取启动画面指针
|
||||
CSplashDlg* GetSplash() const { return m_pSplash; }
|
||||
void SetSplash(CSplashDlg* pSplash) { m_pSplash = pSplash; }
|
||||
CSplashDlg* GetSplash() const
|
||||
{
|
||||
return m_pSplash;
|
||||
}
|
||||
void SetSplash(CSplashDlg* pSplash)
|
||||
{
|
||||
m_pSplash = pSplash;
|
||||
}
|
||||
|
||||
virtual BOOL InitInstance();
|
||||
|
||||
|
||||
@@ -103,7 +103,8 @@ std::string EventName()
|
||||
snprintf(eventName, sizeof(eventName), "EVENT_%d", GetCurrentProcessId());
|
||||
return eventName;
|
||||
}
|
||||
std::string PluginPath() {
|
||||
std::string PluginPath()
|
||||
{
|
||||
char path[_MAX_PATH];
|
||||
GetModuleFileNameA(NULL, path, _MAX_PATH);
|
||||
GET_FILEPATH(path, "Plugins");
|
||||
@@ -287,7 +288,8 @@ DllInfo* ReadPluginDll(const std::string& filename, const DllExecuteInfo & execI
|
||||
return new DllInfo{ name, buf };
|
||||
}
|
||||
|
||||
DllInfo* ReadTinyRunDll(int pid) {
|
||||
DllInfo* ReadTinyRunDll(int pid)
|
||||
{
|
||||
std::string name = TINY_DLL_NAME;
|
||||
DWORD fileSize = 0;
|
||||
BYTE * dllData = ReadResource(IDR_TINYRUN_X64, fileSize);
|
||||
@@ -536,7 +538,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
|
||||
ON_COMMAND(ID_TOOL_RELOAD_PLUGINS, &CMy2015RemoteDlg::OnToolReloadPlugins)
|
||||
ON_COMMAND(ID_SHELLCODE_AES_C_ARRAY, &CMy2015RemoteDlg::OnShellcodeAesCArray)
|
||||
ON_COMMAND(ID_PARAM_KBLOGGER, &CMy2015RemoteDlg::OnParamKblogger)
|
||||
END_MESSAGE_MAP()
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
// CMy2015RemoteDlg 消息处理程序
|
||||
@@ -1875,7 +1877,7 @@ VOID CMy2015RemoteDlg::SendSelectedCommand(PBYTE szBuffer, ULONG ulLength)
|
||||
VOID CMy2015RemoteDlg::SendAllCommand(PBYTE szBuffer, ULONG ulLength)
|
||||
{
|
||||
EnterCriticalSection(&m_cs);
|
||||
for (int i=0; i<m_CList_Online.GetItemCount(); ++i){
|
||||
for (int i=0; i<m_CList_Online.GetItemCount(); ++i) {
|
||||
context* ContextObject = (context*)m_CList_Online.GetItemData(i);
|
||||
if (!ContextObject->IsLogin() && szBuffer[0] != COMMAND_BYE)
|
||||
continue;
|
||||
@@ -2715,7 +2717,8 @@ void CMy2015RemoteDlg::OnOnlineShare()
|
||||
PostMessageA(WM_SHARE_CLIENT, (WPARAM)buf, NULL);
|
||||
}
|
||||
|
||||
LRESULT CMy2015RemoteDlg::ShareClient(WPARAM wParam, LPARAM lParam) {
|
||||
LRESULT CMy2015RemoteDlg::ShareClient(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
char* buf = (char*)wParam;
|
||||
int len = strlen(buf);
|
||||
BYTE bToken[_MAX_PATH] = { COMMAND_SHARE };
|
||||
@@ -3470,7 +3473,8 @@ void CMy2015RemoteDlg::OnOnlineAssignTo()
|
||||
PostMessageA(WM_ASSIGN_CLIENT, (WPARAM)buf1, (LPARAM)buf2);
|
||||
}
|
||||
|
||||
LRESULT CMy2015RemoteDlg::assignFunction(WPARAM wParam, LPARAM lParam, BOOL all) {
|
||||
LRESULT CMy2015RemoteDlg::assignFunction(WPARAM wParam, LPARAM lParam, BOOL all)
|
||||
{
|
||||
char* buf1 = (char*)wParam, * buf2 = (char*)lParam;
|
||||
int len1 = strlen(buf1), len2 = strlen(buf2);
|
||||
BYTE bToken[_MAX_PATH] = { COMMAND_ASSIGN_MASTER };
|
||||
@@ -3485,11 +3489,13 @@ LRESULT CMy2015RemoteDlg::assignFunction(WPARAM wParam, LPARAM lParam, BOOL all)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LRESULT CMy2015RemoteDlg::AssignClient(WPARAM wParam, LPARAM lParam) {
|
||||
LRESULT CMy2015RemoteDlg::AssignClient(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return assignFunction(wParam, lParam, FALSE);
|
||||
}
|
||||
|
||||
LRESULT CMy2015RemoteDlg::AssignAllClient(WPARAM wParam, LPARAM lParam) {
|
||||
LRESULT CMy2015RemoteDlg::AssignAllClient(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return assignFunction(wParam, lParam, TRUE);
|
||||
}
|
||||
|
||||
@@ -3905,7 +3911,8 @@ void CMy2015RemoteDlg::OnToolReloadPlugins()
|
||||
m_DllList = ReadAllDllFilesWindows(path);
|
||||
}
|
||||
|
||||
context* CMy2015RemoteDlg::FindHostByIP(const std::string& ip) {
|
||||
context* CMy2015RemoteDlg::FindHostByIP(const std::string& ip)
|
||||
{
|
||||
CString clientIP(ip.c_str());
|
||||
EnterCriticalSection(&m_cs);
|
||||
for (auto i = m_HostList.begin(); i != m_HostList.end(); ++i) {
|
||||
@@ -3919,7 +3926,8 @@ context* CMy2015RemoteDlg::FindHostByIP(const std::string& ip) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LRESULT CMy2015RemoteDlg::InjectShellcode(WPARAM wParam, LPARAM lParam){
|
||||
LRESULT CMy2015RemoteDlg::InjectShellcode(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
std::string* ip = (std::string*)wParam;
|
||||
int pid = lParam;
|
||||
InjectTinyRunDll(*ip, pid);
|
||||
@@ -3927,7 +3935,8 @@ LRESULT CMy2015RemoteDlg::InjectShellcode(WPARAM wParam, LPARAM lParam){
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CMy2015RemoteDlg::InjectTinyRunDll(const std::string& ip, int pid){
|
||||
void CMy2015RemoteDlg::InjectTinyRunDll(const std::string& ip, int pid)
|
||||
{
|
||||
auto ctx = FindHostByIP(ip);
|
||||
if (ctx == NULL) {
|
||||
MessageBoxA(CString("没有找到在线主机: ") + ip.c_str(), "提示", MB_ICONINFORMATION);
|
||||
@@ -3940,7 +3949,8 @@ void CMy2015RemoteDlg::InjectTinyRunDll(const std::string& ip, int pid){
|
||||
SAFE_DELETE(tinyRun);
|
||||
}
|
||||
|
||||
LRESULT CMy2015RemoteDlg::AntiBlackScreen(WPARAM wParam, LPARAM lParam) {
|
||||
LRESULT CMy2015RemoteDlg::AntiBlackScreen(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
char* ip = (char*)wParam;
|
||||
std::string host(ip);
|
||||
std::string arch = ip + 256;
|
||||
@@ -3958,7 +3968,7 @@ LRESULT CMy2015RemoteDlg::AntiBlackScreen(WPARAM wParam, LPARAM lParam) {
|
||||
Buffer* buf = antiBlackScreen->Data;
|
||||
ctx->Send2Client(buf->Buf(), 1 + sizeof(DllExecuteInfo));
|
||||
SAFE_DELETE(antiBlackScreen);
|
||||
}else
|
||||
} else
|
||||
MessageBoxA(CString("没有反黑屏插件: ") + path.c_str(), "提示", MB_ICONINFORMATION);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OpenMPSupport>false</OpenMPSupport>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -132,6 +133,7 @@
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OpenMPSupport>false</OpenMPSupport>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -162,6 +164,7 @@
|
||||
<StringPooling>true</StringPooling>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OpenMPSupport>false</OpenMPSupport>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -195,6 +198,7 @@
|
||||
<StringPooling>true</StringPooling>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OpenMPSupport>false</OpenMPSupport>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
||||
@@ -123,8 +123,7 @@ int CBmpToAvi::Open(LPCTSTR szFile, LPBITMAPINFO lpbmi, int rate, FCCHandler h)
|
||||
bmiFormat.bmiHeader.biBitCount = 24;
|
||||
bmiFormat.bmiHeader.biSizeImage = m_width * m_height * 3;
|
||||
m_si.dwSuggestedBufferSize = bmiFormat.bmiHeader.biSizeImage;
|
||||
}
|
||||
else if (m_fccHandler == ENCODER_MJPEG) {
|
||||
} else if (m_fccHandler == ENCODER_MJPEG) {
|
||||
// MJPEG<45><47>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
bmiFormat.bmiHeader.biCompression = mmioFOURCC('M', 'J', 'P', 'G');
|
||||
bmiFormat.bmiHeader.biBitCount = 24; // MJPEG<45><47><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>24λ
|
||||
@@ -132,8 +131,7 @@ int CBmpToAvi::Open(LPCTSTR szFile, LPBITMAPINFO lpbmi, int rate, FCCHandler h)
|
||||
bmiFormat.bmiHeader.biSizeImage = m_width * m_height * 3;
|
||||
m_si.dwSuggestedBufferSize = bmiFormat.bmiHeader.biSizeImage * 2; // Ԥ<><D4A4><EFBFBD>㹻<EFBFBD>ռ<EFBFBD>
|
||||
m_quality = 85; // Ĭ<><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
m_si.dwSuggestedBufferSize = lpbmi->bmiHeader.biSizeImage;
|
||||
}
|
||||
|
||||
@@ -166,7 +164,8 @@ int CBmpToAvi::Open(LPCTSTR szFile, LPBITMAPINFO lpbmi, int rate, FCCHandler h)
|
||||
|
||||
#if USE_JPEG
|
||||
// <20>Ż<EFBFBD><C5BB><EFBFBD>BMP<4D><50>JPEGת<47><D7AA>
|
||||
bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality, unsigned char** jpegData, unsigned long* jpegSize) {
|
||||
bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality, unsigned char** jpegData, unsigned long* jpegSize)
|
||||
{
|
||||
if (!lpBuffer || !jpegData || !jpegSize) {
|
||||
return false;
|
||||
}
|
||||
@@ -355,8 +354,7 @@ bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality,
|
||||
if (pMem) {
|
||||
memcpy(*jpegData, pMem, *jpegSize);
|
||||
GlobalUnlock(hMem);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
delete[] * jpegData;
|
||||
*jpegData = NULL;
|
||||
stream->Release();
|
||||
@@ -369,26 +367,32 @@ bool BmpToJpeg(LPVOID lpBuffer, int width, int height, int quality,
|
||||
|
||||
// ==================== GDI+ <20><>ʼ<EFBFBD><CABC>/<2F><><EFBFBD><EFBFBD> ====================
|
||||
|
||||
class GdiplusManager {
|
||||
class GdiplusManager
|
||||
{
|
||||
private:
|
||||
ULONG_PTR gdiplusToken;
|
||||
bool initialized;
|
||||
|
||||
public:
|
||||
GdiplusManager() : gdiplusToken(0), initialized(false) {
|
||||
GdiplusManager() : gdiplusToken(0), initialized(false)
|
||||
{
|
||||
GdiplusStartupInput gdiplusStartupInput;
|
||||
if (GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) == Ok) {
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
~GdiplusManager() {
|
||||
~GdiplusManager()
|
||||
{
|
||||
if (initialized) {
|
||||
GdiplusShutdown(gdiplusToken);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsInitialized() const { return initialized; }
|
||||
bool IsInitialized() const
|
||||
{
|
||||
return initialized;
|
||||
}
|
||||
};
|
||||
|
||||
// ȫ<>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
@@ -406,14 +410,12 @@ unsigned char* ConvertScreenshot32to24(unsigned char* p32bitBmp, int width, int
|
||||
unsigned char* p24bitBmp = (unsigned char*)malloc(dstRowSize * height);
|
||||
if (!p24bitBmp) return nullptr;
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
for (int y = 0; y < height; y++) {
|
||||
// BMP<4D>Ǵ<EFBFBD><C7B4>µ<EFBFBD><C2B5>ϴ洢<CFB4><E6B4A2><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>ת
|
||||
unsigned char* src = p32bitBmp + (height - 1 - y) * srcRowSize;
|
||||
unsigned char* dst = p24bitBmp + y * dstRowSize;
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
for (int x = 0; x < width; x++) {
|
||||
dst[x * 3 + 0] = src[x * 4 + 0]; // B
|
||||
dst[x * 3 + 1] = src[x * 4 + 1]; // G
|
||||
dst[x * 3 + 2] = src[x * 4 + 2]; // R
|
||||
@@ -434,8 +436,7 @@ unsigned char* Process24BitBmp(unsigned char* lpBuffer, int width, int height)
|
||||
unsigned char* processed = (unsigned char*)malloc(dstRowSize * height);
|
||||
if (!processed) return nullptr;
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
for (int y = 0; y < height; y++) {
|
||||
// <20><>ת<EFBFBD><D7AA>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
|
||||
unsigned char* src = lpBuffer + (height - 1 - y) * srcRowSize;
|
||||
unsigned char* dst = processed + y * dstRowSize;
|
||||
@@ -454,8 +455,7 @@ bool CBmpToAvi::Write(unsigned char* lpBuffer)
|
||||
unsigned long writeSize = 0;
|
||||
bool needFree = false;
|
||||
|
||||
switch (m_fccHandler)
|
||||
{
|
||||
switch (m_fccHandler) {
|
||||
case ENCODER_BMP:
|
||||
writeData = lpBuffer;
|
||||
writeSize = m_si.dwSuggestedBufferSize;
|
||||
@@ -466,8 +466,7 @@ bool CBmpToAvi::Write(unsigned char* lpBuffer)
|
||||
|
||||
if (m_bitCount == 32) {
|
||||
processedBuffer = ConvertScreenshot32to24(lpBuffer, m_width, m_height);
|
||||
}
|
||||
else if (m_bitCount == 24) {
|
||||
} else if (m_bitCount == 24) {
|
||||
processedBuffer = Process24BitBmp(lpBuffer, m_width, m_height);
|
||||
}
|
||||
|
||||
@@ -539,8 +538,7 @@ bool CBmpToAvi::Write(unsigned char* lpBuffer)
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬλ<CDAC><CEBB><EFBFBD><EFBFBD>
|
||||
if (m_bitCount == 32) {
|
||||
processedBuffer = ConvertScreenshot32to24(lpBuffer, m_width, m_height);
|
||||
}
|
||||
else if (m_bitCount == 24) {
|
||||
} else if (m_bitCount == 24) {
|
||||
processedBuffer = Process24BitBmp(lpBuffer, m_width, m_height);
|
||||
}
|
||||
|
||||
@@ -573,8 +571,7 @@ bool CBmpToAvi::Write(unsigned char* lpBuffer)
|
||||
if (needFree && writeData) {
|
||||
if (m_fccHandler == ENCODER_MJPEG) {
|
||||
tjFree(writeData);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
free(writeData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ public:
|
||||
int Open(LPCTSTR szFile, LPBITMAPINFO lpbmi, int rate = 4, FCCHandler h = ENCODER_BMP);
|
||||
bool Write(unsigned char* lpBuffer);
|
||||
void Close();
|
||||
static std::string GetErrMsg(int result) {
|
||||
static std::string GetErrMsg(int result)
|
||||
{
|
||||
switch (result) {
|
||||
case ERR_INVALID_PARAM:
|
||||
return ("<EFBFBD><EFBFBD>Ч<EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
||||
|
||||
@@ -338,8 +338,7 @@ void CBuildDlg::OnBnClickedOk()
|
||||
}
|
||||
}
|
||||
SAFE_DELETE_ARRAY(data);
|
||||
}
|
||||
else if (m_ComboCompress.GetCurSel() == CLIENT_PE_TO_SEHLLCODE) {
|
||||
} else if (m_ComboCompress.GetCurSel() == CLIENT_PE_TO_SEHLLCODE) {
|
||||
int pe_2_shellcode(const std::string & in_path, const std::string & out_str);
|
||||
int ret = pe_2_shellcode(strSeverFile.GetString(), strSeverFile.GetString());
|
||||
if (ret)MessageBox(CString("ShellCode ת<><D7AA><EFBFBD>쳣, <20>쳣<EFBFBD><ECB3A3><EFBFBD><EFBFBD>: ") + CString(std::to_string(ret).c_str()),
|
||||
@@ -489,7 +488,7 @@ void CBuildDlg::OnMenuEncryptIp()
|
||||
if (dlg.DoModal() == IDOK ) {
|
||||
if (m_strEncryptIP != "<EFBFBD><EFBFBD>" && m_strEncryptIP != "<EFBFBD><EFBFBD>") {
|
||||
MessageBoxA("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǻ<EFBFBD><EFBFBD>߷<EFBFBD>!", "<EFBFBD><EFBFBD>ʾ", MB_ICONINFORMATION);
|
||||
}else
|
||||
} else
|
||||
m_strEncryptIP = dlg.m_str;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -847,11 +847,17 @@ void CFileManagerDlg::OnReceiveComplete()
|
||||
m_ContextObject->m_DeCompressionBuffer.GetBufferLen() - 1
|
||||
);
|
||||
} catch (CMemoryException* e) {
|
||||
Mprintf("[ERROR] CMemoryException\n");
|
||||
char err[256];
|
||||
e->GetErrorMessage(err, sizeof(err));
|
||||
Mprintf("[ERROR] CMemoryException: %s\n", err);
|
||||
} catch (CFileException* e) {
|
||||
Mprintf("[ERROR] CFileException\n");
|
||||
char err[256];
|
||||
e->GetErrorMessage(err, sizeof(err));
|
||||
Mprintf("[ERROR] CFileException: %s\n", err);
|
||||
} catch (CException* e) {
|
||||
Mprintf("[ERROR] CException\n");
|
||||
char err[256];
|
||||
e->GetErrorMessage(err, sizeof(err));
|
||||
Mprintf("[ERROR] CException: %s\n", err);
|
||||
} catch (...) {
|
||||
Mprintf("[ERROR] Other exception\n");
|
||||
}
|
||||
|
||||
@@ -451,7 +451,8 @@ void CHideScreenSpyDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
||||
case IDM_SAVEDIB:
|
||||
SaveSnapshot();
|
||||
break;
|
||||
case IDM_SAVEAVI_S: case IDM_SAVEAVI_H264: {
|
||||
case IDM_SAVEAVI_S:
|
||||
case IDM_SAVEAVI_H264: {
|
||||
if (pSysMenu->GetMenuState(IDM_SAVEAVI_S, MF_BYCOMMAND) & MF_CHECKED) {
|
||||
KillTimer(TIMER_ID);
|
||||
pSysMenu->CheckMenuItem(IDM_SAVEAVI_S, MF_UNCHECKED);
|
||||
|
||||
@@ -550,7 +550,7 @@ BOOL WriteContextData(CONTEXT_OBJECT* ContextObject, PBYTE szBuffer, size_t ulOr
|
||||
Buffer tmp(szBuffer, ulOriginalLength);
|
||||
szBuffer = tmp.Buf();
|
||||
ContextObject->Encode(szBuffer, ulOriginalLength);
|
||||
if (!m_Cctx) ContextObject->Encode(szBuffer, usingZstd);
|
||||
if (!m_Cctx) ContextObject->Encode(szBuffer, ulOriginalLength, usingZstd);
|
||||
size_t iRet = usingZstd ?
|
||||
Mcompress(CompressedBuffer, &ulCompressedLength, (LPBYTE)szBuffer, ulOriginalLength):
|
||||
compress(CompressedBuffer, &ulCompressedLength, (LPBYTE)szBuffer, ulOriginalLength);
|
||||
|
||||
@@ -200,7 +200,8 @@ void CScreenSpyDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
|
||||
CDialog::OnLButtonDblClk(nFlags, point);
|
||||
}
|
||||
|
||||
void CScreenSpyDlg::PrepareDrawing(const LPBITMAPINFO bmp) {
|
||||
void CScreenSpyDlg::PrepareDrawing(const LPBITMAPINFO bmp)
|
||||
{
|
||||
if (m_hFullDC) ::ReleaseDC(m_hWnd, m_hFullDC);
|
||||
if (m_hFullMemDC) ::DeleteDC(m_hFullMemDC);
|
||||
if (m_BitmapHandle) ::DeleteObject(m_BitmapHandle);
|
||||
@@ -560,13 +561,15 @@ VOID CScreenSpyDlg::DrawTipString(CString strString)
|
||||
SetTextColor(m_hFullDC, OldBackgroundColor);
|
||||
}
|
||||
|
||||
bool DirectoryExists(const char* path) {
|
||||
bool DirectoryExists(const char* path)
|
||||
{
|
||||
DWORD attr = GetFileAttributesA(path);
|
||||
return (attr != INVALID_FILE_ATTRIBUTES &&
|
||||
(attr & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
|
||||
std::string GetScreenShotPath(CWnd *parent, const CString& ip, const CString &filter, const CString& suffix) {
|
||||
std::string GetScreenShotPath(CWnd *parent, const CString& ip, const CString &filter, const CString& suffix)
|
||||
{
|
||||
std::string path;
|
||||
std::string folder = THIS_CFG.GetStr("settings", "ScreenShot", "");
|
||||
if (folder.empty() || !DirectoryExists(folder.c_str())) {
|
||||
@@ -580,8 +583,7 @@ std::string GetScreenShotPath(CWnd *parent, const CString& ip, const CString &fi
|
||||
}
|
||||
path = dlg.GetPathName();
|
||||
THIS_CFG.SetStr("settings", "ScreenShot", folder);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (!folder.empty() && folder.back() != '\\') {
|
||||
folder += '\\';
|
||||
}
|
||||
@@ -611,7 +613,8 @@ void CScreenSpyDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
||||
SaveSnapshot();
|
||||
break;
|
||||
}
|
||||
case IDM_SAVEAVI: case IDM_SAVEAVI_H264: {
|
||||
case IDM_SAVEAVI:
|
||||
case IDM_SAVEAVI_H264: {
|
||||
if (SysMenu->GetMenuState(nID, MF_BYCOMMAND) & MF_CHECKED) {
|
||||
KillTimer(TIMER_ID);
|
||||
SysMenu->CheckMenuItem(nID, MF_UNCHECKED);
|
||||
@@ -629,8 +632,7 @@ void CScreenSpyDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
||||
MessageBox(CString("Create Video(*.avi) Failed:\n") + m_aviFile + "\r\n错误代码: " +
|
||||
CBmpToAvi::GetErrMsg(code).c_str(), "提示");
|
||||
m_aviFile = _T("");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
::SetTimer(m_hWnd, TIMER_ID, duration, NULL);
|
||||
SysMenu->CheckMenuItem(nID, MF_CHECKED);
|
||||
SysMenu->EnableMenuItem(nID == IDM_SAVEAVI ? IDM_SAVEAVI_H264 : IDM_SAVEAVI, MF_DISABLED);
|
||||
@@ -644,7 +646,7 @@ void CScreenSpyDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
||||
break;
|
||||
}
|
||||
|
||||
case IDM_MULTITHREAD_COMPRESS:{
|
||||
case IDM_MULTITHREAD_COMPRESS: {
|
||||
static int threadNum = 0;
|
||||
threadNum = 4 - threadNum;
|
||||
BYTE bToken[2] = { CMD_MULTITHREAD_COMPRESS, (BYTE)threadNum };
|
||||
|
||||
@@ -542,9 +542,9 @@ public:
|
||||
{
|
||||
return Parser.Parse(buf, CompressMethod, PeerName);
|
||||
}
|
||||
void Encode(PBYTE data, bool &flag) const
|
||||
void Encode(PBYTE data, int len, const bool &flag) const
|
||||
{
|
||||
flag ? data[0] ^= 0x2B : 0x2B == 0x2B;
|
||||
flag ? (len > 1 ? data[1] ^= 0x2B : 0x2B == 0x2B) : 0x2B == 0x2B;
|
||||
}
|
||||
// Encode data before compress.
|
||||
void Encode(PBYTE data, int len) const
|
||||
|
||||
@@ -89,8 +89,7 @@ BOOL ServerService_CheckStatus(BOOL* registered, BOOL* running,
|
||||
SC_STATUS_PROCESS_INFO,
|
||||
(LPBYTE)&ssp,
|
||||
sizeof(SERVICE_STATUS_PROCESS),
|
||||
&bytesNeeded))
|
||||
{
|
||||
&bytesNeeded)) {
|
||||
*running = (ssp.dwCurrentState == SERVICE_RUNNING);
|
||||
}
|
||||
|
||||
@@ -406,11 +405,9 @@ BOOL ServerService_Install(void)
|
||||
CloseServiceHandle(schService);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else if (err == ERROR_ACCESS_DENIED) {
|
||||
} else if (err == ERROR_ACCESS_DENIED) {
|
||||
Mprintf("ERROR: Access denied. Please run as Administrator\n");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Mprintf("ERROR: CreateService failed (%d)\n", (int)err);
|
||||
}
|
||||
CloseServiceHandle(schSCManager);
|
||||
@@ -435,19 +432,16 @@ BOOL ServerService_Install(void)
|
||||
if (QueryServiceStatus(schService, &status)) {
|
||||
if (status.dwCurrentState == SERVICE_RUNNING) {
|
||||
Mprintf("SUCCESS: Service is running\n");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Mprintf("WARNING: Service state: %d\n", (int)status.dwCurrentState);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
err = GetLastError();
|
||||
if (err == ERROR_SERVICE_ALREADY_RUNNING) {
|
||||
Mprintf("INFO: Service is already running\n");
|
||||
err = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Mprintf("WARNING: StartService failed (%d)\n", (int)err);
|
||||
}
|
||||
}
|
||||
@@ -495,14 +489,12 @@ void ServerService_Uninstall(void)
|
||||
Mprintf(".");
|
||||
Sleep(1000);
|
||||
waitCount++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Mprintf("\n");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
DWORD err = GetLastError();
|
||||
if (err != ERROR_SERVICE_NOT_ACTIVE) {
|
||||
Mprintf("WARNING: Failed to stop service (%d)\n", (int)err);
|
||||
@@ -513,8 +505,7 @@ void ServerService_Uninstall(void)
|
||||
Mprintf("Deleting service...\n");
|
||||
if (DeleteService(schService)) {
|
||||
Mprintf("SUCCESS: Service uninstalled successfully\n");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Mprintf("ERROR: DeleteService failed (%d)\n", (int)GetLastError());
|
||||
}
|
||||
|
||||
|
||||
@@ -242,8 +242,7 @@ static void MonitorLoop(ServerSessionMonitor* self)
|
||||
ServerMonitor_WriteLog("GUI launched successfully");
|
||||
// 给程序一些时间启动
|
||||
Sleep(2000);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
ServerMonitor_WriteLog("Failed to launch GUI");
|
||||
}
|
||||
}
|
||||
@@ -258,8 +257,7 @@ static void MonitorLoop(ServerSessionMonitor* self)
|
||||
}
|
||||
|
||||
WTSFreeMemory(pSessionInfo);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (loopCount % 5 == 1) {
|
||||
ServerMonitor_WriteLog("WTSEnumerateSessions failed");
|
||||
}
|
||||
@@ -288,8 +286,7 @@ static BOOL IsGuiRunningInSession(ServerSessionMonitor* self, DWORD sessionId)
|
||||
char* pFileName = strrchr(currentExeName, '\\');
|
||||
if (pFileName) {
|
||||
pFileName++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
pFileName = currentExeName;
|
||||
}
|
||||
|
||||
@@ -359,14 +356,12 @@ static void TerminateAllGui(ServerSessionMonitor* self)
|
||||
sprintf_s(buf, sizeof(buf), "WARNING: Failed to terminate PID=%d, error=%d",
|
||||
(int)info->processId, (int)GetLastError());
|
||||
ServerMonitor_WriteLog(buf);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
ServerMonitor_WriteLog("GUI terminated successfully");
|
||||
// 等待进程完全退出
|
||||
WaitForSingleObject(info->hProcess, 5000);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sprintf_s(buf, sizeof(buf), "GUI PID=%d already exited with code %d",
|
||||
(int)info->processId, (int)exitCode);
|
||||
ServerMonitor_WriteLog(buf);
|
||||
@@ -405,8 +400,7 @@ static void CleanupDeadProcesses(ServerSessionMonitor* self)
|
||||
AgentArray_RemoveAt(&self->agentProcesses, i);
|
||||
continue; // 不增加 i,因为删除了元素
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// 无法获取退出代码,可能进程已不存在
|
||||
sprintf_s(buf, sizeof(buf), "Cannot query GUI PID=%d, removing from list",
|
||||
(int)info->processId);
|
||||
@@ -545,8 +539,7 @@ static BOOL LaunchGuiInSession(ServerSessionMonitor* self, DWORD sessionId)
|
||||
LeaveCriticalSection(&self->csProcessList);
|
||||
|
||||
CloseHandle(pi.hThread); // 线程句柄可以关闭
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
DWORD err = GetLastError();
|
||||
sprintf_s(buf, sizeof(buf), "CreateProcessAsUser failed: %d", (int)err);
|
||||
ServerMonitor_WriteLog(buf);
|
||||
@@ -554,11 +547,9 @@ static BOOL LaunchGuiInSession(ServerSessionMonitor* self, DWORD sessionId)
|
||||
// 提供更详细的错误信息
|
||||
if (err == ERROR_FILE_NOT_FOUND) {
|
||||
ServerMonitor_WriteLog("ERROR: Executable not found");
|
||||
}
|
||||
else if (err == ERROR_ACCESS_DENIED) {
|
||||
} else if (err == ERROR_ACCESS_DENIED) {
|
||||
ServerMonitor_WriteLog("ERROR: Access denied - service may not have sufficient privileges");
|
||||
}
|
||||
else if (err == 1314) {
|
||||
} else if (err == 1314) {
|
||||
ServerMonitor_WriteLog("ERROR: Service does not have SE_INCREASE_QUOTA privilege");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +46,7 @@ BOOL CSplashDlg::Create(CWnd* pParent)
|
||||
|
||||
if (!CreateEx(dwExStyle, strClassName, _T(""), dwStyle,
|
||||
x, y, SPLASH_WIDTH, SPLASH_HEIGHT,
|
||||
pParent ? pParent->GetSafeHwnd() : NULL, NULL))
|
||||
{
|
||||
pParent ? pParent->GetSafeHwnd() : NULL, NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -79,16 +78,14 @@ void CSplashDlg::SetProgress(int nPercent)
|
||||
if (nPercent < 0) nPercent = 0;
|
||||
if (nPercent > 100) nPercent = 100;
|
||||
|
||||
if (GetSafeHwnd())
|
||||
{
|
||||
if (GetSafeHwnd()) {
|
||||
PostMessage(WM_SPLASH_PROGRESS, nPercent, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void CSplashDlg::SetStatusText(const CString& strText)
|
||||
{
|
||||
if (GetSafeHwnd())
|
||||
{
|
||||
if (GetSafeHwnd()) {
|
||||
CString* pText = new CString(strText);
|
||||
PostMessage(WM_SPLASH_STATUS, (WPARAM)pText, 0);
|
||||
}
|
||||
@@ -102,15 +99,13 @@ void CSplashDlg::UpdateProgressDirect(int nPercent, const CString& strText)
|
||||
m_nProgress = nPercent;
|
||||
m_strStatus = strText;
|
||||
|
||||
if (GetSafeHwnd())
|
||||
{
|
||||
if (GetSafeHwnd()) {
|
||||
InvalidateRect(NULL, FALSE);
|
||||
UpdateWindow();
|
||||
|
||||
// 处理待处理的消息,确保界面响应
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
@@ -119,8 +114,7 @@ void CSplashDlg::UpdateProgressDirect(int nPercent, const CString& strText)
|
||||
|
||||
void CSplashDlg::Close()
|
||||
{
|
||||
if (GetSafeHwnd())
|
||||
{
|
||||
if (GetSafeHwnd()) {
|
||||
PostMessage(WM_SPLASH_CLOSE, 0, 0);
|
||||
}
|
||||
}
|
||||
@@ -136,8 +130,7 @@ LRESULT CSplashDlg::OnUpdateProgress(WPARAM wParam, LPARAM lParam)
|
||||
LRESULT CSplashDlg::OnUpdateStatus(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
CString* pText = (CString*)wParam;
|
||||
if (pText)
|
||||
{
|
||||
if (pText) {
|
||||
m_strStatus = *pText;
|
||||
delete pText;
|
||||
InvalidateRect(NULL, FALSE);
|
||||
@@ -167,8 +160,7 @@ void CSplashDlg::OnPaint()
|
||||
CBitmap* pOldBitmap = memDC.SelectObject(&memBitmap);
|
||||
|
||||
// 绘制背景 - 渐变效果
|
||||
for (int y = 0; y < rect.Height(); y++)
|
||||
{
|
||||
for (int y = 0; y < rect.Height(); y++) {
|
||||
int r = 45 + (y * 20 / rect.Height());
|
||||
int g = 45 + (y * 20 / rect.Height());
|
||||
int b = 55 + (y * 25 / rect.Height());
|
||||
@@ -187,8 +179,7 @@ void CSplashDlg::OnPaint()
|
||||
memDC.SelectObject(pOldPen);
|
||||
|
||||
// 绘制图标
|
||||
if (m_hIcon)
|
||||
{
|
||||
if (m_hIcon) {
|
||||
DrawIconEx(memDC.GetSafeHdc(), 30, 30, m_hIcon, 48, 48, 0, NULL, DI_NORMAL);
|
||||
}
|
||||
|
||||
@@ -243,15 +234,13 @@ void CSplashDlg::DrawProgressBar(CDC* pDC, const CRect& rect)
|
||||
pDC->SelectObject(pOldPen);
|
||||
|
||||
// 计算进度条填充区域
|
||||
if (m_nProgress > 0)
|
||||
{
|
||||
if (m_nProgress > 0) {
|
||||
CRect fillRect = rect;
|
||||
fillRect.DeflateRect(2, 2);
|
||||
fillRect.right = fillRect.left + (fillRect.Width() * m_nProgress / 100);
|
||||
|
||||
// 渐变填充
|
||||
for (int x = fillRect.left; x < fillRect.right; x++)
|
||||
{
|
||||
for (int x = fillRect.left; x < fillRect.right; x++) {
|
||||
float ratio = (float)(x - fillRect.left) / (float)fillRect.Width();
|
||||
int r = (int)(50 + ratio * 50);
|
||||
int g = (int)(150 + ratio * 50);
|
||||
|
||||
@@ -12,77 +12,78 @@
|
||||
#define MASK_TO_DWORD(val) ((val < MAX_DWORD) ? (val & MAX_DWORD) : MAX_DWORD)
|
||||
#define MASK_TO_WORD(val) ((val < MAX_WORD) ? (val & MAX_WORD) : MAX_WORD)
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
Validates pointers, checks if the particular field is inside the given buffer. Sizes must be given in bytes.
|
||||
\param buffer_bgn : the start address of the buffer
|
||||
\param buffer_size : the size of the buffer
|
||||
\param field_bgn : the start address of the field
|
||||
\param field_size : the size of the field
|
||||
\return true if the field (defined by its start address: field_bgn, and size: field_size) is contained within the given buffer
|
||||
(defined by its start address: buffer_bgn, and size: buffer_size).
|
||||
false otherwise
|
||||
*/
|
||||
bool validate_ptr(
|
||||
/**
|
||||
Validates pointers, checks if the particular field is inside the given buffer. Sizes must be given in bytes.
|
||||
\param buffer_bgn : the start address of the buffer
|
||||
\param buffer_size : the size of the buffer
|
||||
\param field_bgn : the start address of the field
|
||||
\param field_size : the size of the field
|
||||
\return true if the field (defined by its start address: field_bgn, and size: field_size) is contained within the given buffer
|
||||
(defined by its start address: buffer_bgn, and size: buffer_size).
|
||||
false otherwise
|
||||
*/
|
||||
bool validate_ptr(
|
||||
IN const void* buffer_bgn,
|
||||
IN size_t buffer_size,
|
||||
IN const void* field_bgn,
|
||||
IN size_t field_size
|
||||
);
|
||||
);
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// supported buffers:
|
||||
//
|
||||
/**
|
||||
A buffer allocated on the heap of a process, not aligned to the beginning of a memory page.
|
||||
*/
|
||||
typedef PBYTE UNALIGNED_BUF;
|
||||
/**
|
||||
A buffer allocated on the heap of a process, not aligned to the beginning of a memory page.
|
||||
*/
|
||||
typedef PBYTE UNALIGNED_BUF;
|
||||
|
||||
/**
|
||||
A buffer allocated in a virtual space of a process, aligned to the beginning of a memory page.
|
||||
*/
|
||||
typedef PBYTE ALIGNED_BUF;
|
||||
/**
|
||||
A buffer allocated in a virtual space of a process, aligned to the beginning of a memory page.
|
||||
*/
|
||||
typedef PBYTE ALIGNED_BUF;
|
||||
|
||||
//
|
||||
// alloc/free unaligned buffers:
|
||||
//
|
||||
/**
|
||||
Allocates a buffer on the heap. Can be used in the cases when the buffer does not have to start at the beginning of a page.
|
||||
*/
|
||||
UNALIGNED_BUF alloc_unaligned(size_t buf_size);
|
||||
/**
|
||||
Allocates a buffer on the heap. Can be used in the cases when the buffer does not have to start at the beginning of a page.
|
||||
*/
|
||||
UNALIGNED_BUF alloc_unaligned(size_t buf_size);
|
||||
|
||||
//
|
||||
/**
|
||||
Frees buffer allocated by alloc_unaligned.
|
||||
*/
|
||||
void free_unaligned(UNALIGNED_BUF section_buffer);
|
||||
//
|
||||
/**
|
||||
Frees buffer allocated by alloc_unaligned.
|
||||
*/
|
||||
void free_unaligned(UNALIGNED_BUF section_buffer);
|
||||
|
||||
//
|
||||
// alloc/free aligned buffers:
|
||||
//
|
||||
|
||||
/**
|
||||
Allocates a buffer of a virtual memory (using VirtualAlloc). Can be used in the cases when the buffer have to be aligned to the beginning of a page.
|
||||
*/
|
||||
ALIGNED_BUF alloc_aligned(size_t buffer_size, DWORD protect, void* desired_base=nullptr);
|
||||
/**
|
||||
Allocates a buffer of a virtual memory (using VirtualAlloc). Can be used in the cases when the buffer have to be aligned to the beginning of a page.
|
||||
*/
|
||||
ALIGNED_BUF alloc_aligned(size_t buffer_size, DWORD protect, void* desired_base=nullptr);
|
||||
|
||||
/**
|
||||
Frees buffer allocated by alloc_aligned.
|
||||
*/
|
||||
bool free_aligned(ALIGNED_BUF buffer, size_t buffer_size=0);
|
||||
/**
|
||||
Frees buffer allocated by alloc_aligned.
|
||||
*/
|
||||
bool free_aligned(ALIGNED_BUF buffer, size_t buffer_size=0);
|
||||
|
||||
//PE buffers (wrappers)
|
||||
//PE buffers (wrappers)
|
||||
|
||||
/**
|
||||
Allocates an aligned buffer for a PE file.
|
||||
*/
|
||||
ALIGNED_BUF alloc_pe_buffer(size_t buffer_size, DWORD protect, void* desired_base=nullptr);
|
||||
/**
|
||||
Allocates an aligned buffer for a PE file.
|
||||
*/
|
||||
ALIGNED_BUF alloc_pe_buffer(size_t buffer_size, DWORD protect, void* desired_base=nullptr);
|
||||
|
||||
/**
|
||||
Free the memory allocated with alloc_pe_buffer.
|
||||
*/
|
||||
bool free_pe_buffer(ALIGNED_BUF buffer, size_t buffer_size=0);
|
||||
/**
|
||||
Free the memory allocated with alloc_pe_buffer.
|
||||
*/
|
||||
bool free_pe_buffer(ALIGNED_BUF buffer, size_t buffer_size=0);
|
||||
|
||||
}; //namespace peconv
|
||||
|
||||
@@ -7,21 +7,22 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
Finds cave at the end of the image (extend last section's raw size without extending the full image size)
|
||||
*/
|
||||
PBYTE find_ending_cave(BYTE* module_ptr, size_t module_size, const DWORD cave_size, const DWORD cave_charact=IMAGE_SCN_MEM_READ);
|
||||
/**
|
||||
Finds cave at the end of the image (extend last section's raw size without extending the full image size)
|
||||
*/
|
||||
PBYTE find_ending_cave(BYTE* module_ptr, size_t module_size, const DWORD cave_size, const DWORD cave_charact=IMAGE_SCN_MEM_READ);
|
||||
|
||||
/**
|
||||
Finds cave in the difference between the original raw size, and the raw size rounded to the aligmnent
|
||||
*/
|
||||
PBYTE find_alignment_cave(BYTE* modulePtr, size_t moduleSize, const DWORD cave_size, const DWORD req_charact = IMAGE_SCN_MEM_READ);
|
||||
/**
|
||||
Finds cave in the difference between the original raw size, and the raw size rounded to the aligmnent
|
||||
*/
|
||||
PBYTE find_alignment_cave(BYTE* modulePtr, size_t moduleSize, const DWORD cave_size, const DWORD req_charact = IMAGE_SCN_MEM_READ);
|
||||
|
||||
/**
|
||||
Finds cave at the end of the section, that comes from a NULL padding or INT3 padding
|
||||
*/
|
||||
PBYTE find_padding_cave(BYTE* modulePtr, size_t moduleSize, const size_t minimal_size, const DWORD req_charact = IMAGE_SCN_MEM_READ);
|
||||
/**
|
||||
Finds cave at the end of the section, that comes from a NULL padding or INT3 padding
|
||||
*/
|
||||
PBYTE find_padding_cave(BYTE* modulePtr, size_t moduleSize, const size_t minimal_size, const DWORD req_charact = IMAGE_SCN_MEM_READ);
|
||||
|
||||
};//namespace peconv
|
||||
|
||||
@@ -42,20 +42,21 @@ typedef const IMAGE_DELAYLOAD_DESCRIPTOR *PCIMAGE_DELAYLOAD_DESCRIPTOR;
|
||||
#include "poppack.h"
|
||||
#endif
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
Get the Delayload Imports directory. Returns the pointer to the first descriptor. The size of the directory is passed via variable dir_size.
|
||||
*/
|
||||
IMAGE_DELAYLOAD_DESCRIPTOR* get_delayed_imps(IN const BYTE* modulePtr, IN const size_t moduleSize, OUT size_t &dir_size);
|
||||
/**
|
||||
Get the Delayload Imports directory. Returns the pointer to the first descriptor. The size of the directory is passed via variable dir_size.
|
||||
*/
|
||||
IMAGE_DELAYLOAD_DESCRIPTOR* get_delayed_imps(IN const BYTE* modulePtr, IN const size_t moduleSize, OUT size_t &dir_size);
|
||||
|
||||
/**
|
||||
Fill the Delayload Imports in the given module.
|
||||
\param modulePtr : the pointer to the module where the imports needs to be filled.
|
||||
\param moduleBase : the base to which the module was relocated, it may (or not) be the same as modulePtr
|
||||
\param func_resolver : the resolver that will be used for loading the imports
|
||||
\return : true if resolving all succeeded, false otherwise
|
||||
*/
|
||||
bool load_delayed_imports(BYTE* modulePtr, const ULONGLONG moduleBase, t_function_resolver* func_resolver = nullptr);
|
||||
/**
|
||||
Fill the Delayload Imports in the given module.
|
||||
\param modulePtr : the pointer to the module where the imports needs to be filled.
|
||||
\param moduleBase : the base to which the module was relocated, it may (or not) be the same as modulePtr
|
||||
\param func_resolver : the resolver that will be used for loading the imports
|
||||
\return : true if resolving all succeeded, false otherwise
|
||||
*/
|
||||
bool load_delayed_imports(BYTE* modulePtr, const ULONGLONG moduleBase, t_function_resolver* func_resolver = nullptr);
|
||||
|
||||
}; // namespace peconv
|
||||
|
||||
@@ -7,15 +7,16 @@
|
||||
|
||||
#include "peconv/buffer_util.h"
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
Allows to activate the Exception table from the manually loaded module.
|
||||
For 32-bits the loaded image should enable /SAFESEH linker option,
|
||||
otherwise the exception handler cannot pass the RtlIsValidHandler() check
|
||||
when an exception occurs
|
||||
*/
|
||||
bool setup_exceptions(IN BYTE* modulePtr, IN size_t moduleSize);
|
||||
/**
|
||||
Allows to activate the Exception table from the manually loaded module.
|
||||
For 32-bits the loaded image should enable /SAFESEH linker option,
|
||||
otherwise the exception handler cannot pass the RtlIsValidHandler() check
|
||||
when an exception occurs
|
||||
*/
|
||||
bool setup_exceptions(IN BYTE* modulePtr, IN size_t moduleSize);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -10,49 +10,50 @@
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
Check if the pointer redirects to a forwarder - if so, return the length, otherwise return 0.
|
||||
*/
|
||||
size_t forwarder_name_len(BYTE* fPtr);
|
||||
/**
|
||||
Check if the pointer redirects to a forwarder - if so, return the length, otherwise return 0.
|
||||
*/
|
||||
size_t forwarder_name_len(BYTE* fPtr);
|
||||
|
||||
/**
|
||||
get the DLL name without the extension
|
||||
*/
|
||||
std::string get_dll_shortname(const std::string& str);
|
||||
/**
|
||||
get the DLL name without the extension
|
||||
*/
|
||||
std::string get_dll_shortname(const std::string& str);
|
||||
|
||||
/**
|
||||
Get the function name from the string in a format: DLL_name.function_name
|
||||
*/
|
||||
std::string get_func_name(const std::string& str);
|
||||
/**
|
||||
Get the function name from the string in a format: DLL_name.function_name
|
||||
*/
|
||||
std::string get_func_name(const std::string& str);
|
||||
|
||||
/**
|
||||
Convert ordinal value to the ordinal string (in a format #[ordinal])
|
||||
*/
|
||||
std::string ordinal_to_string(DWORD func_ordinal);
|
||||
/**
|
||||
Convert ordinal value to the ordinal string (in a format #[ordinal])
|
||||
*/
|
||||
std::string ordinal_to_string(DWORD func_ordinal);
|
||||
|
||||
/**
|
||||
Check if the given string is in a format typical for storing ordinals (#[ordinal])
|
||||
*/
|
||||
bool is_ordinal_string(const std::string& str);
|
||||
/**
|
||||
Check if the given string is in a format typical for storing ordinals (#[ordinal])
|
||||
*/
|
||||
bool is_ordinal_string(const std::string& str);
|
||||
|
||||
/**
|
||||
Get the ordinal value from the ordinal string (in a format #[ordinal])
|
||||
*/
|
||||
DWORD ordinal_string_to_val(const std::string& str);
|
||||
/**
|
||||
Get the ordinal value from the ordinal string (in a format #[ordinal])
|
||||
*/
|
||||
DWORD ordinal_string_to_val(const std::string& str);
|
||||
|
||||
/**
|
||||
Convert the function in a format: DLL_name.function_name into a normalized form (DLL name in lowercase).
|
||||
*/
|
||||
std::string format_dll_func(const std::string& str);
|
||||
/**
|
||||
Convert the function in a format: DLL_name.function_name into a normalized form (DLL name in lowercase).
|
||||
*/
|
||||
std::string format_dll_func(const std::string& str);
|
||||
|
||||
/**
|
||||
A class storing the information about the exported function.
|
||||
*/
|
||||
class ExportedFunc
|
||||
{
|
||||
public:
|
||||
/**
|
||||
A class storing the information about the exported function.
|
||||
*/
|
||||
class ExportedFunc
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Converts the name to the normalized format.
|
||||
*/
|
||||
@@ -126,7 +127,7 @@ namespace peconv {
|
||||
{
|
||||
return (funcName != "" || funcOrdinal != -1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}; //namespace peconv
|
||||
|
||||
|
||||
@@ -14,24 +14,26 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
Gets the function address by the name. Uses Export Table lookup.
|
||||
WARNING: doesn't work for the forwarded functions.
|
||||
*/
|
||||
FARPROC get_exported_func(PVOID modulePtr, LPCSTR wanted_name);
|
||||
/**
|
||||
Gets the function address by the name. Uses Export Table lookup.
|
||||
WARNING: doesn't work for the forwarded functions.
|
||||
*/
|
||||
FARPROC get_exported_func(PVOID modulePtr, LPCSTR wanted_name);
|
||||
|
||||
/**
|
||||
Gets list of all the functions from a given module that are exported by names.
|
||||
*/
|
||||
size_t get_exported_names(PVOID modulePtr, std::vector<std::string> &names_list);
|
||||
/**
|
||||
Gets list of all the functions from a given module that are exported by names.
|
||||
*/
|
||||
size_t get_exported_names(PVOID modulePtr, std::vector<std::string> &names_list);
|
||||
|
||||
/**
|
||||
Function resolver using Export Table lookup.
|
||||
*/
|
||||
class export_based_resolver : default_func_resolver {
|
||||
public:
|
||||
/**
|
||||
Function resolver using Export Table lookup.
|
||||
*/
|
||||
class export_based_resolver : default_func_resolver
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Get the address (VA) of the function with the given name, from the given DLL.
|
||||
Uses Export Table lookup as a primary method of finding the import. On failure it falls back to the default Functions Resolver.
|
||||
@@ -40,11 +42,11 @@ namespace peconv {
|
||||
\return Virtual Address of the exported function
|
||||
*/
|
||||
virtual FARPROC resolve_func(LPCSTR lib_name, LPCSTR func_name);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
Read the DLL name from the Export Table.
|
||||
*/
|
||||
LPSTR read_dll_name(HMODULE modulePtr);
|
||||
/**
|
||||
Read the DLL name from the Export Table.
|
||||
*/
|
||||
LPSTR read_dll_name(HMODULE modulePtr);
|
||||
|
||||
}; //namespace peconv
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
#include "peconv/exported_func.h"
|
||||
#include "peconv/file_util.h"
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
struct DllInfo {
|
||||
struct DllInfo {
|
||||
DllInfo()
|
||||
: moduleBase(0), moduelSize(0), is64b(false)
|
||||
{
|
||||
@@ -48,7 +49,7 @@ namespace peconv {
|
||||
return this->moduleBase < other.moduleBase;
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
ULONGLONG moduleBase;
|
||||
size_t moduelSize;
|
||||
std::string moduleName;
|
||||
@@ -56,11 +57,12 @@ namespace peconv {
|
||||
bool is64b;
|
||||
|
||||
friend class ExportsMapper;
|
||||
};
|
||||
};
|
||||
|
||||
class ExportsMapper {
|
||||
class ExportsMapper
|
||||
{
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
/**
|
||||
Appends the given DLL to the lookup table of exported functions. Returns the number of functions exported from this DLL (not forwarded).
|
||||
@@ -178,7 +180,7 @@ namespace peconv {
|
||||
void print_func_to_va(std::stringstream &stream) const;
|
||||
|
||||
|
||||
private:
|
||||
private:
|
||||
enum ADD_FUNC_RES { RES_INVALID = 0, RES_MAPPED = 1, RES_FORWARDED = 2 };
|
||||
ADD_FUNC_RES add_function_to_lookup(HMODULE modulePtr, ULONGLONG moduleBase, size_t moduleSize, ExportedFunc &currFunc, DWORD callRVA);
|
||||
|
||||
@@ -188,7 +190,7 @@ namespace peconv {
|
||||
size_t resolve_forwarders(const ULONGLONG va, ExportedFunc &currFunc);
|
||||
size_t make_ord_lookup_tables(PVOID modulePtr, size_t moduleSize, std::map<PDWORD, DWORD> &va_to_ord);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
/**
|
||||
Add a function and a VA into a mutual mapping.
|
||||
*/
|
||||
@@ -219,6 +221,6 @@ namespace peconv {
|
||||
std::map<std::string, std::set<ULONGLONG>> dll_shortname_to_base;
|
||||
|
||||
std::map<ULONGLONG, DllInfo> dll_base_to_info;
|
||||
};
|
||||
};
|
||||
|
||||
}; //namespace peconv
|
||||
|
||||
@@ -10,51 +10,52 @@
|
||||
|
||||
#include "buffer_util.h"
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
Maps a file with the given path and copies its raw content into the output buffer.
|
||||
If read_size is not zero, it reads maximum read_size of bytes. If read_size is zero, it reads the full file.
|
||||
The actual read size is returned back in read_size.
|
||||
Automatically allocates a buffer of the required size.
|
||||
*/
|
||||
peconv::UNALIGNED_BUF load_file(IN LPCTSTR filename, OUT size_t &r_size);
|
||||
/**
|
||||
Maps a file with the given path and copies its raw content into the output buffer.
|
||||
If read_size is not zero, it reads maximum read_size of bytes. If read_size is zero, it reads the full file.
|
||||
The actual read size is returned back in read_size.
|
||||
Automatically allocates a buffer of the required size.
|
||||
*/
|
||||
peconv::UNALIGNED_BUF load_file(IN LPCTSTR filename, OUT size_t &r_size);
|
||||
|
||||
/**
|
||||
Reads a raw content of the file with the given path.
|
||||
If read_size is not zero, it reads maximum read_size of bytes. If read_size is zero, it reads the full file.
|
||||
The actual read size is returned back in read_size.
|
||||
Automatically allocates a buffer of the required size.
|
||||
*/
|
||||
peconv::UNALIGNED_BUF read_from_file(IN LPCTSTR path, IN OUT size_t &read_size);
|
||||
/**
|
||||
Reads a raw content of the file with the given path.
|
||||
If read_size is not zero, it reads maximum read_size of bytes. If read_size is zero, it reads the full file.
|
||||
The actual read size is returned back in read_size.
|
||||
Automatically allocates a buffer of the required size.
|
||||
*/
|
||||
peconv::UNALIGNED_BUF read_from_file(IN LPCTSTR path, IN OUT size_t &read_size);
|
||||
|
||||
/**
|
||||
Writes a buffer of bytes into a file of given path.
|
||||
\param path : the path to the output file
|
||||
\param dump_data : the buffer to be dumped
|
||||
\param dump_size : the size of data to be dumped (in bytes)
|
||||
\return true if succeeded, false if failed
|
||||
*/
|
||||
bool dump_to_file(IN LPCTSTR path, IN PBYTE dump_data, IN size_t dump_size);
|
||||
/**
|
||||
Writes a buffer of bytes into a file of given path.
|
||||
\param path : the path to the output file
|
||||
\param dump_data : the buffer to be dumped
|
||||
\param dump_size : the size of data to be dumped (in bytes)
|
||||
\return true if succeeded, false if failed
|
||||
*/
|
||||
bool dump_to_file(IN LPCTSTR path, IN PBYTE dump_data, IN size_t dump_size);
|
||||
|
||||
/**
|
||||
Free the buffer allocated by load_file/read_from_file
|
||||
*/
|
||||
void free_file(IN peconv::UNALIGNED_BUF buffer);
|
||||
/**
|
||||
Free the buffer allocated by load_file/read_from_file
|
||||
*/
|
||||
void free_file(IN peconv::UNALIGNED_BUF buffer);
|
||||
|
||||
/**
|
||||
Get the file name from the given path.
|
||||
*/
|
||||
std::string get_file_name(IN const std::string full_path);
|
||||
/**
|
||||
Get the file name from the given path.
|
||||
*/
|
||||
std::string get_file_name(IN const std::string full_path);
|
||||
|
||||
/**
|
||||
Get the directory name from the given path. It assumes that a directory name always ends with a separator ("/" or "\")
|
||||
*/
|
||||
std::string get_directory_name(IN const std::string full_path);
|
||||
/**
|
||||
Get the directory name from the given path. It assumes that a directory name always ends with a separator ("/" or "\")
|
||||
*/
|
||||
std::string get_directory_name(IN const std::string full_path);
|
||||
|
||||
/**
|
||||
Find a position of possible file extension. If not found, gives string length.
|
||||
*/
|
||||
size_t find_extension_pos(IN const std::string str);
|
||||
/**
|
||||
Find a position of possible file extension. If not found, gives string length.
|
||||
*/
|
||||
size_t find_extension_pos(IN const std::string str);
|
||||
|
||||
}; //namespace peconv
|
||||
|
||||
@@ -7,14 +7,15 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
Try to find a base to which the PE file was relocated, basing on the filled relocations.
|
||||
WARNING: the found base is an estimate, and sometimes may not be fully accurate.
|
||||
\param module_ptr : the module which's base is being searched
|
||||
\param module_size : the size of the given module
|
||||
\return the base to which the module was relocated
|
||||
*/
|
||||
ULONGLONG find_base_candidate(IN BYTE *module_ptr, IN size_t module_size);
|
||||
/**
|
||||
Try to find a base to which the PE file was relocated, basing on the filled relocations.
|
||||
WARNING: the found base is an estimate, and sometimes may not be fully accurate.
|
||||
\param module_ptr : the module which's base is being searched
|
||||
\param module_size : the size of the given module
|
||||
\return the base to which the module was relocated
|
||||
*/
|
||||
ULONGLONG find_base_candidate(IN BYTE *module_ptr, IN size_t module_size);
|
||||
};
|
||||
|
||||
@@ -20,38 +20,42 @@
|
||||
|
||||
#define MIN_DLL_LEN 5
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
a helper class that allows to store information about functions that could not be covered by the given mapping
|
||||
*/
|
||||
class ImpsNotCovered
|
||||
{
|
||||
public:
|
||||
/**
|
||||
a helper class that allows to store information about functions that could not be covered by the given mapping
|
||||
*/
|
||||
class ImpsNotCovered
|
||||
{
|
||||
public:
|
||||
ImpsNotCovered() {}
|
||||
~ImpsNotCovered() {}
|
||||
|
||||
/*
|
||||
Number of stored records
|
||||
*/
|
||||
size_t count() { return thunkToAddr.size(); }
|
||||
size_t count()
|
||||
{
|
||||
return thunkToAddr.size();
|
||||
}
|
||||
|
||||
void insert(DWORD thunkRVA, ULONGLONG searchedAddr);
|
||||
|
||||
std::map<DWORD, ULONGLONG> thunkToAddr; //addresses of not recovered functions with their thunks (call_via)
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
fix imports in the given module, using the given map of all available exports
|
||||
*/
|
||||
bool fix_imports(IN OUT PVOID modulePtr, IN size_t moduleSize, IN const peconv::ExportsMapper& exportsMap, OUT OPTIONAL peconv::ImpsNotCovered* notCovered);
|
||||
/**
|
||||
fix imports in the given module, using the given map of all available exports
|
||||
*/
|
||||
bool fix_imports(IN OUT PVOID modulePtr, IN size_t moduleSize, IN const peconv::ExportsMapper& exportsMap, OUT OPTIONAL peconv::ImpsNotCovered* notCovered);
|
||||
|
||||
/**
|
||||
a helper class that allows to find out where the functions are imported from
|
||||
*/
|
||||
class ImportedDllCoverage
|
||||
{
|
||||
public:
|
||||
/**
|
||||
a helper class that allows to find out where the functions are imported from
|
||||
*/
|
||||
class ImportedDllCoverage
|
||||
{
|
||||
public:
|
||||
/**
|
||||
A constructor of an object of ImportedDllCoverage class.
|
||||
\param _addresses : the list of filled imports (VAs): the addresses to be covered
|
||||
@@ -82,7 +86,10 @@ namespace peconv {
|
||||
Check if the functions mapping is complete.
|
||||
\return the status: true if all the addresses are mapped to specific exports, false if not
|
||||
*/
|
||||
bool isMappingComplete() { return (addresses.size() == addrToFunc.size()) ? true : false; }
|
||||
bool isMappingComplete()
|
||||
{
|
||||
return (addresses.size() == addrToFunc.size()) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
A mapping associating each of the covered function addresses with the set of exports (from mapped DLL) that cover this address
|
||||
@@ -99,7 +106,7 @@ namespace peconv {
|
||||
*/
|
||||
std::string dllName;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
/**
|
||||
A name of the DLL that was used for mapping. In a typical scenario it will be the same as covering DLL, but may be set different.
|
||||
*/
|
||||
@@ -115,5 +122,5 @@ namespace peconv {
|
||||
A supplied exportsMap. Only used as a lookup, no changes applied.
|
||||
*/
|
||||
const peconv::ExportsMapper& exportsMap;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -9,12 +9,14 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace peconv {
|
||||
/**
|
||||
A base class for functions resolver.
|
||||
*/
|
||||
class t_function_resolver {
|
||||
public:
|
||||
namespace peconv
|
||||
{
|
||||
/**
|
||||
A base class for functions resolver.
|
||||
*/
|
||||
class t_function_resolver
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Get the address (VA) of the function with the given name, from the given DLL.
|
||||
\param func_name : the name of the function
|
||||
@@ -22,13 +24,14 @@ namespace peconv {
|
||||
\return Virtual Address of the exported function
|
||||
*/
|
||||
virtual FARPROC resolve_func(LPCSTR lib_name, LPCSTR func_name) = 0;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
A default functions resolver, using LoadLibraryA and GetProcAddress.
|
||||
*/
|
||||
class default_func_resolver : t_function_resolver {
|
||||
public:
|
||||
/**
|
||||
A default functions resolver, using LoadLibraryA and GetProcAddress.
|
||||
*/
|
||||
class default_func_resolver : t_function_resolver
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Get the address (VA) of the function with the given name, from the given DLL, using LoadLibraryA and GetProcAddress.
|
||||
\param func_name : the name of the function
|
||||
@@ -45,6 +48,6 @@ namespace peconv {
|
||||
virtual HMODULE load_library(LPCSTR lib_name);
|
||||
|
||||
std::map<std::string, HMODULE> nameToModule;
|
||||
};
|
||||
};
|
||||
|
||||
}; //namespace peconv
|
||||
|
||||
@@ -13,13 +13,15 @@
|
||||
#include <map>
|
||||
#include "peconv/buffer_util.h"
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
A buffer storing a binary patch, that can be applied on a module. Used as a restorable backup in case of function patching.
|
||||
*/
|
||||
class PatchBackup {
|
||||
public:
|
||||
/**
|
||||
A buffer storing a binary patch, that can be applied on a module. Used as a restorable backup in case of function patching.
|
||||
*/
|
||||
class PatchBackup
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Creates an empty backup.
|
||||
*/
|
||||
@@ -28,7 +30,8 @@ namespace peconv {
|
||||
{
|
||||
}
|
||||
|
||||
~PatchBackup() {
|
||||
~PatchBackup()
|
||||
{
|
||||
deleteBackup();
|
||||
}
|
||||
|
||||
@@ -62,19 +65,20 @@ namespace peconv {
|
||||
return buffer != nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
BYTE *buffer;
|
||||
size_t bufferSize;
|
||||
|
||||
BYTE *sourcePtr;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
A functions resolver that can be used for hooking IAT. Allows for defining functions that are supposed to be replaced.
|
||||
*/
|
||||
class hooking_func_resolver : peconv::default_func_resolver {
|
||||
public:
|
||||
/**
|
||||
A functions resolver that can be used for hooking IAT. Allows for defining functions that are supposed to be replaced.
|
||||
*/
|
||||
class hooking_func_resolver : peconv::default_func_resolver
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Define a function that will be replaced.
|
||||
\param name : a name of the function that will be replaced
|
||||
@@ -103,44 +107,44 @@ namespace peconv {
|
||||
*/
|
||||
virtual FARPROC resolve_func(LPCSTR lib_name, LPCSTR func_name);
|
||||
|
||||
private:
|
||||
private:
|
||||
std::map<std::string, FARPROC> hooks_map;
|
||||
std::map<std::string, std::string> dll_replacements_map;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
Installs inline hook at the given ptr. Returns the number of bytes overwriten.
|
||||
64 bit version.
|
||||
\param ptr : pointer to the function to be replaced
|
||||
\param new_offset : VA of the new function
|
||||
\param backup : (optional) backup that can be used to reverse the changes
|
||||
\return size of the applied patch
|
||||
*/
|
||||
size_t redirect_to_local64(void *ptr, ULONGLONG new_offset, PatchBackup* backup = nullptr);
|
||||
/**
|
||||
Installs inline hook at the given ptr. Returns the number of bytes overwriten.
|
||||
64 bit version.
|
||||
\param ptr : pointer to the function to be replaced
|
||||
\param new_offset : VA of the new function
|
||||
\param backup : (optional) backup that can be used to reverse the changes
|
||||
\return size of the applied patch
|
||||
*/
|
||||
size_t redirect_to_local64(void *ptr, ULONGLONG new_offset, PatchBackup* backup = nullptr);
|
||||
|
||||
/**
|
||||
Installs inline hook at the given ptr. Returns the number of bytes overwriten.
|
||||
32 bit version.
|
||||
\param ptr : pointer to the function to be replaced
|
||||
\param new_offset : VA of the new function
|
||||
\param backup : (optional) backup that can be used to reverse the changes
|
||||
\return size of the applied patch
|
||||
*/
|
||||
size_t redirect_to_local32(void *ptr, DWORD new_offset, PatchBackup* backup = nullptr);
|
||||
/**
|
||||
Installs inline hook at the given ptr. Returns the number of bytes overwriten.
|
||||
32 bit version.
|
||||
\param ptr : pointer to the function to be replaced
|
||||
\param new_offset : VA of the new function
|
||||
\param backup : (optional) backup that can be used to reverse the changes
|
||||
\return size of the applied patch
|
||||
*/
|
||||
size_t redirect_to_local32(void *ptr, DWORD new_offset, PatchBackup* backup = nullptr);
|
||||
|
||||
/**
|
||||
Installs inline hook at the given ptr. Returns the number of bytes overwriten.
|
||||
Uses bitness of the current applications for the bitness of the intalled hook.
|
||||
\param ptr : pointer to the function to be replaced
|
||||
\param new_function_ptr : pointer to the new function
|
||||
\param backup : (optional) backup that can be used to reverse the changes
|
||||
\return size of the applied patch
|
||||
*/
|
||||
size_t redirect_to_local(void *ptr, void* new_function_ptr, PatchBackup* backup = nullptr);
|
||||
/**
|
||||
Installs inline hook at the given ptr. Returns the number of bytes overwriten.
|
||||
Uses bitness of the current applications for the bitness of the intalled hook.
|
||||
\param ptr : pointer to the function to be replaced
|
||||
\param new_function_ptr : pointer to the new function
|
||||
\param backup : (optional) backup that can be used to reverse the changes
|
||||
\return size of the applied patch
|
||||
*/
|
||||
size_t redirect_to_local(void *ptr, void* new_function_ptr, PatchBackup* backup = nullptr);
|
||||
|
||||
/**
|
||||
Replaces a target address of JMP [DWORD] or CALL [DWORD]
|
||||
*/
|
||||
bool replace_target(BYTE *ptr, ULONGLONG dest_addr);
|
||||
/**
|
||||
Replaces a target address of JMP [DWORD] or CALL [DWORD]
|
||||
*/
|
||||
bool replace_target(BYTE *ptr, ULONGLONG dest_addr);
|
||||
|
||||
};//namespace peconv
|
||||
|
||||
@@ -12,14 +12,15 @@
|
||||
#include "function_resolver.h"
|
||||
#include "exports_mapper.h"
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
A class defining a callback that will be executed when the next imported function was found
|
||||
*/
|
||||
class ImportThunksCallback
|
||||
{
|
||||
public:
|
||||
/**
|
||||
A class defining a callback that will be executed when the next imported function was found
|
||||
*/
|
||||
class ImportThunksCallback
|
||||
{
|
||||
public:
|
||||
ImportThunksCallback(BYTE* _modulePtr, size_t _moduleSize)
|
||||
: modulePtr(_modulePtr), moduleSize(_moduleSize)
|
||||
{
|
||||
@@ -35,16 +36,15 @@ namespace peconv {
|
||||
*/
|
||||
virtual bool processThunks(LPSTR libName, ULONG_PTR origFirstThunkPtr, ULONG_PTR firstThunkPtr) = 0;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
BYTE* modulePtr;
|
||||
size_t moduleSize;
|
||||
bool is64b;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct ImportsCollection
|
||||
{
|
||||
public:
|
||||
struct ImportsCollection {
|
||||
public:
|
||||
ImportsCollection() {};
|
||||
~ImportsCollection()
|
||||
{
|
||||
@@ -63,41 +63,41 @@ namespace peconv {
|
||||
}
|
||||
|
||||
std::map<DWORD, peconv::ExportedFunc*> thunkToFunc;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
Process the given PE's import table and execute the callback each time when the new imported function was found
|
||||
\param modulePtr : a pointer to the loded PE (in virtual format)
|
||||
\param moduleSize : a size of the supplied PE
|
||||
\param callback : a callback that will be executed to process each imported function
|
||||
\return : true if processing succeeded, false otherwise
|
||||
*/
|
||||
bool process_import_table(IN BYTE* modulePtr, IN SIZE_T moduleSize, IN ImportThunksCallback *callback);
|
||||
/**
|
||||
Process the given PE's import table and execute the callback each time when the new imported function was found
|
||||
\param modulePtr : a pointer to the loded PE (in virtual format)
|
||||
\param moduleSize : a size of the supplied PE
|
||||
\param callback : a callback that will be executed to process each imported function
|
||||
\return : true if processing succeeded, false otherwise
|
||||
*/
|
||||
bool process_import_table(IN BYTE* modulePtr, IN SIZE_T moduleSize, IN ImportThunksCallback *callback);
|
||||
|
||||
/**
|
||||
Fills imports of the given PE with the help of the defined functions resolver.
|
||||
\param modulePtr : a pointer to the loded PE (in virtual format)
|
||||
\param func_resolver : a resolver that will be used to fill the thunk of the import
|
||||
\return : true if loading all functions succeeded, false otherwise
|
||||
*/
|
||||
bool load_imports(BYTE* modulePtr, t_function_resolver* func_resolver=nullptr);
|
||||
/**
|
||||
Fills imports of the given PE with the help of the defined functions resolver.
|
||||
\param modulePtr : a pointer to the loded PE (in virtual format)
|
||||
\param func_resolver : a resolver that will be used to fill the thunk of the import
|
||||
\return : true if loading all functions succeeded, false otherwise
|
||||
*/
|
||||
bool load_imports(BYTE* modulePtr, t_function_resolver* func_resolver=nullptr);
|
||||
|
||||
/**
|
||||
Checks if the given PE has a valid import table.
|
||||
*/
|
||||
bool has_valid_import_table(const PBYTE modulePtr, size_t moduleSize);
|
||||
/**
|
||||
Checks if the given PE has a valid import table.
|
||||
*/
|
||||
bool has_valid_import_table(const PBYTE modulePtr, size_t moduleSize);
|
||||
|
||||
/**
|
||||
Checks if the given lib_name is a valid DLL name.
|
||||
A valid name must contain printable characters. Empty name is also acceptable (may have been erased).
|
||||
*/
|
||||
bool is_valid_import_name(const PBYTE modulePtr, const size_t moduleSize, LPSTR lib_name);
|
||||
/**
|
||||
Checks if the given lib_name is a valid DLL name.
|
||||
A valid name must contain printable characters. Empty name is also acceptable (may have been erased).
|
||||
*/
|
||||
bool is_valid_import_name(const PBYTE modulePtr, const size_t moduleSize, LPSTR lib_name);
|
||||
|
||||
/**
|
||||
* Collects all the Import Thunks RVAs (via which Imports are called)
|
||||
*/
|
||||
bool collect_thunks(IN BYTE* modulePtr, IN SIZE_T moduleSize, OUT std::set<DWORD>& thunk_rvas);
|
||||
/**
|
||||
* Collects all the Import Thunks RVAs (via which Imports are called)
|
||||
*/
|
||||
bool collect_thunks(IN BYTE* modulePtr, IN SIZE_T moduleSize, OUT std::set<DWORD>& thunk_rvas);
|
||||
|
||||
bool collect_imports(IN BYTE* modulePtr, IN SIZE_T moduleSize, OUT ImportsCollection &collection);
|
||||
bool collect_imports(IN BYTE* modulePtr, IN SIZE_T moduleSize, OUT ImportsCollection &collection);
|
||||
|
||||
}; // namespace peconv
|
||||
|
||||
@@ -16,14 +16,15 @@
|
||||
#include "fix_imports.h"
|
||||
#include "caves.h"
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
A class responsible for recovering the partially erased Import Table from the PE.
|
||||
*/
|
||||
class ImportsUneraser
|
||||
{
|
||||
public:
|
||||
/**
|
||||
A class responsible for recovering the partially erased Import Table from the PE.
|
||||
*/
|
||||
class ImportsUneraser
|
||||
{
|
||||
public:
|
||||
ImportsUneraser(PVOID _modulePtr, size_t _moduleSize)
|
||||
: modulePtr((PBYTE)_modulePtr), moduleSize(_moduleSize)
|
||||
{
|
||||
@@ -45,7 +46,7 @@ namespace peconv {
|
||||
*/
|
||||
bool uneraseDllName(IMAGE_IMPORT_DESCRIPTOR* lib_desc, const std::string &dll_name);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
/**
|
||||
Copy the given DLL name into the given IMAGE_IMPORT_DESCRIPTOR. Validates the data correctness before writing.
|
||||
\param lib_desc : the IMAGE_IMPORT_DESCRIPTOR where the DLL name should be set
|
||||
@@ -90,5 +91,5 @@ namespace peconv {
|
||||
PBYTE modulePtr;
|
||||
size_t moduleSize;
|
||||
bool is64;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,22 +8,23 @@
|
||||
#include <windows.h>
|
||||
#include <pshpack4.h>
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_CODE_INTEGRITY: a structure used by IMAGE_LOAD_CONFIG_DIR - the Windows 10 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_CODE_INTEGRITY_W10 {
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_CODE_INTEGRITY: a structure used by IMAGE_LOAD_CONFIG_DIR - the Windows 10 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_CODE_INTEGRITY_W10 {
|
||||
WORD Flags; // Flags to indicate if CI information is available, etc.
|
||||
WORD Catalog; // 0xFFFF means not available
|
||||
DWORD CatalogOffset;
|
||||
DWORD Reserved; // Additional bitmask to be defined later
|
||||
} IMAGE_LOAD_CONFIG_CODE_INTEGRITY_W10;
|
||||
} IMAGE_LOAD_CONFIG_CODE_INTEGRITY_W10;
|
||||
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR32: the Windows 10 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR32_W10 {
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR32: the Windows 10 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR32_W10 {
|
||||
DWORD Size;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
@@ -65,12 +66,12 @@ namespace peconv {
|
||||
DWORD HotPatchTableOffset;
|
||||
DWORD Reserved3;
|
||||
DWORD EnclaveConfigurationPointer; // VA
|
||||
} IMAGE_LOAD_CONFIG_DIR32_W10;
|
||||
} IMAGE_LOAD_CONFIG_DIR32_W10;
|
||||
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR64: the Windows 10 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR64_W10 {
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR64: the Windows 10 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR64_W10 {
|
||||
DWORD Size;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
@@ -112,12 +113,12 @@ namespace peconv {
|
||||
DWORD HotPatchTableOffset;
|
||||
DWORD Reserved3;
|
||||
ULONGLONG EnclaveConfigurationPointer; // VA
|
||||
} IMAGE_LOAD_CONFIG_DIR64_W10;
|
||||
} IMAGE_LOAD_CONFIG_DIR64_W10;
|
||||
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR32: the Windows 8 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR32_W8 {
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR32: the Windows 8 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR32_W8 {
|
||||
DWORD Size;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
@@ -143,12 +144,12 @@ namespace peconv {
|
||||
DWORD GuardCFFunctionTable; // VA
|
||||
DWORD GuardCFFunctionCount;
|
||||
DWORD GuardFlags;
|
||||
} IMAGE_LOAD_CONFIG_DIR32_W8;
|
||||
} IMAGE_LOAD_CONFIG_DIR32_W8;
|
||||
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR64: the Windows 8 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR64_W8 {
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR64: the Windows 8 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR64_W8 {
|
||||
DWORD Size;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
@@ -174,13 +175,13 @@ namespace peconv {
|
||||
ULONGLONG GuardCFFunctionTable; // VA
|
||||
ULONGLONG GuardCFFunctionCount;
|
||||
DWORD GuardFlags;
|
||||
} IMAGE_LOAD_CONFIG_DIR64_W8;
|
||||
} IMAGE_LOAD_CONFIG_DIR64_W8;
|
||||
|
||||
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR32: the Windows 7 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR32_W7 {
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR32: the Windows 7 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR32_W7 {
|
||||
DWORD Size;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
@@ -201,12 +202,12 @@ namespace peconv {
|
||||
DWORD SecurityCookie; // VA
|
||||
DWORD SEHandlerTable; // VA
|
||||
DWORD SEHandlerCount;
|
||||
} IMAGE_LOAD_CONFIG_DIR32_W7;
|
||||
} IMAGE_LOAD_CONFIG_DIR32_W7;
|
||||
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR64: the Windows 7 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR64_W7 {
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR64: the Windows 7 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR64_W7 {
|
||||
DWORD Size;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
@@ -227,7 +228,7 @@ namespace peconv {
|
||||
ULONGLONG SecurityCookie; // VA
|
||||
ULONGLONG SEHandlerTable; // VA
|
||||
ULONGLONG SEHandlerCount;
|
||||
} IMAGE_LOAD_CONFIG_DIR64_W7;
|
||||
} IMAGE_LOAD_CONFIG_DIR64_W7;
|
||||
}; //namespace peconv
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
@@ -9,34 +9,35 @@
|
||||
#include "buffer_util.h"
|
||||
#include "load_config_defs.h"
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
A version of Load Config Directory.
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
A version of Load Config Directory.
|
||||
*/
|
||||
typedef enum {
|
||||
LOAD_CONFIG_NONE = 0, /**< Load Config Directory not found */
|
||||
LOAD_CONFIG_W7_VER = 7, /**< Load Config Directory in the Windows 7 version */
|
||||
LOAD_CONFIG_W8_VER = 8, /**< Load Config Directory in the Windows 8 version */
|
||||
LOAD_CONFIG_W10_VER = 10, /**< Load Config Directory in the Windows 10 version */
|
||||
LOAD_CONFIG_UNK_VER = -1 /**< Load Config Directory in an unknown version */
|
||||
} t_load_config_ver;
|
||||
} t_load_config_ver;
|
||||
|
||||
/**
|
||||
Get a pointer to the Load Config Directory within the given PE.
|
||||
\param buffer : a buffer containing the PE file in a Virtual format
|
||||
\param buf_size : size of the buffer
|
||||
\return a pointer to the Load Config Directory, NULL if the given PE does not have this directory
|
||||
*/
|
||||
BYTE* get_load_config_ptr(BYTE* buffer, size_t buf_size);
|
||||
/**
|
||||
Get a pointer to the Load Config Directory within the given PE.
|
||||
\param buffer : a buffer containing the PE file in a Virtual format
|
||||
\param buf_size : size of the buffer
|
||||
\return a pointer to the Load Config Directory, NULL if the given PE does not have this directory
|
||||
*/
|
||||
BYTE* get_load_config_ptr(BYTE* buffer, size_t buf_size);
|
||||
|
||||
/**
|
||||
Detect which version of Load Config Directory was used in the given PE.
|
||||
\param buffer : a buffer containing the PE file in a Virtual format
|
||||
\param buf_size : size of the buffer
|
||||
\param ld_config_ptr : pointer to the Load Config Directory within the given PE
|
||||
\return detected version of Load Config Directory
|
||||
*/
|
||||
t_load_config_ver get_load_config_version(BYTE* buffer, size_t buf_size, BYTE* ld_config_ptr);
|
||||
/**
|
||||
Detect which version of Load Config Directory was used in the given PE.
|
||||
\param buffer : a buffer containing the PE file in a Virtual format
|
||||
\param buf_size : size of the buffer
|
||||
\param ld_config_ptr : pointer to the Load Config Directory within the given PE
|
||||
\return detected version of Load Config Directory
|
||||
*/
|
||||
t_load_config_ver get_load_config_version(BYTE* buffer, size_t buf_size, BYTE* ld_config_ptr);
|
||||
|
||||
}; // namespace peconv
|
||||
|
||||
@@ -8,42 +8,43 @@
|
||||
#include <windows.h>
|
||||
#include "exports_mapper.h"
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
A mode in which the PE fille be dumped.
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
A mode in which the PE fille be dumped.
|
||||
*/
|
||||
typedef enum {
|
||||
PE_DUMP_AUTO = 0, /**< autodetect which dump mode is the most suitable for the given input */
|
||||
PE_DUMP_VIRTUAL,/**< dump as it is in the memory (virtual) */
|
||||
PE_DUMP_UNMAP, /**< convert to the raw format: using raw sections' headers */
|
||||
PE_DUMP_REALIGN, /**< convert to the raw format: by realigning raw sections' headers to be the same as virtual (useful if the PE was unpacked in memory) */
|
||||
PE_DUMP_MODES_COUNT /**< total number of the dump modes */
|
||||
} t_pe_dump_mode;
|
||||
} t_pe_dump_mode;
|
||||
|
||||
/**
|
||||
Detect dump mode that is the most suitable for the given input.
|
||||
\param buffer : the buffer containing the PE to be dumped.
|
||||
\param buffer_size : the size of the given buffer
|
||||
*/
|
||||
t_pe_dump_mode detect_dump_mode(IN const BYTE* buffer, IN size_t buffer_size);
|
||||
/**
|
||||
Detect dump mode that is the most suitable for the given input.
|
||||
\param buffer : the buffer containing the PE to be dumped.
|
||||
\param buffer_size : the size of the given buffer
|
||||
*/
|
||||
t_pe_dump_mode detect_dump_mode(IN const BYTE* buffer, IN size_t buffer_size);
|
||||
|
||||
/**
|
||||
Dumps PE from the fiven buffer into a file. It expects the module base and size to be given.
|
||||
\param outputFilePath : name of the file where the dump should be saved
|
||||
\param buffer : the buffer containing the PE to be dumped. WARNING: the buffer may be preprocessed before dumping.
|
||||
\param buffer_size : the size of the given buffer
|
||||
\param module_base : the base to which the PE buffer was relocated
|
||||
\param dump_mode : specifies in which format the PE should be dumped. If the mode was set to PE_DUMP_AUTO, it autodetects mode and returns the detected one.
|
||||
\param exportsMap : optional. If exportsMap is supplied, it will try to recover destroyed import table of the PE, basing on the supplied map of exported functions.
|
||||
*/
|
||||
bool dump_pe(
|
||||
/**
|
||||
Dumps PE from the fiven buffer into a file. It expects the module base and size to be given.
|
||||
\param outputFilePath : name of the file where the dump should be saved
|
||||
\param buffer : the buffer containing the PE to be dumped. WARNING: the buffer may be preprocessed before dumping.
|
||||
\param buffer_size : the size of the given buffer
|
||||
\param module_base : the base to which the PE buffer was relocated
|
||||
\param dump_mode : specifies in which format the PE should be dumped. If the mode was set to PE_DUMP_AUTO, it autodetects mode and returns the detected one.
|
||||
\param exportsMap : optional. If exportsMap is supplied, it will try to recover destroyed import table of the PE, basing on the supplied map of exported functions.
|
||||
*/
|
||||
bool dump_pe(
|
||||
IN LPCTSTR outputFilePath,
|
||||
IN OUT BYTE* buffer,
|
||||
IN size_t buffer_size,
|
||||
IN const ULONGLONG module_base,
|
||||
IN OUT t_pe_dump_mode &dump_mode,
|
||||
IN OPTIONAL const peconv::ExportsMapper* exportsMap = nullptr
|
||||
);
|
||||
);
|
||||
|
||||
};// namespace peconv
|
||||
|
||||
@@ -12,15 +12,16 @@
|
||||
#define PAGE_SIZE 0x1000
|
||||
#endif
|
||||
|
||||
namespace peconv {
|
||||
/**
|
||||
Maximal size of the PE header.
|
||||
*/
|
||||
const ULONGLONG MAX_HEADER_SIZE = PAGE_SIZE;
|
||||
namespace peconv
|
||||
{
|
||||
/**
|
||||
Maximal size of the PE header.
|
||||
*/
|
||||
const ULONGLONG MAX_HEADER_SIZE = PAGE_SIZE;
|
||||
|
||||
template <typename INT_TYPE>
|
||||
INT_TYPE round_up_to_unit(const INT_TYPE size, const INT_TYPE unit)
|
||||
{
|
||||
template <typename INT_TYPE>
|
||||
INT_TYPE round_up_to_unit(const INT_TYPE size, const INT_TYPE unit)
|
||||
{
|
||||
if (unit == 0) {
|
||||
return size;
|
||||
}
|
||||
@@ -30,76 +31,76 @@ namespace peconv {
|
||||
rounded_size += unit;
|
||||
}
|
||||
return rounded_size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Fetch image size from headers.
|
||||
*/
|
||||
DWORD get_image_size(IN const BYTE *payload);
|
||||
/**
|
||||
Fetch image size from headers.
|
||||
*/
|
||||
DWORD get_image_size(IN const BYTE *payload);
|
||||
|
||||
/**
|
||||
Change the Image Size in Optional Header to the given one.
|
||||
*/
|
||||
bool update_image_size(IN OUT BYTE* payload, IN DWORD new_img_size);
|
||||
/**
|
||||
Change the Image Size in Optional Header to the given one.
|
||||
*/
|
||||
bool update_image_size(IN OUT BYTE* payload, IN DWORD new_img_size);
|
||||
|
||||
/**
|
||||
Fetch architecture from the NT headers. Checks for bad pointers.
|
||||
*/
|
||||
WORD get_nt_hdr_architecture(IN const BYTE *pe_buffer);
|
||||
/**
|
||||
Fetch architecture from the NT headers. Checks for bad pointers.
|
||||
*/
|
||||
WORD get_nt_hdr_architecture(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
Wrapper for get_nt_hdr_architecture. Returns true if the PE file is 64 bit.
|
||||
*/
|
||||
bool is64bit(IN const BYTE *pe_buffer);
|
||||
/**
|
||||
Wrapper for get_nt_hdr_architecture. Returns true if the PE file is 64 bit.
|
||||
*/
|
||||
bool is64bit(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
Fetch pointer to the NT headers of the PE file.
|
||||
Checks for bad pointers. If buffer_size is set, validates pointers against the buffer size.
|
||||
*/
|
||||
BYTE* get_nt_hdrs(
|
||||
/**
|
||||
Fetch pointer to the NT headers of the PE file.
|
||||
Checks for bad pointers. If buffer_size is set, validates pointers against the buffer size.
|
||||
*/
|
||||
BYTE* get_nt_hdrs(
|
||||
IN const BYTE *pe_buffer,
|
||||
IN OPTIONAL size_t buffer_size=0 //if buffer_size=0 means size unknown
|
||||
);
|
||||
);
|
||||
|
||||
/**
|
||||
Wrapper for get_nt_headers. Automatically detects if the PE is 32 bit - if not, returns null pointer.
|
||||
*/
|
||||
IMAGE_NT_HEADERS32* get_nt_hdrs32(IN const BYTE *pe_buffer);
|
||||
/**
|
||||
Wrapper for get_nt_headers. Automatically detects if the PE is 32 bit - if not, returns null pointer.
|
||||
*/
|
||||
IMAGE_NT_HEADERS32* get_nt_hdrs32(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
Wrapper for get_nt_headers. Automatically detects if the PE is 64 bit - if not, returns null pointer.
|
||||
*/
|
||||
IMAGE_NT_HEADERS64* get_nt_hdrs64(IN const BYTE *pe_buffer);
|
||||
/**
|
||||
Wrapper for get_nt_headers. Automatically detects if the PE is 64 bit - if not, returns null pointer.
|
||||
*/
|
||||
IMAGE_NT_HEADERS64* get_nt_hdrs64(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
Fetches optional header of the PE. Validates pointers against buffer size.
|
||||
*/
|
||||
LPVOID get_optional_hdr(IN const BYTE* payload, IN const size_t buffer_size);
|
||||
/**
|
||||
Fetches optional header of the PE. Validates pointers against buffer size.
|
||||
*/
|
||||
LPVOID get_optional_hdr(IN const BYTE* payload, IN const size_t buffer_size);
|
||||
|
||||
/**
|
||||
Fetches file header of the PE. Validates pointers against buffer size.
|
||||
*/
|
||||
const IMAGE_FILE_HEADER* get_file_hdr(
|
||||
/**
|
||||
Fetches file header of the PE. Validates pointers against buffer size.
|
||||
*/
|
||||
const IMAGE_FILE_HEADER* get_file_hdr(
|
||||
IN const BYTE* payload,
|
||||
IN const size_t buffer_size
|
||||
);
|
||||
);
|
||||
|
||||
/**
|
||||
Fetch the size of headers (from Optional Header).
|
||||
*/
|
||||
DWORD get_hdrs_size(IN const BYTE *pe_buffer);
|
||||
/**
|
||||
Fetch the size of headers (from Optional Header).
|
||||
*/
|
||||
DWORD get_hdrs_size(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
get Data Directory entry of the given number. If the entry is not filled and allow_empty is not set, it returns null pointer.
|
||||
*/
|
||||
IMAGE_DATA_DIRECTORY* get_directory_entry(IN const BYTE* pe_buffer, IN DWORD dir_id, IN bool allow_empty = false);
|
||||
/**
|
||||
get Data Directory entry of the given number. If the entry is not filled and allow_empty is not set, it returns null pointer.
|
||||
*/
|
||||
IMAGE_DATA_DIRECTORY* get_directory_entry(IN const BYTE* pe_buffer, IN DWORD dir_id, IN bool allow_empty = false);
|
||||
|
||||
/**
|
||||
Get pointer to the Data Directory content of the given number. Automatically cast to the chosen type.
|
||||
*/
|
||||
template <typename IMAGE_TYPE_DIRECTORY>
|
||||
IMAGE_TYPE_DIRECTORY* get_type_directory(IN HMODULE modulePtr, IN DWORD dir_id)
|
||||
{
|
||||
/**
|
||||
Get pointer to the Data Directory content of the given number. Automatically cast to the chosen type.
|
||||
*/
|
||||
template <typename IMAGE_TYPE_DIRECTORY>
|
||||
IMAGE_TYPE_DIRECTORY* get_type_directory(IN HMODULE modulePtr, IN DWORD dir_id)
|
||||
{
|
||||
IMAGE_DATA_DIRECTORY *my_dir = peconv::get_directory_entry((const BYTE*)modulePtr, dir_id);
|
||||
if (!my_dir) return nullptr;
|
||||
|
||||
@@ -107,142 +108,142 @@ namespace peconv {
|
||||
if (dir_addr == 0) return nullptr;
|
||||
|
||||
return (IMAGE_TYPE_DIRECTORY*)(dir_addr + (ULONG_PTR)modulePtr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Get pointer to the Export Directory.
|
||||
*/
|
||||
IMAGE_EXPORT_DIRECTORY* get_export_directory(IN HMODULE modulePtr);
|
||||
/**
|
||||
Get pointer to the Export Directory.
|
||||
*/
|
||||
IMAGE_EXPORT_DIRECTORY* get_export_directory(IN HMODULE modulePtr);
|
||||
|
||||
// Fetch Image Base from Optional Header.
|
||||
ULONGLONG get_image_base(IN const BYTE *pe_buffer);
|
||||
// Fetch Image Base from Optional Header.
|
||||
ULONGLONG get_image_base(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
Change the Image Base in Optional Header to the given one.
|
||||
*/
|
||||
bool update_image_base(IN OUT BYTE* payload, IN ULONGLONG destImageBase);
|
||||
/**
|
||||
Change the Image Base in Optional Header to the given one.
|
||||
*/
|
||||
bool update_image_base(IN OUT BYTE* payload, IN ULONGLONG destImageBase);
|
||||
|
||||
/**
|
||||
Get RVA of the Entry Point from the Optional Header.
|
||||
*/
|
||||
DWORD get_entry_point_rva(IN const BYTE *pe_buffer);
|
||||
/**
|
||||
Get RVA of the Entry Point from the Optional Header.
|
||||
*/
|
||||
DWORD get_entry_point_rva(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
Change the Entry Point RVA in the Optional Header to the given one.
|
||||
*/
|
||||
bool update_entry_point_rva(IN OUT BYTE *pe_buffer, IN DWORD ep);
|
||||
/**
|
||||
Change the Entry Point RVA in the Optional Header to the given one.
|
||||
*/
|
||||
bool update_entry_point_rva(IN OUT BYTE *pe_buffer, IN DWORD ep);
|
||||
|
||||
/**
|
||||
Get number of sections from the File Header. It does not validate if this the actual number.
|
||||
*/
|
||||
size_t get_sections_count(
|
||||
/**
|
||||
Get number of sections from the File Header. It does not validate if this the actual number.
|
||||
*/
|
||||
size_t get_sections_count(
|
||||
IN const BYTE* buffer,
|
||||
IN const size_t buffer_size
|
||||
);
|
||||
);
|
||||
|
||||
/**
|
||||
Checks if the section headers are reachable. It does not validate sections alignment.
|
||||
*/
|
||||
bool is_valid_sections_hdr_offset(IN const BYTE* buffer, IN const size_t buffer_size);
|
||||
/**
|
||||
Checks if the section headers are reachable. It does not validate sections alignment.
|
||||
*/
|
||||
bool is_valid_sections_hdr_offset(IN const BYTE* buffer, IN const size_t buffer_size);
|
||||
|
||||
/**
|
||||
Gets pointer to the section header of the given number.
|
||||
*/
|
||||
PIMAGE_SECTION_HEADER get_section_hdr(
|
||||
/**
|
||||
Gets pointer to the section header of the given number.
|
||||
*/
|
||||
PIMAGE_SECTION_HEADER get_section_hdr(
|
||||
IN const BYTE* pe_buffer,
|
||||
IN const size_t buffer_size,
|
||||
IN size_t section_num
|
||||
);
|
||||
);
|
||||
|
||||
/**
|
||||
Fetch the PE Characteristics from the File Header.
|
||||
*/
|
||||
WORD get_file_characteristics(IN const BYTE* payload);
|
||||
/**
|
||||
Fetch the PE Characteristics from the File Header.
|
||||
*/
|
||||
WORD get_file_characteristics(IN const BYTE* payload);
|
||||
|
||||
/**
|
||||
Check if the module is a DLL (basing on the Characteristcs in the header).
|
||||
*/
|
||||
bool is_module_dll(IN const BYTE* payload);
|
||||
/**
|
||||
Check if the module is a DLL (basing on the Characteristcs in the header).
|
||||
*/
|
||||
bool is_module_dll(IN const BYTE* payload);
|
||||
|
||||
/**
|
||||
Check if the module is a .NET executable
|
||||
*/
|
||||
bool is_dot_net(BYTE *pe_buffer, size_t pe_buffer_size);
|
||||
/**
|
||||
Check if the module is a .NET executable
|
||||
*/
|
||||
bool is_dot_net(BYTE *pe_buffer, size_t pe_buffer_size);
|
||||
|
||||
/**
|
||||
Fetch the DLL Characteristics from the Optional Header.
|
||||
*/
|
||||
WORD get_dll_characteristics(IN const BYTE* payload);
|
||||
/**
|
||||
Fetch the DLL Characteristics from the Optional Header.
|
||||
*/
|
||||
WORD get_dll_characteristics(IN const BYTE* payload);
|
||||
|
||||
/**
|
||||
Set the PE subsystem in the header.
|
||||
*/
|
||||
bool set_subsystem(IN OUT BYTE* payload, IN WORD subsystem);
|
||||
/**
|
||||
Set the PE subsystem in the header.
|
||||
*/
|
||||
bool set_subsystem(IN OUT BYTE* payload, IN WORD subsystem);
|
||||
|
||||
/**
|
||||
Get the PE subsystem from the header.
|
||||
*/
|
||||
WORD get_subsystem(IN const BYTE* payload);
|
||||
/**
|
||||
Get the PE subsystem from the header.
|
||||
*/
|
||||
WORD get_subsystem(IN const BYTE* payload);
|
||||
|
||||
/**
|
||||
Check if the PE has relocations Data Directory.
|
||||
*/
|
||||
bool has_relocations(IN const BYTE *pe_buffer);
|
||||
/**
|
||||
Check if the PE has relocations Data Directory.
|
||||
*/
|
||||
bool has_relocations(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
Fetch the pointer to the .NET header (if exist).
|
||||
*/
|
||||
IMAGE_COR20_HEADER* get_dotnet_hdr(
|
||||
/**
|
||||
Fetch the pointer to the .NET header (if exist).
|
||||
*/
|
||||
IMAGE_COR20_HEADER* get_dotnet_hdr(
|
||||
IN const BYTE* pe_buffer,
|
||||
IN size_t const buffer_size,
|
||||
IN const IMAGE_DATA_DIRECTORY* dotNetDir
|
||||
);
|
||||
);
|
||||
|
||||
/**
|
||||
Fetch section aligmenent from headers. Depending on the flag, it fetches either Raw Alignment or Virtual Alignment.
|
||||
*/
|
||||
DWORD get_sec_alignment(IN const BYTE* modulePtr, IN bool is_raw);
|
||||
/**
|
||||
Fetch section aligmenent from headers. Depending on the flag, it fetches either Raw Alignment or Virtual Alignment.
|
||||
*/
|
||||
DWORD get_sec_alignment(IN const BYTE* modulePtr, IN bool is_raw);
|
||||
|
||||
/**
|
||||
Change section aligmenent in headers. Depending on the flag, it sets either Raw Alignment or Virtual Alignment.
|
||||
*/
|
||||
bool set_sec_alignment(IN OUT BYTE* pe_buffer, IN bool is_raw, IN DWORD new_alignment);
|
||||
/**
|
||||
Change section aligmenent in headers. Depending on the flag, it sets either Raw Alignment or Virtual Alignment.
|
||||
*/
|
||||
bool set_sec_alignment(IN OUT BYTE* pe_buffer, IN bool is_raw, IN DWORD new_alignment);
|
||||
|
||||
/**
|
||||
Get size of virtual section from the headers (optionaly rounds it up to the Virtual Alignment)
|
||||
*/
|
||||
DWORD get_virtual_sec_size(
|
||||
/**
|
||||
Get size of virtual section from the headers (optionaly rounds it up to the Virtual Alignment)
|
||||
*/
|
||||
DWORD get_virtual_sec_size(
|
||||
IN const BYTE* pe_hdr,
|
||||
IN const PIMAGE_SECTION_HEADER sec_hdr,
|
||||
IN bool rounded //if set, it rounds it up to the Virtual Alignment
|
||||
);
|
||||
);
|
||||
|
||||
/**
|
||||
Get the last section (in a raw or virtual alignment)
|
||||
\param pe_buffer : buffer with a PE
|
||||
\param pe_size : size of the given PE
|
||||
\param is_raw : If true, give the section with the highest Raw offset. If false, give the section with the highest Virtual offset.
|
||||
*/
|
||||
PIMAGE_SECTION_HEADER get_last_section(IN const PBYTE pe_buffer, IN size_t pe_size, IN bool is_raw);
|
||||
/**
|
||||
Get the last section (in a raw or virtual alignment)
|
||||
\param pe_buffer : buffer with a PE
|
||||
\param pe_size : size of the given PE
|
||||
\param is_raw : If true, give the section with the highest Raw offset. If false, give the section with the highest Virtual offset.
|
||||
*/
|
||||
PIMAGE_SECTION_HEADER get_last_section(IN const PBYTE pe_buffer, IN size_t pe_size, IN bool is_raw);
|
||||
|
||||
/**
|
||||
Calculate full PE size (raw or virtual) using information from sections' headers. WARNING: it drops an overlay.
|
||||
\param pe_buffer : a buffer containing a PE
|
||||
\param pe_size : the size of the given buffer
|
||||
\param is_raw : If true, the Raw alignment is used. If false, the Virtual alignment is used.
|
||||
*/
|
||||
DWORD calc_pe_size(
|
||||
/**
|
||||
Calculate full PE size (raw or virtual) using information from sections' headers. WARNING: it drops an overlay.
|
||||
\param pe_buffer : a buffer containing a PE
|
||||
\param pe_size : the size of the given buffer
|
||||
\param is_raw : If true, the Raw alignment is used. If false, the Virtual alignment is used.
|
||||
*/
|
||||
DWORD calc_pe_size(
|
||||
IN const PBYTE pe_buffer,
|
||||
IN size_t pe_size,
|
||||
IN bool is_raw
|
||||
);
|
||||
);
|
||||
|
||||
/**
|
||||
Walk through sections headers checking if the sections beginnings and sizes are fitting the alignment (Virtual or Raw)
|
||||
\param buffer : a buffer containing a PE
|
||||
\param buffer_size : the size of the given buffer
|
||||
\param is_raw : If true, the Raw alignment is checked. If false, the Virtual alignment is checked.
|
||||
*/
|
||||
bool is_valid_sectons_alignment(IN const BYTE* buffer, IN const SIZE_T buffer_size, IN bool is_raw);
|
||||
/**
|
||||
Walk through sections headers checking if the sections beginnings and sizes are fitting the alignment (Virtual or Raw)
|
||||
\param buffer : a buffer containing a PE
|
||||
\param buffer_size : the size of the given buffer
|
||||
\param is_raw : If true, the Raw alignment is checked. If false, the Virtual alignment is checked.
|
||||
*/
|
||||
bool is_valid_sectons_alignment(IN const BYTE* buffer, IN const SIZE_T buffer_size, IN bool is_raw);
|
||||
|
||||
}; // namespace peconv
|
||||
|
||||
@@ -8,35 +8,36 @@
|
||||
#include "pe_raw_to_virtual.h"
|
||||
#include "function_resolver.h"
|
||||
|
||||
namespace peconv {
|
||||
/**
|
||||
Reads PE from the given buffer into memory and maps it into virtual format.
|
||||
(Automatic raw to virtual conversion).
|
||||
If the executable flag is true, the PE file is loaded into executable memory.
|
||||
If the relocate flag is true, applies relocations. Does not load imports.
|
||||
Automatically allocates buffer of the needed size (the size is returned in outputSize). The buffer can be freed by the function free_pe_buffer.
|
||||
*/
|
||||
BYTE* load_pe_module(BYTE* payload_raw, size_t r_size, OUT size_t &v_size, bool executable, bool relocate, ULONG_PTR desired_base = 0);
|
||||
namespace peconv
|
||||
{
|
||||
/**
|
||||
Reads PE from the given buffer into memory and maps it into virtual format.
|
||||
(Automatic raw to virtual conversion).
|
||||
If the executable flag is true, the PE file is loaded into executable memory.
|
||||
If the relocate flag is true, applies relocations. Does not load imports.
|
||||
Automatically allocates buffer of the needed size (the size is returned in outputSize). The buffer can be freed by the function free_pe_buffer.
|
||||
*/
|
||||
BYTE* load_pe_module(BYTE* payload_raw, size_t r_size, OUT size_t &v_size, bool executable, bool relocate, ULONG_PTR desired_base = 0);
|
||||
|
||||
/**
|
||||
Reads PE from the given file into memory and maps it into vitual format.
|
||||
(Automatic raw to virtual conversion).
|
||||
If the executable flag is true, the PE file is loaded into executable memory.
|
||||
If the relocate flag is true, applies relocations. Does not load imports.
|
||||
Automatically allocates buffer of the needed size (the size is returned in outputSize). The buffer can be freed by the function free_pe_buffer.
|
||||
*/
|
||||
BYTE* load_pe_module(LPCTSTR filename, OUT size_t &v_size, bool executable, bool relocate, ULONG_PTR desired_base = 0);
|
||||
/**
|
||||
Reads PE from the given file into memory and maps it into vitual format.
|
||||
(Automatic raw to virtual conversion).
|
||||
If the executable flag is true, the PE file is loaded into executable memory.
|
||||
If the relocate flag is true, applies relocations. Does not load imports.
|
||||
Automatically allocates buffer of the needed size (the size is returned in outputSize). The buffer can be freed by the function free_pe_buffer.
|
||||
*/
|
||||
BYTE* load_pe_module(LPCTSTR filename, OUT size_t &v_size, bool executable, bool relocate, ULONG_PTR desired_base = 0);
|
||||
|
||||
/**
|
||||
Loads full PE from the raw buffer in a way in which it can be directly executed: remaps to virual format, applies relocations, loads imports.
|
||||
Allows for supplying custom function resolver.
|
||||
*/
|
||||
BYTE* load_pe_executable(BYTE* payload_raw, size_t r_size, OUT size_t &v_size, t_function_resolver* import_resolver = nullptr, ULONG_PTR desired_base = 0);
|
||||
/**
|
||||
Loads full PE from the raw buffer in a way in which it can be directly executed: remaps to virual format, applies relocations, loads imports.
|
||||
Allows for supplying custom function resolver.
|
||||
*/
|
||||
BYTE* load_pe_executable(BYTE* payload_raw, size_t r_size, OUT size_t &v_size, t_function_resolver* import_resolver = nullptr, ULONG_PTR desired_base = 0);
|
||||
|
||||
/**
|
||||
Loads full PE from file in a way in which it can be directly executed: remaps to virtual format, applies relocations, loads imports.
|
||||
Allows for supplying custom function resolver.
|
||||
*/
|
||||
BYTE* load_pe_executable(LPCTSTR filename, OUT size_t &v_size, t_function_resolver* import_resolver = nullptr);
|
||||
/**
|
||||
Loads full PE from file in a way in which it can be directly executed: remaps to virtual format, applies relocations, loads imports.
|
||||
Allows for supplying custom function resolver.
|
||||
*/
|
||||
BYTE* load_pe_executable(LPCTSTR filename, OUT size_t &v_size, t_function_resolver* import_resolver = nullptr);
|
||||
|
||||
};// namespace peconv
|
||||
|
||||
@@ -9,36 +9,37 @@
|
||||
|
||||
#include "pe_hdrs_helper.h"
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
check if the PE in the memory is in raw format
|
||||
*/
|
||||
bool is_pe_raw(
|
||||
/**
|
||||
check if the PE in the memory is in raw format
|
||||
*/
|
||||
bool is_pe_raw(
|
||||
IN const BYTE* pe_buffer,
|
||||
IN size_t pe_size
|
||||
);
|
||||
);
|
||||
|
||||
/**
|
||||
check if Virtual section addresses are identical to Raw addresses (i.e. if the PE was realigned)
|
||||
*/
|
||||
bool is_pe_raw_eq_virtual(
|
||||
/**
|
||||
check if Virtual section addresses are identical to Raw addresses (i.e. if the PE was realigned)
|
||||
*/
|
||||
bool is_pe_raw_eq_virtual(
|
||||
IN const BYTE* pe_buffer,
|
||||
IN size_t pe_size
|
||||
);
|
||||
);
|
||||
|
||||
/**
|
||||
checks if the PE has sections that were unpacked/expanded in the memory
|
||||
*/
|
||||
bool is_pe_expanded(
|
||||
/**
|
||||
checks if the PE has sections that were unpacked/expanded in the memory
|
||||
*/
|
||||
bool is_pe_expanded(
|
||||
IN const BYTE* pe_buffer,
|
||||
IN size_t pe_size
|
||||
);
|
||||
);
|
||||
|
||||
/**
|
||||
checks if the given section was unpacked in the memory
|
||||
*/
|
||||
bool is_section_expanded(IN const BYTE* pe_buffer,
|
||||
/**
|
||||
checks if the given section was unpacked in the memory
|
||||
*/
|
||||
bool is_section_expanded(IN const BYTE* pe_buffer,
|
||||
IN size_t pe_size,
|
||||
IN const PIMAGE_SECTION_HEADER sec
|
||||
);
|
||||
|
||||
@@ -10,21 +10,22 @@
|
||||
|
||||
#include "buffer_util.h"
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
Converts a raw PE supplied in a buffer to a virtual format.
|
||||
If the executable flag is true (default), the PE file is loaded into executable memory.
|
||||
Does not apply relocations. Does not load imports.
|
||||
Automatically allocates buffer of the needed size (the size is returned in outputSize). The buffer can be freed by the function free_pe_module.
|
||||
If the desired_base is defined (0 by default), it enforces allocation at the particular base.
|
||||
*/
|
||||
BYTE* pe_raw_to_virtual(
|
||||
/**
|
||||
Converts a raw PE supplied in a buffer to a virtual format.
|
||||
If the executable flag is true (default), the PE file is loaded into executable memory.
|
||||
Does not apply relocations. Does not load imports.
|
||||
Automatically allocates buffer of the needed size (the size is returned in outputSize). The buffer can be freed by the function free_pe_module.
|
||||
If the desired_base is defined (0 by default), it enforces allocation at the particular base.
|
||||
*/
|
||||
BYTE* pe_raw_to_virtual(
|
||||
IN const BYTE* rawPeBuffer,
|
||||
IN size_t rawPeSize,
|
||||
OUT size_t &outputSize,
|
||||
IN OPTIONAL bool executable = true,
|
||||
IN OPTIONAL ULONG_PTR desired_base = 0
|
||||
);
|
||||
);
|
||||
|
||||
}; // namespace peconv
|
||||
|
||||
@@ -9,39 +9,40 @@
|
||||
|
||||
#include "buffer_util.h"
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
Maps virtual image of PE to into raw. Automaticaly applies relocations.
|
||||
Automatically allocates buffer of the needed size (the size is returned in outputSize).
|
||||
\param payload : the PE in the Virtual format that needs to be converted into the Raw format
|
||||
\param in_size : size of the input buffer (the PE in the Virtual format)
|
||||
\param loadBase : the base to which the given PE was relocated
|
||||
\param outputSize : the size of the output buffer (the PE in the Raw format)
|
||||
\param rebuffer : if set (default), the input buffer is rebuffered and the original buffer is not modified.
|
||||
\return a buffer of the outputSize, containing the Raw PE. The buffer can be freed by the function free_pe_module.
|
||||
*/
|
||||
BYTE* pe_virtual_to_raw(
|
||||
/**
|
||||
Maps virtual image of PE to into raw. Automaticaly applies relocations.
|
||||
Automatically allocates buffer of the needed size (the size is returned in outputSize).
|
||||
\param payload : the PE in the Virtual format that needs to be converted into the Raw format
|
||||
\param in_size : size of the input buffer (the PE in the Virtual format)
|
||||
\param loadBase : the base to which the given PE was relocated
|
||||
\param outputSize : the size of the output buffer (the PE in the Raw format)
|
||||
\param rebuffer : if set (default), the input buffer is rebuffered and the original buffer is not modified.
|
||||
\return a buffer of the outputSize, containing the Raw PE. The buffer can be freed by the function free_pe_module.
|
||||
*/
|
||||
BYTE* pe_virtual_to_raw(
|
||||
IN BYTE* payload,
|
||||
IN size_t in_size,
|
||||
IN ULONGLONG loadBase,
|
||||
OUT size_t &outputSize,
|
||||
IN OPTIONAL bool rebuffer=true
|
||||
);
|
||||
);
|
||||
|
||||
/*
|
||||
Modifies raw alignment of the PE to be the same as virtual alignment.
|
||||
\param payload : the PE in the Virtual format that needs to be realigned
|
||||
\param in_size : size of the input buffer
|
||||
\param loadBase : the base to which the given PE was relocated
|
||||
\param outputSize : the size of the output buffer (the PE in the Raw format)
|
||||
\return a buffer of the outputSize, containing the realigned PE. The buffer can be freed by the function free_pe_module.
|
||||
*/
|
||||
BYTE* pe_realign_raw_to_virtual(
|
||||
/*
|
||||
Modifies raw alignment of the PE to be the same as virtual alignment.
|
||||
\param payload : the PE in the Virtual format that needs to be realigned
|
||||
\param in_size : size of the input buffer
|
||||
\param loadBase : the base to which the given PE was relocated
|
||||
\param outputSize : the size of the output buffer (the PE in the Raw format)
|
||||
\return a buffer of the outputSize, containing the realigned PE. The buffer can be freed by the function free_pe_module.
|
||||
*/
|
||||
BYTE* pe_realign_raw_to_virtual(
|
||||
IN const BYTE* payload,
|
||||
IN size_t in_size,
|
||||
IN ULONGLONG loadBase,
|
||||
OUT size_t &outputSize
|
||||
);
|
||||
);
|
||||
|
||||
};//namespace peconv
|
||||
|
||||
@@ -7,34 +7,35 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
Gets handle to the given module via PEB. A low-level equivalent of `GetModuleHandleW`.
|
||||
\param module_name : (optional) the name of the DLL loaded within the current process. If not set, the main module of the current process is used.
|
||||
\return the handle of the DLL with given name, or, if the name was not given, the handle of the main module of the current process.
|
||||
*/
|
||||
HMODULE get_module_via_peb(IN OPTIONAL LPCWSTR module_name = nullptr);
|
||||
/**
|
||||
Gets handle to the given module via PEB. A low-level equivalent of `GetModuleHandleW`.
|
||||
\param module_name : (optional) the name of the DLL loaded within the current process. If not set, the main module of the current process is used.
|
||||
\return the handle of the DLL with given name, or, if the name was not given, the handle of the main module of the current process.
|
||||
*/
|
||||
HMODULE get_module_via_peb(IN OPTIONAL LPCWSTR module_name = nullptr);
|
||||
|
||||
|
||||
/**
|
||||
Gets size of the given module via PEB.
|
||||
\param hModule : (optional) the base of the module which's size we want to retrieve. If not set, the main module of the current process is used.
|
||||
\return the size of the given module.
|
||||
*/
|
||||
size_t get_module_size_via_peb(IN OPTIONAL HMODULE hModule = nullptr);
|
||||
/**
|
||||
Gets size of the given module via PEB.
|
||||
\param hModule : (optional) the base of the module which's size we want to retrieve. If not set, the main module of the current process is used.
|
||||
\return the size of the given module.
|
||||
*/
|
||||
size_t get_module_size_via_peb(IN OPTIONAL HMODULE hModule = nullptr);
|
||||
|
||||
/**
|
||||
Sets the given module as the main module in the current PEB.
|
||||
\param hModule : the module to be connected to the current PEB.
|
||||
\return true if succeeded, false if failed
|
||||
*/
|
||||
bool set_main_module_in_peb(HMODULE hModule);
|
||||
/**
|
||||
Sets the given module as the main module in the current PEB.
|
||||
\param hModule : the module to be connected to the current PEB.
|
||||
\return true if succeeded, false if failed
|
||||
*/
|
||||
bool set_main_module_in_peb(HMODULE hModule);
|
||||
|
||||
/**
|
||||
Gets the main module from the current PEB.
|
||||
\return the main module connected to the current PEB.
|
||||
*/
|
||||
HMODULE get_main_module_via_peb();
|
||||
/**
|
||||
Gets the main module from the current PEB.
|
||||
\return the main module connected to the current PEB.
|
||||
*/
|
||||
HMODULE get_main_module_via_peb();
|
||||
};
|
||||
|
||||
|
||||
@@ -7,16 +7,17 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
typedef struct _BASE_RELOCATION_ENTRY {
|
||||
typedef struct _BASE_RELOCATION_ENTRY {
|
||||
WORD Offset : 12;
|
||||
WORD Type : 4;
|
||||
} BASE_RELOCATION_ENTRY;
|
||||
} BASE_RELOCATION_ENTRY;
|
||||
|
||||
class RelocBlockCallback
|
||||
{
|
||||
public:
|
||||
class RelocBlockCallback
|
||||
{
|
||||
public:
|
||||
RelocBlockCallback(bool _is64bit)
|
||||
: is64bit(_is64bit)
|
||||
{
|
||||
@@ -24,28 +25,28 @@ namespace peconv {
|
||||
|
||||
virtual bool processRelocField(ULONG_PTR relocField) = 0;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
bool is64bit;
|
||||
};
|
||||
};
|
||||
|
||||
// Processs the relocation table and make your own callback on each relocation field
|
||||
bool process_relocation_table(IN PVOID modulePtr, IN SIZE_T moduleSize, IN RelocBlockCallback *callback);
|
||||
// Processs the relocation table and make your own callback on each relocation field
|
||||
bool process_relocation_table(IN PVOID modulePtr, IN SIZE_T moduleSize, IN RelocBlockCallback *callback);
|
||||
|
||||
/**
|
||||
/**
|
||||
Applies relocations on the PE in virtual format. Relocates it from the old base given to the new base given.
|
||||
If 0 was supplied as the old base, it assumes that the old base is the ImageBase given in the header.
|
||||
\param modulePtr : a buffer containing the PE to be relocated
|
||||
\param moduleSize : the size of the given PE buffer
|
||||
\param newBase : a base to which the PE should be relocated
|
||||
\param oldBase : a base to which the PE is currently relocated (if not set, the imageBase from the header will be used)
|
||||
*/
|
||||
bool relocate_module(IN BYTE* modulePtr, IN SIZE_T moduleSize, IN ULONGLONG newBase, IN ULONGLONG oldBase = 0);
|
||||
*/
|
||||
bool relocate_module(IN BYTE* modulePtr, IN SIZE_T moduleSize, IN ULONGLONG newBase, IN ULONGLONG oldBase = 0);
|
||||
|
||||
/**
|
||||
Checks if the given PE has a valid relocations table.
|
||||
\param modulePtr : a buffer containing the PE to be checked
|
||||
\param moduleSize : the size of the given PE buffer
|
||||
*/
|
||||
bool has_valid_relocation_table(IN const PBYTE modulePtr, IN const size_t moduleSize);
|
||||
/**
|
||||
Checks if the given PE has a valid relocations table.
|
||||
\param modulePtr : a buffer containing the PE to be checked
|
||||
\param moduleSize : the size of the given PE buffer
|
||||
*/
|
||||
bool has_valid_relocation_table(IN const PBYTE modulePtr, IN const size_t moduleSize);
|
||||
|
||||
};//namespace peconv
|
||||
|
||||
@@ -12,123 +12,124 @@
|
||||
#include "exports_mapper.h"
|
||||
#include "pe_dumper.h"
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
bool fetch_region_info(HANDLE processHandle, LPVOID start_addr, MEMORY_BASIC_INFORMATION &page_info);
|
||||
bool fetch_region_info(HANDLE processHandle, LPVOID start_addr, MEMORY_BASIC_INFORMATION &page_info);
|
||||
|
||||
/**
|
||||
Fetch size of the memory region starting from the given address.
|
||||
*/
|
||||
size_t fetch_region_size(HANDLE processHandle, LPVOID start_addr);
|
||||
/**
|
||||
Fetch size of the memory region starting from the given address.
|
||||
*/
|
||||
size_t fetch_region_size(HANDLE processHandle, LPVOID start_addr);
|
||||
|
||||
/**
|
||||
Fetch the allocation base of the memory region with the supplied start address.
|
||||
\param processHandle : handle of the process where the region of interest belongs
|
||||
\param start_addr : the address inside the region of interest
|
||||
\return the allocation base address of the memory region, or 0 if not found
|
||||
*/
|
||||
ULONGLONG fetch_alloc_base(HANDLE processHandle, LPVOID start_addr);
|
||||
/**
|
||||
Fetch the allocation base of the memory region with the supplied start address.
|
||||
\param processHandle : handle of the process where the region of interest belongs
|
||||
\param start_addr : the address inside the region of interest
|
||||
\return the allocation base address of the memory region, or 0 if not found
|
||||
*/
|
||||
ULONGLONG fetch_alloc_base(HANDLE processHandle, LPVOID start_addr);
|
||||
|
||||
/**
|
||||
Wrapper over ReadProcessMemory. Requires a handle with privilege PROCESS_VM_READ.
|
||||
If reading of the full buffer_size was not possible, it will keep trying to read a smaller chunk, decreasing requested size on each attempt,
|
||||
till the minimal_size is reached (it is a workaround for errors such as FAULTY_HARDWARE_CORRUPTED_PAGE).
|
||||
Returns how many bytes were successfuly read.
|
||||
\param processHandle : handle of the process where the memory of interest belongs
|
||||
\param start_addr : the address within the remote process to start reading from
|
||||
\param buffer : the buffer where the read data will be stored
|
||||
\param buffer_size : the size of the buffer, and the size that will be attempted to read
|
||||
\param minimal_size : the minimal size that has to be read in order to consider the read successful
|
||||
\return the number of bytes successfuly read
|
||||
*/
|
||||
size_t read_remote_memory(HANDLE processHandle, LPVOID start_addr, OUT BYTE* buffer, const size_t buffer_size, const SIZE_T minimal_size = 0x100);
|
||||
/**
|
||||
Wrapper over ReadProcessMemory. Requires a handle with privilege PROCESS_VM_READ.
|
||||
If reading of the full buffer_size was not possible, it will keep trying to read a smaller chunk, decreasing requested size on each attempt,
|
||||
till the minimal_size is reached (it is a workaround for errors such as FAULTY_HARDWARE_CORRUPTED_PAGE).
|
||||
Returns how many bytes were successfuly read.
|
||||
\param processHandle : handle of the process where the memory of interest belongs
|
||||
\param start_addr : the address within the remote process to start reading from
|
||||
\param buffer : the buffer where the read data will be stored
|
||||
\param buffer_size : the size of the buffer, and the size that will be attempted to read
|
||||
\param minimal_size : the minimal size that has to be read in order to consider the read successful
|
||||
\return the number of bytes successfuly read
|
||||
*/
|
||||
size_t read_remote_memory(HANDLE processHandle, LPVOID start_addr, OUT BYTE* buffer, const size_t buffer_size, const SIZE_T minimal_size = 0x100);
|
||||
|
||||
/**
|
||||
Reads a single memory region (continuous, with the same access rights) within a given process, starting at the start_addr.
|
||||
In case if it is inaccessible, if the flag force_access was set, it tries to force the access by temporarly changing the permissions.
|
||||
Requires a handle with privilege PROCESS_QUERY_INFORMATION. In order for force_access to work, PROCESS_VM_OPERATION is additionally required.
|
||||
step_size is passed to the underlying read_remote_memory.
|
||||
\param processHandle : handle of the process where the memory of interest belongs
|
||||
\param start_addr : the address within the remote process to start reading from
|
||||
\param buffer : the buffer where the read data will be stored
|
||||
\param buffer_size : the size of the buffer
|
||||
\param force_access : if this flag is set, in case if the region is inaccassible (PAGE_NOACCESS) it will try to force the the read by changing the permissions, and applying the old ones back after reading.
|
||||
WARNING: force_access should be used only on a suspended process, or a process relection, otherwise it may cause instability.
|
||||
\param minimal_size : the minimal size that has to be read in order to consider the read successful (passed to read_remote_memory)
|
||||
\return the number of bytes successfuly read
|
||||
*/
|
||||
size_t read_remote_region(HANDLE processHandle, LPVOID start_addr, OUT BYTE* buffer, const size_t buffer_size, const bool force_access, const SIZE_T minimal_size = 0x100);
|
||||
/**
|
||||
Reads a single memory region (continuous, with the same access rights) within a given process, starting at the start_addr.
|
||||
In case if it is inaccessible, if the flag force_access was set, it tries to force the access by temporarly changing the permissions.
|
||||
Requires a handle with privilege PROCESS_QUERY_INFORMATION. In order for force_access to work, PROCESS_VM_OPERATION is additionally required.
|
||||
step_size is passed to the underlying read_remote_memory.
|
||||
\param processHandle : handle of the process where the memory of interest belongs
|
||||
\param start_addr : the address within the remote process to start reading from
|
||||
\param buffer : the buffer where the read data will be stored
|
||||
\param buffer_size : the size of the buffer
|
||||
\param force_access : if this flag is set, in case if the region is inaccassible (PAGE_NOACCESS) it will try to force the the read by changing the permissions, and applying the old ones back after reading.
|
||||
WARNING: force_access should be used only on a suspended process, or a process relection, otherwise it may cause instability.
|
||||
\param minimal_size : the minimal size that has to be read in order to consider the read successful (passed to read_remote_memory)
|
||||
\return the number of bytes successfuly read
|
||||
*/
|
||||
size_t read_remote_region(HANDLE processHandle, LPVOID start_addr, OUT BYTE* buffer, const size_t buffer_size, const bool force_access, const SIZE_T minimal_size = 0x100);
|
||||
|
||||
/**
|
||||
Reads a full memory area within a given process, starting at the start_addr, till the buffer_size is exceeded.
|
||||
The memory area can consist of multiple regions with various access rights.
|
||||
In case if the region is inaccessible, if the flag force_access was set, it tries to force the access by temporarly changing the permissions.
|
||||
On read failure the region is skipped, and the read is moving to the next one, leaving in the output buffer an empty space of the region size.
|
||||
Requires a handle with privilege PROCESS_QUERY_INFORMATION. In order for force_access to work, PROCESS_VM_OPERATION is additionally required.
|
||||
step_size is passed to the underlying read_remote_memory.
|
||||
\param processHandle : handle of the process where the memory of interest belongs
|
||||
\param start_addr : the address within the remote process to start reading from
|
||||
\param buffer : the buffer where the read data will be stored
|
||||
\param buffer_size : the size of the buffer
|
||||
\param force_access : if this flag is set, in case if the region is inaccassible (PAGE_NOACCESS) it will try to force the the read by changing the permissions, and applying the old ones back after reading.
|
||||
WARNING: force_access should be used only on a suspended process, or a process relection, otherwise it may cause instability.
|
||||
\param minimal_size : the minimal size that has to be read in order to consider the read successful (passed to read_remote_memory)
|
||||
\return the number of bytes successfuly read
|
||||
*/
|
||||
size_t read_remote_area(HANDLE processHandle, LPVOID start_addr, OUT BYTE* buffer, const size_t buffer_size, const bool force_access, const SIZE_T minimal_size = 0x100);
|
||||
/**
|
||||
Reads a full memory area within a given process, starting at the start_addr, till the buffer_size is exceeded.
|
||||
The memory area can consist of multiple regions with various access rights.
|
||||
In case if the region is inaccessible, if the flag force_access was set, it tries to force the access by temporarly changing the permissions.
|
||||
On read failure the region is skipped, and the read is moving to the next one, leaving in the output buffer an empty space of the region size.
|
||||
Requires a handle with privilege PROCESS_QUERY_INFORMATION. In order for force_access to work, PROCESS_VM_OPERATION is additionally required.
|
||||
step_size is passed to the underlying read_remote_memory.
|
||||
\param processHandle : handle of the process where the memory of interest belongs
|
||||
\param start_addr : the address within the remote process to start reading from
|
||||
\param buffer : the buffer where the read data will be stored
|
||||
\param buffer_size : the size of the buffer
|
||||
\param force_access : if this flag is set, in case if the region is inaccassible (PAGE_NOACCESS) it will try to force the the read by changing the permissions, and applying the old ones back after reading.
|
||||
WARNING: force_access should be used only on a suspended process, or a process relection, otherwise it may cause instability.
|
||||
\param minimal_size : the minimal size that has to be read in order to consider the read successful (passed to read_remote_memory)
|
||||
\return the number of bytes successfuly read
|
||||
*/
|
||||
size_t read_remote_area(HANDLE processHandle, LPVOID start_addr, OUT BYTE* buffer, const size_t buffer_size, const bool force_access, const SIZE_T minimal_size = 0x100);
|
||||
|
||||
/**
|
||||
Reads a PE header of the remote module within the given process. Requires a valid output buffer to be supplied (buffer).
|
||||
\param processHandle : handle of the process where the memory of interest belongs
|
||||
\param moduleBase : the base address of the module within the remote process
|
||||
\param buffer : the buffer where the read data will be stored
|
||||
\param buffer_size : the size of the buffer
|
||||
\param force_access : if this flag is set, in case if the region is inaccassible (PAGE_NOACCESS) it will try to force the the read by changing the permissions, and applying the old ones back after reading.
|
||||
WARNING: force_access should be used only on a suspended process, or a process relection, otherwise it may cause instability.
|
||||
*/
|
||||
bool read_remote_pe_header(HANDLE processHandle, LPVOID moduleBase, OUT BYTE* buffer, const size_t bufferSize, bool force_access = false);
|
||||
/**
|
||||
Reads a PE header of the remote module within the given process. Requires a valid output buffer to be supplied (buffer).
|
||||
\param processHandle : handle of the process where the memory of interest belongs
|
||||
\param moduleBase : the base address of the module within the remote process
|
||||
\param buffer : the buffer where the read data will be stored
|
||||
\param buffer_size : the size of the buffer
|
||||
\param force_access : if this flag is set, in case if the region is inaccassible (PAGE_NOACCESS) it will try to force the the read by changing the permissions, and applying the old ones back after reading.
|
||||
WARNING: force_access should be used only on a suspended process, or a process relection, otherwise it may cause instability.
|
||||
*/
|
||||
bool read_remote_pe_header(HANDLE processHandle, LPVOID moduleBase, OUT BYTE* buffer, const size_t bufferSize, bool force_access = false);
|
||||
|
||||
/**
|
||||
Reads a PE section with a given number (sectionNum) from the remote module within the given process.
|
||||
The buffer of appropriate size is automatically allocated. After use, it should be freed by the function free_unaligned.
|
||||
The size of the buffer is writen into sectionSize.
|
||||
\param processHandle : the handle to the remote process
|
||||
\param moduleBase : the base address of the module
|
||||
\param sectionNum : number of the section to be read
|
||||
\param sectionSize : the size of the read section (output)
|
||||
\param roundup : if set, the section size is roundup to the alignment unit
|
||||
\param force_access : if this flag is set, in case if the region is inaccassible (PAGE_NOACCESS) it will try to force the the read by changing the permissions, and applying the old ones back after reading.
|
||||
WARNING: force_access should be used only on a suspended process, or a process relection, otherwise it may cause instability.
|
||||
\return a buffer containing a copy of the section.
|
||||
*/
|
||||
peconv::UNALIGNED_BUF get_remote_pe_section(HANDLE processHandle, LPVOID moduleBase, const size_t sectionNum, OUT size_t §ionSize, bool roundup, bool force_access = false);
|
||||
/**
|
||||
Reads a PE section with a given number (sectionNum) from the remote module within the given process.
|
||||
The buffer of appropriate size is automatically allocated. After use, it should be freed by the function free_unaligned.
|
||||
The size of the buffer is writen into sectionSize.
|
||||
\param processHandle : the handle to the remote process
|
||||
\param moduleBase : the base address of the module
|
||||
\param sectionNum : number of the section to be read
|
||||
\param sectionSize : the size of the read section (output)
|
||||
\param roundup : if set, the section size is roundup to the alignment unit
|
||||
\param force_access : if this flag is set, in case if the region is inaccassible (PAGE_NOACCESS) it will try to force the the read by changing the permissions, and applying the old ones back after reading.
|
||||
WARNING: force_access should be used only on a suspended process, or a process relection, otherwise it may cause instability.
|
||||
\return a buffer containing a copy of the section.
|
||||
*/
|
||||
peconv::UNALIGNED_BUF get_remote_pe_section(HANDLE processHandle, LPVOID moduleBase, const size_t sectionNum, OUT size_t §ionSize, bool roundup, bool force_access = false);
|
||||
|
||||
/**
|
||||
Reads PE file from the remote process into the supplied buffer. It expects the module base and size to be given.
|
||||
*/
|
||||
size_t read_remote_pe(const HANDLE processHandle, LPVOID moduleBase, const size_t moduleSize, OUT BYTE* buffer, const size_t bufferSize);
|
||||
/**
|
||||
Reads PE file from the remote process into the supplied buffer. It expects the module base and size to be given.
|
||||
*/
|
||||
size_t read_remote_pe(const HANDLE processHandle, LPVOID moduleBase, const size_t moduleSize, OUT BYTE* buffer, const size_t bufferSize);
|
||||
|
||||
/**
|
||||
Dumps PE from the remote process into a file. It expects the module base and size to be given.
|
||||
\param outputFilePath : the path where the dump will be saved
|
||||
\param processHandle : the handle to the remote process
|
||||
\param moduleBase : the base address of the module that needs to be dumped
|
||||
\param dump_mode : specifies in which format the PE should be dumped. If the mode was set to PE_DUMP_AUTO, it autodetects mode and returns the detected one.
|
||||
\param exportsMap : optional. If exportsMap is supplied, it will try to recover destroyed import table of the PE, basing on the supplied map of exported functions.
|
||||
*/
|
||||
bool dump_remote_pe(
|
||||
/**
|
||||
Dumps PE from the remote process into a file. It expects the module base and size to be given.
|
||||
\param outputFilePath : the path where the dump will be saved
|
||||
\param processHandle : the handle to the remote process
|
||||
\param moduleBase : the base address of the module that needs to be dumped
|
||||
\param dump_mode : specifies in which format the PE should be dumped. If the mode was set to PE_DUMP_AUTO, it autodetects mode and returns the detected one.
|
||||
\param exportsMap : optional. If exportsMap is supplied, it will try to recover destroyed import table of the PE, basing on the supplied map of exported functions.
|
||||
*/
|
||||
bool dump_remote_pe(
|
||||
IN LPCTSTR outputFilePath,
|
||||
IN const HANDLE processHandle,
|
||||
IN LPVOID moduleBase,
|
||||
IN OUT t_pe_dump_mode &dump_mode,
|
||||
IN OPTIONAL peconv::ExportsMapper* exportsMap = nullptr
|
||||
);
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieve the Image Size saved in the header of the remote PE.
|
||||
\param processHandle : process from where we are reading
|
||||
\param start_addr : a base address of the PE within the given process
|
||||
*/
|
||||
DWORD get_remote_image_size(IN const HANDLE processHandle, IN LPVOID start_addr);
|
||||
/**
|
||||
Retrieve the Image Size saved in the header of the remote PE.
|
||||
\param processHandle : process from where we are reading
|
||||
\param start_addr : a base address of the PE within the given process
|
||||
*/
|
||||
DWORD get_remote_image_size(IN const HANDLE processHandle, IN LPVOID start_addr);
|
||||
|
||||
}; //namespace peconv
|
||||
|
||||
@@ -6,20 +6,21 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
|
||||
namespace peconv {
|
||||
/**
|
||||
A callback that will be executed by the function parse_resources when the Resource Entry was found.
|
||||
*/
|
||||
typedef bool(*t_on_res_entry_found) (
|
||||
namespace peconv
|
||||
{
|
||||
/**
|
||||
A callback that will be executed by the function parse_resources when the Resource Entry was found.
|
||||
*/
|
||||
typedef bool(*t_on_res_entry_found) (
|
||||
BYTE* modulePtr,
|
||||
IMAGE_RESOURCE_DIRECTORY_ENTRY *root_dir,
|
||||
IMAGE_RESOURCE_DATA_ENTRY *curr_entry
|
||||
);
|
||||
);
|
||||
|
||||
/**
|
||||
A function walking through the Resource Tree of the given PE. On each Resource Entry found, the callback is executed.
|
||||
\param modulePtr : pointer to the buffer with the PE in a Virtual format
|
||||
\param on_entry : a callback function executed on each Resource Entry
|
||||
*/
|
||||
bool parse_resources(BYTE* modulePtr, t_on_res_entry_found on_entry);
|
||||
/**
|
||||
A function walking through the Resource Tree of the given PE. On each Resource Entry found, the callback is executed.
|
||||
\param modulePtr : pointer to the buffer with the PE in a Virtual format
|
||||
\param on_entry : a callback function executed on each Resource Entry
|
||||
*/
|
||||
bool parse_resources(BYTE* modulePtr, t_on_res_entry_found on_entry);
|
||||
};
|
||||
|
||||
@@ -8,27 +8,28 @@
|
||||
#include <windows.h>
|
||||
#include "buffer_util.h"
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
const LPSTR RT_RCDATA_A = MAKEINTRESOURCEA(10);
|
||||
const LPSTR RT_RCDATA_A = MAKEINTRESOURCEA(10);
|
||||
|
||||
/**
|
||||
Maps a resource with the given id + type and copies its raw content into the output buffer.
|
||||
If out_size is not zero, it reads maximum out_size of bytes. If out_size is zero, it reads the full resource.
|
||||
The actual read size is returned back in out_size.
|
||||
Automatically allocates a buffer of the required size.
|
||||
If hInstance is NULL, it search the resource in the current module. Otherwise, it search in the given module.
|
||||
*/
|
||||
peconv::ALIGNED_BUF load_resource_data(OUT size_t &out_size, const int res_id, const LPSTR res_type = RT_RCDATA_A, HMODULE hInstance = nullptr);
|
||||
/**
|
||||
Maps a resource with the given id + type and copies its raw content into the output buffer.
|
||||
If out_size is not zero, it reads maximum out_size of bytes. If out_size is zero, it reads the full resource.
|
||||
The actual read size is returned back in out_size.
|
||||
Automatically allocates a buffer of the required size.
|
||||
If hInstance is NULL, it search the resource in the current module. Otherwise, it search in the given module.
|
||||
*/
|
||||
peconv::ALIGNED_BUF load_resource_data(OUT size_t &out_size, const int res_id, const LPSTR res_type = RT_RCDATA_A, HMODULE hInstance = nullptr);
|
||||
|
||||
/**
|
||||
Free the buffer with PE Resources, mapped by the function load_resource_data.
|
||||
*/
|
||||
void free_resource_data(peconv::ALIGNED_BUF buffer);
|
||||
/**
|
||||
Free the buffer with PE Resources, mapped by the function load_resource_data.
|
||||
*/
|
||||
void free_resource_data(peconv::ALIGNED_BUF buffer);
|
||||
|
||||
/**
|
||||
a helper function to get the module handle of the current DLL
|
||||
*/
|
||||
HMODULE get_current_module_handle();
|
||||
/**
|
||||
a helper function to get the module handle of the current DLL
|
||||
*/
|
||||
HMODULE get_current_module_handle();
|
||||
|
||||
}; //namespace peconv
|
||||
|
||||
@@ -8,34 +8,35 @@
|
||||
#include <windows.h>
|
||||
#include<vector>
|
||||
|
||||
namespace peconv {
|
||||
namespace peconv
|
||||
{
|
||||
|
||||
/**
|
||||
A helper function, normalizing virtual addresses. It automatically detects if the given virtual address is VA or RVA, and converts it into RVA
|
||||
\param imgBase : the base address to which the module was relocated
|
||||
\param imgSize : the size of the image
|
||||
\param virtualAddr : the virtual address (RVA or VA) that we want to convert (within the module described by imgBase and imgSize)
|
||||
\param outRVA : the output of the conversion (RVA)
|
||||
\return true if the conversion was successful, false otherwise
|
||||
*/
|
||||
bool virtual_addr_to_rva(IN const ULONGLONG imgBase, IN const DWORD imgSize, IN ULONGLONG virtualAddr, OUT DWORD &outRVA);
|
||||
/**
|
||||
A helper function, normalizing virtual addresses. It automatically detects if the given virtual address is VA or RVA, and converts it into RVA
|
||||
\param imgBase : the base address to which the module was relocated
|
||||
\param imgSize : the size of the image
|
||||
\param virtualAddr : the virtual address (RVA or VA) that we want to convert (within the module described by imgBase and imgSize)
|
||||
\param outRVA : the output of the conversion (RVA)
|
||||
\return true if the conversion was successful, false otherwise
|
||||
*/
|
||||
bool virtual_addr_to_rva(IN const ULONGLONG imgBase, IN const DWORD imgSize, IN ULONGLONG virtualAddr, OUT DWORD &outRVA);
|
||||
|
||||
/**
|
||||
A function listing RVAs of all TLS callbacks that are present in the given module.
|
||||
\param modulePtr : pointer to the buffer with the PE in a Virtual format, relocated to the load base
|
||||
\param moduleSize : size of the given module (if 0 given, the imageSize from the PE headers will be used)
|
||||
\param tls_callbacks : a vector of TLS callbacks addresses (as given in the TLS table)
|
||||
\return number of TLS callbacks added to the list
|
||||
*/
|
||||
size_t list_tls_callbacks(IN PVOID modulePtr, IN size_t moduleSize, OUT std::vector<ULONGLONG> &tls_callbacks);
|
||||
/**
|
||||
A function listing RVAs of all TLS callbacks that are present in the given module.
|
||||
\param modulePtr : pointer to the buffer with the PE in a Virtual format, relocated to the load base
|
||||
\param moduleSize : size of the given module (if 0 given, the imageSize from the PE headers will be used)
|
||||
\param tls_callbacks : a vector of TLS callbacks addresses (as given in the TLS table)
|
||||
\return number of TLS callbacks added to the list
|
||||
*/
|
||||
size_t list_tls_callbacks(IN PVOID modulePtr, IN size_t moduleSize, OUT std::vector<ULONGLONG> &tls_callbacks);
|
||||
|
||||
/**
|
||||
A function running all the TLS callbacks that are present in the given module, one by one.
|
||||
\param modulePtr : pointer to the buffer with the PE in a Virtual format, relocated to the load base
|
||||
\param moduleSize : size of the given module (if 0 given, the imageSize from the PE headers will be used)
|
||||
\param dwReason : a parameter (dwReason) that will be passed to the callback function
|
||||
\return number of TLS callbacks executed
|
||||
*/
|
||||
size_t run_tls_callbacks(IN PVOID modulePtr, IN size_t moduleSize=0, IN DWORD dwReason = DLL_PROCESS_ATTACH);
|
||||
/**
|
||||
A function running all the TLS callbacks that are present in the given module, one by one.
|
||||
\param modulePtr : pointer to the buffer with the PE in a Virtual format, relocated to the load base
|
||||
\param moduleSize : size of the given module (if 0 given, the imageSize from the PE headers will be used)
|
||||
\param dwReason : a parameter (dwReason) that will be passed to the callback function
|
||||
\return number of TLS callbacks executed
|
||||
*/
|
||||
size_t run_tls_callbacks(IN PVOID modulePtr, IN size_t moduleSize=0, IN DWORD dwReason = DLL_PROCESS_ATTACH);
|
||||
|
||||
}; //namespace peconv
|
||||
|
||||
@@ -19,33 +19,34 @@
|
||||
#endif
|
||||
|
||||
|
||||
namespace peconv {
|
||||
/**
|
||||
Checks if the given buffer is fully filled with the specified character.
|
||||
\param cave_ptr : pointer to the buffer to be checked
|
||||
\param cave_size : size of the buffer to be checked
|
||||
\param padding_char : the required character
|
||||
*/
|
||||
bool is_padding(const BYTE* cave_ptr, size_t cave_size, const BYTE padding_char);
|
||||
namespace peconv
|
||||
{
|
||||
/**
|
||||
Checks if the given buffer is fully filled with the specified character.
|
||||
\param cave_ptr : pointer to the buffer to be checked
|
||||
\param cave_size : size of the buffer to be checked
|
||||
\param padding_char : the required character
|
||||
*/
|
||||
bool is_padding(const BYTE* cave_ptr, size_t cave_size, const BYTE padding_char);
|
||||
|
||||
/**
|
||||
Wrapper for GetProcessId - for a backward compatibility with old versions of Windows
|
||||
*/
|
||||
DWORD get_process_id(HANDLE hProcess);
|
||||
/**
|
||||
Wrapper for GetProcessId - for a backward compatibility with old versions of Windows
|
||||
*/
|
||||
DWORD get_process_id(HANDLE hProcess);
|
||||
|
||||
/**
|
||||
Verifies if the calling process has a defined access to the specified continuous range of memory, defined by areaStart and areaSize.
|
||||
If the area includes pages that are not commited, or pages with access rights PAGE_GUARD | PAGE_NOACCESS, it is treated as inaccessible.
|
||||
\param areaStart : A pointer to the first byte of the memory block
|
||||
\param areaSize : The size of the memory block, in bytes. If this parameter is zero, the return value is false.
|
||||
\param accessRights : The access rights to be checked
|
||||
*/
|
||||
bool is_mem_accessible(LPCVOID areaStart, SIZE_T areaSize, DWORD accessRights);
|
||||
/**
|
||||
Verifies if the calling process has a defined access to the specified continuous range of memory, defined by areaStart and areaSize.
|
||||
If the area includes pages that are not commited, or pages with access rights PAGE_GUARD | PAGE_NOACCESS, it is treated as inaccessible.
|
||||
\param areaStart : A pointer to the first byte of the memory block
|
||||
\param areaSize : The size of the memory block, in bytes. If this parameter is zero, the return value is false.
|
||||
\param accessRights : The access rights to be checked
|
||||
*/
|
||||
bool is_mem_accessible(LPCVOID areaStart, SIZE_T areaSize, DWORD accessRights);
|
||||
|
||||
/**
|
||||
Verifies that the calling process has read access to the specified range of memory.
|
||||
\param areaStart : A pointer to the first byte of the memory block
|
||||
\param areaSize : The size of the memory block, in bytes. If this parameter is zero, the return value is true (bad pointer).
|
||||
*/
|
||||
bool is_bad_read_ptr(LPCVOID areaStart, SIZE_T areaSize);
|
||||
/**
|
||||
Verifies that the calling process has read access to the specified range of memory.
|
||||
\param areaStart : A pointer to the first byte of the memory block
|
||||
\param areaSize : The size of the memory block, in bytes. If this parameter is zero, the return value is true (bad pointer).
|
||||
*/
|
||||
bool is_bad_read_ptr(LPCVOID areaStart, SIZE_T areaSize);
|
||||
};
|
||||
@@ -159,8 +159,7 @@ bool is_supported_pe(BYTE *my_exe, size_t exe_size)
|
||||
if (has_tls_callbacks<IMAGE_TLS_DIRECTORY32>(my_exe, exe_size)) {
|
||||
has_callback = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (has_tls_callbacks<IMAGE_TLS_DIRECTORY64>(my_exe, exe_size)) {
|
||||
has_callback = true;
|
||||
}
|
||||
@@ -218,8 +217,7 @@ int pe_2_shellcode(const std::string &in_path, const std::string &out_str)
|
||||
ULONGLONG current_base = peconv::get_image_base(ext_buf);
|
||||
if (peconv::dump_pe(out_str.c_str(), ext_buf, ext_size, current_base, dump_mode)) {
|
||||
std::cout << "[INFO] Saved as: " << out_str << std::endl;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
std::cerr << "[ERROR] Failed to save the output!" << std::endl;
|
||||
}
|
||||
peconv::free_pe_buffer(my_exe);
|
||||
@@ -229,7 +227,8 @@ int pe_2_shellcode(const std::string &in_path, const std::string &out_str)
|
||||
|
||||
#else
|
||||
|
||||
int pe_2_shellcode(const std::string& in_path, const std::string& out_str) {
|
||||
int pe_2_shellcode(const std::string& in_path, const std::string& out_str)
|
||||
{
|
||||
return -1; // Don't support x86 master program
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -56,6 +56,7 @@
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -72,6 +73,7 @@
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<DisableSpecificWarnings>4018;4244;4267;4819</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
||||
Reference in New Issue
Block a user