Skip to content

Commit

Permalink
dpVS2012
Browse files Browse the repository at this point in the history
  • Loading branch information
i-saint committed Nov 15, 2013
1 parent fc7ce1d commit aa1c84b
Show file tree
Hide file tree
Showing 22 changed files with 1,012 additions and 82 deletions.
77 changes: 76 additions & 1 deletion DynamicPatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#pragma comment(lib,"disasm" dpLibArch ".lib")
#endif // dpWithTDisasm


static dpContext *g_dpDefaultContext = nullptr;
static __declspec(thread) dpContext *g_dpCurrentContext = nullptr;

Expand Down Expand Up @@ -221,3 +220,79 @@ dpAPI const char* dpGetVCVarsPath()
{
return dpGetCurrentContext()->getBuilder()->getVCVarsPath();
}


#include <tlhelp32.h>

// F: [](DWORD thread_id)->void
template<class F>
inline void dpEnumerateThreads(DWORD pid, const F &f)
{
HANDLE ss = ::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if(ss!=INVALID_HANDLE_VALUE) {
THREADENTRY32 te;
te.dwSize = sizeof(te);
if(::Thread32First(ss, &te)) {
do {
if(te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID)+sizeof(te.th32OwnerProcessID) &&
te.th32OwnerProcessID==pid)
{
f(te.th32ThreadID);
}
te.dwSize = sizeof(te);
} while(::Thread32Next(ss, &te));
}
::CloseHandle(ss);
}
}

void dpExecExclusive(const std::function<void ()> &f)
{
std::vector<HANDLE> threads;
DWORD pid = ::GetCurrentProcessId();
dpEnumerateThreads(pid, [&](DWORD tid){
if(tid==::GetCurrentThreadId()) { return; }
if(HANDLE thread=::OpenThread(THREAD_ALL_ACCESS, FALSE, tid)) {
::SuspendThread(thread);
threads.push_back(thread);
}
});
f();
std::for_each(threads.begin(), threads.end(), [](HANDLE thread){
::ResumeThread(thread);
::CloseHandle(thread);
});
}


bool g_dp_stop_periodic_update = false;
bool g_dp_periodic_update_running = false;

unsigned __stdcall dpPeriodicUpdate(void *)
{
while(!g_dp_stop_periodic_update) {
dpExecExclusive([&](){ dpUpdate(); });
::Sleep(1000);
}
g_dp_periodic_update_running = false;
return 0;
}

dpAPI void dpBeginPeriodicUpdate()
{
dpExecExclusive([&](){ dpInitialize(); });
g_dp_stop_periodic_update = false;
g_dp_periodic_update_running = true;
// std::thread 使いたいが VS2010 対応を考慮して使わない方向で
_beginthreadex(nullptr, 0, &dpPeriodicUpdate, nullptr, 0, nullptr);
}

dpAPI void dpEndPeriodicUpdate()
{
if(g_dp_periodic_update_running) {
g_dp_stop_periodic_update = true;
while(!g_dp_periodic_update_running) {
::SwitchToThread();
}
}
}
2 changes: 2 additions & 0 deletions DynamicPatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ struct dpConfig
vc_ver = 2010;
#elif _MSC_VER==1700
vc_ver = 2012;
#elif _MSC_VER==1800
vc_ver = 2013;
#endif
}
};
Expand Down
194 changes: 194 additions & 0 deletions DynamicPatcher2012.sln

Large diffs are not rendered by default.

91 changes: 17 additions & 74 deletions DynamicPatcherInjector.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
// created by i-saint
// distributed under Creative Commons Attribution (CC BY) license.
// https://github.com/i-saint/DynamicPatcher

#pragma comment(lib, "psapi.lib")
#include <windows.h>
#include <psapi.h>
#include "windows.h"
#include <string>
#include "dpInternal.h"

#ifdef _M_IX64
# define InjectorDLL "DynamicPatcherInjectorDLL64.dll"
Expand All @@ -16,11 +9,6 @@
# define PatcherDLL "DynamicPatcher.dll"
#endif // _M_IX64

dpConfigFile g_option;

// VirtualAllocEx で dll の path を対象プロセスに書き込み、
// CreateRemoteThread で対象プロセスにスレッドを作って、↑で書き込んだ dll path をパラメータにして LoadLibraryA を呼ぶ。
// 結果、対象プロセス内で任意の dll を実行させる。
bool InjectDLL(HANDLE hProcess, const char* dllname)
{
SIZE_T bytesRet = 0;
Expand All @@ -41,72 +29,27 @@ bool InjectDLL(HANDLE hProcess, const char* dllname)
return true;
}

bool TryInject(const char *process_name, const char *dllname)
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prev, LPWSTR cmd, int show)
{
char dll_fullpath[MAX_PATH];
DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;
if(!::GetFullPathNameA(dllname, _countof(dll_fullpath), dll_fullpath, nullptr)) {
return false;
}

if(!::EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) {
return false;
}

cProcesses = cbNeeded / sizeof(DWORD);
for(i=0; i<cProcesses; i++) {
if( aProcesses[i] == 0 ) { continue; }
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, aProcesses[i]);
if(hProcess==NULL) { continue; }

char szProcessName[MAX_PATH] = "\0";
HMODULE hMod;
DWORD cbNeeded2;
if(::EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded2)) {
::GetModuleBaseNameA(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR));
if( strstr(szProcessName, process_name)!=NULL) {
if(InjectDLL(hProcess, dll_fullpath)) {
printf("injection complete: %s -> %s\n", dllname, process_name);
fflush(stdout);
return true;
}
}
}
::CloseHandle(hProcess);
}

return false;
}

std::wstring exe_path = __wargv[1];
const char dll_path[MAX_PATH] = InjectorDLL;

int main(int argc, char *argv[])
{
if(argc<2) {
printf("usage: DynamicPatcherInjector [target_proces.exe] [config_file.dpconf(optional)]\n");
return 1;
DWORD flags = NORMAL_PRIORITY_CLASS;
if(__argc>=3 && wcscmp(__wargv[2], L"/suspended")==0) {
flags |= CREATE_SUSPENDED;
}

bool ok = true;
if(argc>=3) { ok=g_option.load(argv[2]) ;}
else { ok=g_option.load(); }
if(!ok) {
printf("config file could not read.\n");
return 1;
STARTUPINFOW si;
PROCESS_INFORMATION pi;
::ZeroMemory(&si, sizeof(si));
::ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
BOOL ret = ::CreateProcessW(nullptr, (wchar_t*)exe_path.c_str(), nullptr, nullptr, FALSE,
flags, nullptr, nullptr, &si, &pi);
if(ret) {
InjectDLL(pi.hProcess, dll_path);
return pi.dwProcessId;
}

const char *target_process = argv[1];
char exe_path[MAX_PATH];
std::string exe_dir;
dpGetMainModulePath(exe_path, _countof(exe_path));
dpSeparateDirFile(exe_path, &exe_dir, nullptr);

if(TryInject(target_process, (exe_dir+PatcherDLL).c_str())) {
std::string conf_path;
dpSeparateFileExt(target_process, &conf_path, nullptr);
conf_path += "dpconf";
g_option.copy(conf_path.c_str());
TryInject(target_process, (exe_dir+InjectorDLL).c_str());
}
return 0;
}
8 changes: 4 additions & 4 deletions DynamicPatcherInjector2012.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
<PreprocessorDefinitions>dpNoLib;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
Expand All @@ -135,7 +135,7 @@
<PreprocessorDefinitions>dpNoLib;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
Expand All @@ -154,7 +154,7 @@
<PreprocessorDefinitions>dpNoLib;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
</Link>
<PostBuildEvent>
Expand All @@ -172,7 +172,7 @@
<PreprocessorDefinitions>dpNoLib;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
</Link>
<PostBuildEvent>
Expand Down
7 changes: 4 additions & 3 deletions DynamicPatcherInjectorDLL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@

#include <windows.h>

#define dpLinkDynamic
#include "DynamicPatcher.h"
dpAPI void dpBeginPeriodicUpdate();
dpAPI void dpEndPeriodicUpdate();

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if(fdwReason==DLL_PROCESS_ATTACH) {
dpInitialize();
dpBeginPeriodicUpdate();
}
else if(fdwReason==DLL_PROCESS_DETACH) {
dpFinalize();
dpEndPeriodicUpdate();
}
return TRUE;
}
1 change: 1 addition & 0 deletions dpFoundation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,3 +572,4 @@ dpSymbol* dpSymbolTable::findSymbolByAddress( void *addr )
}
return nullptr;
}

51 changes: 51 additions & 0 deletions dpVS2012/dpVS/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System.Reflection;
using System.Runtime.CompilerServices;

//
// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。
// アセンブリに関連付けられている情報を変更するには、
// これらの属性値を変更してください。
//
[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

//
// アセンブリのバージョン情報は、以下の 4 つの値で構成されています:
//
// Major Version
// Minor Version
// Revision
// Build Number
//
// すべての値を指定するか、下のように '*' を使ってリビジョンおよびビルド番号を
// 既定値にすることができます:

[assembly: AssemblyVersion("1.0.*")]

//
// アセンブリに署名するには、使用するキーを指定しなければなりません。アセンブリ署名に関する
// 詳細については、Microsoft .NET Framework ドキュメントを参照してください。
//
// 下の属性を使用して、署名に使用されるキーを制御します。
//
// メモ:
// (*) キーが指定されないと、アセンブリは署名されません。
// (*) KeyName は、コンピューターにインストールされている暗号サービス プロバイダー (CSP) を
// 表します。
// (*) キー ファイルおよびキー名の属性が共に指定されている場合は、
// 以下の処理が行われます:
// (1) KeyName が CSP に見つかった場合、そのキーが使われます。
// (2) KeyName が存在せず、KeyFile が存在する場合、
// ファイルにあるキーが CSP にインストールされ、使われます。
// (*) 遅延署名は高度なオプションです - Microsoft .NET Framework
// ドキュメントを参照してください。
//
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]
Loading

0 comments on commit aa1c84b

Please sign in to comment.