diff --git a/AppGame.sln b/AppGame.sln new file mode 100644 index 0000000..d3fbe3d --- /dev/null +++ b/AppGame.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32421.90 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "InjectAssembly", "InjectAssembly\InjectAssembly.vcxproj", "{679C01AF-C56D-49E2-A823-FA17A7F6A979}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TragetAssembly2", "TragetAssembly2\TragetAssembly2.csproj", "{27DEE685-15F5-44AF-9A55-BD61D7535553}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {679C01AF-C56D-49E2-A823-FA17A7F6A979}.Debug|Any CPU.ActiveCfg = Debug|x64 + {679C01AF-C56D-49E2-A823-FA17A7F6A979}.Debug|Any CPU.Build.0 = Debug|x64 + {679C01AF-C56D-49E2-A823-FA17A7F6A979}.Debug|x64.ActiveCfg = Debug|x64 + {679C01AF-C56D-49E2-A823-FA17A7F6A979}.Debug|x64.Build.0 = Debug|x64 + {679C01AF-C56D-49E2-A823-FA17A7F6A979}.Debug|x86.ActiveCfg = Debug|Win32 + {679C01AF-C56D-49E2-A823-FA17A7F6A979}.Debug|x86.Build.0 = Debug|Win32 + {679C01AF-C56D-49E2-A823-FA17A7F6A979}.Release|Any CPU.ActiveCfg = Release|x64 + {679C01AF-C56D-49E2-A823-FA17A7F6A979}.Release|Any CPU.Build.0 = Release|x64 + {679C01AF-C56D-49E2-A823-FA17A7F6A979}.Release|x64.ActiveCfg = Release|x64 + {679C01AF-C56D-49E2-A823-FA17A7F6A979}.Release|x64.Build.0 = Release|x64 + {679C01AF-C56D-49E2-A823-FA17A7F6A979}.Release|x86.ActiveCfg = Release|Win32 + {679C01AF-C56D-49E2-A823-FA17A7F6A979}.Release|x86.Build.0 = Release|Win32 + {27DEE685-15F5-44AF-9A55-BD61D7535553}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {27DEE685-15F5-44AF-9A55-BD61D7535553}.Debug|Any CPU.Build.0 = Debug|Any CPU + {27DEE685-15F5-44AF-9A55-BD61D7535553}.Debug|x64.ActiveCfg = Debug|Any CPU + {27DEE685-15F5-44AF-9A55-BD61D7535553}.Debug|x64.Build.0 = Debug|Any CPU + {27DEE685-15F5-44AF-9A55-BD61D7535553}.Debug|x86.ActiveCfg = Debug|Any CPU + {27DEE685-15F5-44AF-9A55-BD61D7535553}.Debug|x86.Build.0 = Debug|Any CPU + {27DEE685-15F5-44AF-9A55-BD61D7535553}.Release|Any CPU.ActiveCfg = Release|Any CPU + {27DEE685-15F5-44AF-9A55-BD61D7535553}.Release|Any CPU.Build.0 = Release|Any CPU + {27DEE685-15F5-44AF-9A55-BD61D7535553}.Release|x64.ActiveCfg = Release|Any CPU + {27DEE685-15F5-44AF-9A55-BD61D7535553}.Release|x64.Build.0 = Release|Any CPU + {27DEE685-15F5-44AF-9A55-BD61D7535553}.Release|x86.ActiveCfg = Release|Any CPU + {27DEE685-15F5-44AF-9A55-BD61D7535553}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E6F22F6F-A63B-4481-AD55-A1E9FFA500FC} + EndGlobalSection +EndGlobal diff --git a/InjectAssembly/ExecuteAssembly.h b/InjectAssembly/ExecuteAssembly.h new file mode 100644 index 0000000..693353f --- /dev/null +++ b/InjectAssembly/ExecuteAssembly.h @@ -0,0 +1,252 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include + +#import "D:\Program Files\Microsoft Visual Studio\2022\Professional\mscorlib.tlb" auto_rename +using namespace mscorlib; + +#pragma optimize( "", off ) + + +__forceinline void f_memcpy(char* dst, const char* src, size_t size) +{ + const char* psrc; + char* pdst; + psrc = src + size - 1; + pdst = dst + size - 1; + while (size--) { + *pdst-- = *psrc--; + } +} +__forceinline void f_memset(char* ptr, int v, size_t len) +{ + for (int i = 0; i < len; i++) + { + *(PBYTE)(ptr + i) = v; + } +} + + +typedef NTSTATUS(WINAPI* LdrGetProcedureAddressT)(IN PVOID DllHandle, IN PANSI_STRING ProcedureName OPTIONAL, IN ULONG ProcedureNumber OPTIONAL, OUT FARPROC* ProcedureAddress); +typedef VOID(WINAPI* RtlFreeUnicodeStringT)(_Inout_ PUNICODE_STRING UnicodeString); +typedef VOID(WINAPI* RtlInitAnsiStringT)(_Out_ PANSI_STRING DestinationString, _In_opt_ PCSZ SourceString); +typedef VOID(WINAPI* RtlInitUnicodeStringT)(_Out_ PUNICODE_STRING DestinationString, _In_opt_ PCWSTR SourceString); +typedef VOID(WINAPI* RtlFreeAnsiStringT)(PANSI_STRING AnsiString); + +typedef NTSTATUS(WINAPI* RtlAnsiStringToUnicodeStringT)(_Inout_ PUNICODE_STRING DestinationString, _In_ PCANSI_STRING SourceString, _In_ BOOLEAN AllocateDestinationString); +typedef NTSTATUS(WINAPI* LdrLoadDllT)(PWCHAR, PULONG, PUNICODE_STRING, PHANDLE); +typedef BOOL(APIENTRY* ProcDllMain)(LPVOID, DWORD, LPVOID); +typedef NTSTATUS(WINAPI* NtAllocateVirtualMemoryT)(IN HANDLE ProcessHandle, IN OUT PVOID* BaseAddress, IN ULONG ZeroBits, IN OUT PSIZE_T RegionSize, IN ULONG AllocationType, IN ULONG Protect); + +typedef HRESULT(WINAPI* FCLRCreateInstance)(REFCLSID clsid, REFIID riid, LPVOID* ppInterface); +typedef SAFEARRAY*(WINAPI* FSafeArrayCreate)(_In_ VARTYPE vt, _In_ UINT cDims, _In_ SAFEARRAYBOUND* rgsabound); +typedef HRESULT(WINAPI* FSafeArrayAccessData)(_In_ SAFEARRAY* psa, _Outptr_result_buffer_(_Inexpressible_(psa->cbElements* product(psa->rgsabound[0..psa->cDims - 1]->cElements))) void HUGEP** ppvData); +typedef HRESULT(WINAPI* FSafeArrayUnaccessData)(_In_ SAFEARRAY* psa); +typedef SAFEARRAY*(WINAPI* FSafeArrayCreateVector)(_In_ VARTYPE vt, _In_ LONG lLbound, _In_ ULONG cElements); +typedef BSTR(WINAPI* FSysAllocString)(_In_opt_z_ const OLECHAR* psz); +typedef HRESULT(WINAPI* FSafeArrayPutElement)(_In_ SAFEARRAY* psa, _In_reads_(_Inexpressible_(psa->cDims)) LONG* rgIndices, _In_ void* pv); +typedef void (WINAPI* FSysFreeString)(_In_opt_ BSTR bstrString); + +struct PARAMX +{ + PVOID lpFileData; + DWORD DataLength; + WCHAR szArgument[512]; + LdrGetProcedureAddressT LdrGetProcedureAddress; + NtAllocateVirtualMemoryT NtAllocateVirtualMemory; + LdrLoadDllT LdrLoadDll; + RtlInitUnicodeStringT RtlInitUnicodeString; + RtlInitAnsiStringT RtlInitAnsiString; + RtlFreeAnsiStringT RtlFreeAnsiString; + RtlAnsiStringToUnicodeStringT RtlAnsiStringToUnicodeString; + RtlFreeUnicodeStringT RtlFreeUnicodeString; +}; + +int WINAPI ExecuteAssembly(PARAMX* Param) +{ + HRESULT hr; + + ICLRMetaHost* pMetaHost = NULL; + ICLRRuntimeInfo* pRuntimeInfo = NULL; + BOOL bLoadable; + ICorRuntimeHost* pRuntimeHost; + SAFEARRAYBOUND rgsabound[1]; + VARIANT retVal; + VARIANT obj; + SAFEARRAY* psaStaticMethodArgs; + VARIANT vtPsa; + + HANDLE hDll = 0; + UNICODE_STRING UnicodeString; + ANSI_STRING AnsiString; + + IUnknown* pAppDomainThunk; + //intptr_t pDefaultAppDomain; + _AppDomain* pDefaultAppDomain; + _Assembly* pAssembly; + _MethodInfo* pMethodInfo; + + + + FSafeArrayCreate pSafeArrayCreate; + FSafeArrayAccessData pSafeArrayAccessData; + FSafeArrayUnaccessData pSafeArrayUnaccessData; + FSafeArrayCreateVector pSafeArrayCreateVector; + FSysAllocString pSysAllocString; + FSafeArrayPutElement pSafeArrayPutElement; + FSysFreeString pSysFreeString; + //Oleaut32.dll + const WCHAR szOleaut32_dll[] = { 0x004F,0x006C,0x0065,0x0061,0x0075,0x0074,0x0033,0x0032,0x002E,0x0064,0x006C,0x006C,0x0000 }; + Param->RtlInitUnicodeString(&UnicodeString, szOleaut32_dll); + Param->LdrLoadDll(NULL, NULL, &UnicodeString, &hDll); + + + //SafeArrayCreate + const CHAR szSafeArrayCreate[] = { 0x53,0x61,0x66,0x65,0x41,0x72,0x72,0x61,0x79,0x43,0x72,0x65,0x61,0x74,0x65,0x00 }; + Param->RtlInitAnsiString(&AnsiString, szSafeArrayCreate); + Param->LdrGetProcedureAddress(hDll, &AnsiString, 0, (FARPROC*)&pSafeArrayCreate); + + + //SafeArrayAccessData + const CHAR szSafeArrayAccessData[] = { 0x53,0x61,0x66,0x65,0x41,0x72,0x72,0x61,0x79,0x41,0x63,0x63,0x65,0x73,0x73,0x44,0x61,0x74,0x61,0x00 }; + Param->RtlInitAnsiString(&AnsiString, szSafeArrayAccessData); + Param->LdrGetProcedureAddress(hDll, &AnsiString, 0, (FARPROC*)&pSafeArrayAccessData); + + + //SafeArrayUnaccessData + const CHAR szSafeArrayUnaccessData[] = { 0x53,0x61,0x66,0x65,0x41,0x72,0x72,0x61,0x79,0x55,0x6E,0x61,0x63,0x63,0x65,0x73,0x73,0x44,0x61,0x74,0x61,0x00 }; + Param->RtlInitAnsiString(&AnsiString, szSafeArrayUnaccessData); + Param->LdrGetProcedureAddress(hDll, &AnsiString, 0, (FARPROC*)&pSafeArrayUnaccessData); + + + //SafeArrayCreateVector + const CHAR szSafeArrayCreateVector[] = { 0x53,0x61,0x66,0x65,0x41,0x72,0x72,0x61,0x79,0x43,0x72,0x65,0x61,0x74,0x65,0x56,0x65,0x63,0x74,0x6F,0x72,0x00 }; + Param->RtlInitAnsiString(&AnsiString, szSafeArrayCreateVector); + Param->LdrGetProcedureAddress(hDll, &AnsiString, 0, (FARPROC*)&pSafeArrayCreateVector); + + + //SysAllocString + const CHAR szSysAllocString[] = { 0x53,0x79,0x73,0x41,0x6C,0x6C,0x6F,0x63,0x53,0x74,0x72,0x69,0x6E,0x67,0x00 }; + Param->RtlInitAnsiString(&AnsiString, szSysAllocString); + Param->LdrGetProcedureAddress(hDll, &AnsiString, 0, (FARPROC*)&pSysAllocString); + + + //SafeArrayPutElement + const CHAR szSafeArrayPutElement[] = { 0x53,0x61,0x66,0x65,0x41,0x72,0x72,0x61,0x79,0x50,0x75,0x74,0x45,0x6C,0x65,0x6D,0x65,0x6E,0x74,0x00 }; + Param->RtlInitAnsiString(&AnsiString, szSafeArrayPutElement); + Param->LdrGetProcedureAddress(hDll, &AnsiString, 0, (FARPROC*)&pSafeArrayPutElement); + + + //SysFreeString + const CHAR szSysFreeString[] = { 0x53,0x79,0x73,0x46,0x72,0x65,0x65,0x53,0x74,0x72,0x69,0x6E,0x67,0x00 }; + Param->RtlInitAnsiString(&AnsiString, szSysFreeString); + Param->LdrGetProcedureAddress(hDll, &AnsiString, 0, (FARPROC*)&pSysFreeString); + + + + + rgsabound[0].cElements = Param->DataLength; + rgsabound[0].lLbound = 0; + SAFEARRAY* pSafeArray = pSafeArrayCreate(VT_UI1, 1, rgsabound); + void* pvData = NULL; + + hr = pSafeArrayAccessData(pSafeArray, &pvData); + f_memcpy((char*)pvData, (char*)Param->lpFileData, Param->DataLength); + hr = pSafeArrayUnaccessData(pSafeArray); + + //mscoree.dll + const WCHAR szMscoree_dll[] = { 0x006D,0x0073,0x0063,0x006F,0x0072,0x0065,0x0065,0x002E,0x0064,0x006C,0x006C,0x0000 }; + + FCLRCreateInstance pCLRCreateInstance; + + Param->RtlInitUnicodeString(&UnicodeString, szMscoree_dll); + Param->LdrLoadDll(NULL, NULL, &UnicodeString, &hDll); + + + //CLRCreateInstance + const CHAR szCLRCreateInstance[] = { 0x43,0x4C,0x52,0x43,0x72,0x65,0x61,0x74,0x65,0x49,0x6E,0x73,0x74,0x61,0x6E,0x63,0x65,0x00 }; + Param->RtlInitAnsiString(&AnsiString, szCLRCreateInstance); + Param->LdrGetProcedureAddress(hDll, &AnsiString, 0, (FARPROC*)&pCLRCreateInstance); + + + GUID _CLSID_CLRMetaHost = { 0x9280188d, 0xe8e, 0x4867, { 0xb3, 0xc, 0x7f, 0xa8, 0x38, 0x84, 0xe8, 0xde } }; + GUID _IID_ICLRMetaHost = { 0xd332db9e, 0xb9b3,0x4125, {0x82,0x07,0xa1,0x48,0x84,0xf5,0x32,0x16 } }; + hr = pCLRCreateInstance(_CLSID_CLRMetaHost, _IID_ICLRMetaHost, (VOID**)&pMetaHost); + + //v4.0.30319 + const WCHAR szv4_0_30319[] = { 0x0076,0x0034,0x002E,0x0030,0x002E,0x0033,0x0030,0x0033,0x0031,0x0039,0x0000 }; + GUID _IID_ICLRRuntimeInfo = { 0xbd39d1d2, 0xba2f, 0x486a, { 0x89,0xb0,0xb4,0xb0,0xcb,0x46,0x68,0x91 } }; + hr = pMetaHost->GetRuntime(szv4_0_30319, _IID_ICLRRuntimeInfo, (VOID**)&pRuntimeInfo); + if (FAILED(hr)) return -1; + + hr = pRuntimeInfo->IsLoadable(&bLoadable); + + if (FAILED(hr) || !bLoadable) + { + return -1; + } + GUID _CLSID_CorRuntimeHost = { 0xcb2f6723, 0xab3a, 0x11d2, {0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e} }; + GUID _IID_ICorRuntimeHost = { 0xcb2f6722, 0xab3a, 0x11d2, {0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e} }; + hr = pRuntimeInfo->GetInterface(_CLSID_CorRuntimeHost, _IID_ICorRuntimeHost, (VOID**)&pRuntimeHost); + if (FAILED(hr)) return -1; + + hr = pRuntimeHost->Start(); + if (FAILED(hr)) return -1; + + hr = pRuntimeHost->GetDefaultDomain(&pAppDomainThunk); + if (FAILED(hr)) return -1; + + //05f696dc_2b29_3663_ad8b_c4389cf2a713 + GUID _IID_AppDomain = { 0x05f696dc, 0x2b29, 0x3663, {0xad,0x8b,0xc4,0x38,0x9c,0xf2,0xa7,0x13} }; + hr = pAppDomainThunk->QueryInterface(_IID_AppDomain, (VOID**)&pDefaultAppDomain); + if (FAILED(hr)) return -1; + + hr = pDefaultAppDomain->raw_Load_3(pSafeArray,&pAssembly); + if (FAILED(hr)) return -1; + + + + hr = pAssembly->get_EntryPoint(&pMethodInfo); + if (FAILED(hr)) return -1; + + f_memset((char*)&retVal,0, sizeof(VARIANT)); + f_memset((char*)&obj,0, sizeof(VARIANT)); + + + //ֵvoid String ĺ + obj.vt = VT_NULL; + vtPsa.vt = (VT_ARRAY | VT_BSTR); + + psaStaticMethodArgs = pSafeArrayCreateVector(VT_VARIANT, 0, 1); + vtPsa.parray = pSafeArrayCreateVector(VT_BSTR, 0, 1); + long index = 0; + BSTR strParam1 = pSysAllocString(Param->szArgument); + hr = pSafeArrayPutElement(vtPsa.parray, &index, strParam1); + if (FAILED(hr)) return -1; + + + long iEventCdIdx(0); + hr = pSafeArrayPutElement(psaStaticMethodArgs, &iEventCdIdx, &vtPsa); + if (FAILED(hr)) return -1; + + //Assembly execution + hr = pMethodInfo->raw_Invoke_3(obj, psaStaticMethodArgs,&retVal); + + pSysFreeString(strParam1); + + return 0; +}; + + +FunctionEndFlag(ExecuteAssembly) + +#pragma optimize( "", on ) + + diff --git a/InjectAssembly/InjectAssembly.cpp b/InjectAssembly/InjectAssembly.cpp new file mode 100644 index 0000000..b9e9f65 --- /dev/null +++ b/InjectAssembly/InjectAssembly.cpp @@ -0,0 +1,229 @@ +// InjectAssembly.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 +// + +#include +#include "LHCommon.h" +#include "ExecuteAssembly.h" + + +BOOL InjectRometeDll(DWORD dwProcessId,LPCTSTR szFilePath, LPCTSTR szArg) +{ + BOOL bResult = FALSE; + HANDLE hProcess = NULL; + HANDLE hThread = NULL; + HANDLE hFile = NULL; + PSTR pRemoteMemory = NULL; + SIZE_T cch; + __try + { + printf("dwProcessId:%08X\n", dwProcessId); + // 获得想要注入代码的进程的句柄. + hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); + printf("OpenProcess:%p\n", hProcess); + if (hProcess == NULL) + { + printf("[错误] OpenProcess(%d) 调用失败!错误代码: [%d]\n", dwProcessId, GetLastError()); + __leave; + } + + HANDLE hFile = CreateFileW(szFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); + if (hFile == NULL) + { + printf("[错误] CreateFile(%ls) 调用失败!错误代码: [%d]\n", szFilePath, GetLastError()); + __leave; + } + DWORD FileSize = GetFileSize(hFile, NULL); + intptr_t FunctionSize = GetFunctionSize(ExecuteAssembly); + printf("FunctionSize:%lld [%ls] FileSize:%ld\n", FunctionSize, szFilePath, FileSize); + if ((FileSize == 0)||(FileSize==-1)) + { + printf("[错误] GetFileSize NULL 调用失败!错误代码: [%d]\n", GetLastError()); + __leave; + } + LPBYTE FileData = new BYTE[FileSize + 1]; + DWORD filetemp; + if (ReadFile(hFile, FileData, FileSize, &filetemp, NULL)==0) + { + printf(("[错误] ReadFile:[%ld]%ls error:%d\n"), FileSize, szFilePath, GetLastError()); + __leave; + } + + + cch = FunctionSize + sizeof(PARAMX) + FileSize + 0x100; + // 在远程线程中为路径名分配空间. + pRemoteMemory = (PSTR)VirtualAllocEx(hProcess, NULL, cch, MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE); + if (pRemoteMemory == NULL) + { + printf("[错误] VirtualAllocEx(%d) size:%lld 调用失败!错误代码: [%d]\n", dwProcessId,cch, GetLastError()); + __leave; + } + + HMODULE NTDLL = GetModuleHandleA("ntdll"); + if (NTDLL == 0) __leave; + PARAMX param; + RtlZeroMemory(¶m, sizeof(PARAMX)); + + param.lpFileData = pRemoteMemory + FunctionSize + sizeof(PARAMX); + param.DataLength = FileSize; + wcscpy_s(param.szArgument,512, szArg); + + + param.LdrGetProcedureAddress = (LdrGetProcedureAddressT)GetProcAddress(NTDLL, "LdrGetProcedureAddress");; + param.NtAllocateVirtualMemory = (NtAllocateVirtualMemoryT)GetProcAddress(NTDLL, "NtAllocateVirtualMemory"); + param.LdrLoadDll = (LdrLoadDllT)GetProcAddress(NTDLL, "LdrLoadDll"); + param.RtlInitAnsiString = (RtlInitAnsiStringT)GetProcAddress(NTDLL, "RtlInitAnsiString"); + param.RtlFreeAnsiString = (RtlFreeAnsiStringT)GetProcAddress(NTDLL, "RtlFreeAnsiString"); + param.RtlAnsiStringToUnicodeString = (RtlAnsiStringToUnicodeStringT)GetProcAddress(NTDLL, "RtlAnsiStringToUnicodeString"); + param.RtlFreeUnicodeString = (RtlFreeUnicodeStringT)GetProcAddress(NTDLL, "RtlFreeUnicodeString"); + param.RtlInitUnicodeString = (RtlInitUnicodeStringT)GetProcAddress(NTDLL, "RtlInitUnicodeString"); + + + //写入shellcode + if (!WriteProcessMemory(hProcess, pRemoteMemory, (PVOID)ExecuteAssembly, FunctionSize, &cch)) + { + printf("[错误] WriteProcessMemory A (%d) 调用失败!错误代码: [%d]\n", dwProcessId, GetLastError()); + __leave; + } + if (!WriteProcessMemory(hProcess, pRemoteMemory + FunctionSize, (PVOID)¶m, sizeof(PARAMX), &cch)) + { + printf("[错误] WriteProcessMemory B (%d) 调用失败!错误代码: [%d]\n", dwProcessId, GetLastError()); + __leave; + } + if (!WriteProcessMemory(hProcess, pRemoteMemory + FunctionSize + sizeof(PARAMX), (PVOID)FileData, FileSize, &cch)) + { + printf("[错误] WriteProcessMemory C (%d) 调用失败!错误代码: [%d]\n", dwProcessId, GetLastError()); + __leave; + } + + // 创建远程线程,并通过远程线程调用用户的DLL文件. + hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)(pRemoteMemory), pRemoteMemory + FunctionSize, 0, NULL); + if (hThread == NULL) + { + printf("[错误] CreateRemoteThread( %p ) 失败!错误代码: [%d]\n", pRemoteMemory + FileSize, GetLastError()); + __leave; + } + + // 等待远程线程终止. + if (WAIT_FAILED == WaitForSingleObject(hThread, INFINITE)) + { + printf("CreateRemoteThread() : WaitForSingleObject() 调用失败!错误代码: [%d]\n", GetLastError()); + __leave; + } + + cch = FileSize + FunctionSize + sizeof(PARAMX) + 0x100; + //清空DLL路径以免被侦测 + LPBYTE zBuffer = new BYTE[cch + 1]; + memset(zBuffer, 0, cch + 1); + //WriteProcessMemory(hProcess, (PVOID)pRemoteMemory, (PVOID)zBuffer, cch, NULL); + delete[] zBuffer; + bResult = TRUE; + } + __finally + { + // 关闭句柄. + if (pRemoteMemory != NULL) + { + //VirtualFreeEx(hProcess, (PVOID)pRemoteMemory, 0, MEM_RELEASE); + } + if (hThread != NULL) CloseHandle(hThread); + if (hProcess != NULL) CloseHandle(hProcess); + if (hFile != NULL) CloseHandle(hFile); + } + return bResult; +} + + +DWORD EnablePrivilege(LPCTSTR name) +{ + BOOL rv; + HANDLE hToken; + + TOKEN_PRIVILEGES priv = { 1,{0,0,SE_PRIVILEGE_ENABLED} }; + + LookupPrivilegeValue(0, name, &priv.Privileges[0].Luid); + + OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken); + + AdjustTokenPrivileges(hToken, FALSE, &priv, sizeof priv, 0, 0); + + rv = GetLastError(); + printf(("EnablePrivilege GetLastError:%d \n"), rv); + + CloseHandle(hToken); + return rv; +} + + +#define PROCESSFLAG 20210822 + +int main(int argc, char* argv[]) +{ + if (argc != 4) + { + printf("arg count error"); + return -1; + } + list ProcessList; + wstring sProcessName; + wstring sLibraryPath; + wstring sLibraryArg; + Utf8ToUnicode(argv[1], sProcessName); + Utf8ToUnicode(argv[2], sLibraryPath); + Utf8ToUnicode(argv[3], sLibraryArg); + printf("3FindProcessName:%ls [%ls]\n", sProcessName.c_str(), sLibraryPath.c_str()); + //%08d + const WCHAR szB08d[] = { 0x0025,0x0030,0x0038,0x0064,0x0000 }; + BYTE szTempBuff[0x100]; + + printf("argv:%ls\n", sLibraryArg.c_str()); + const WCHAR szSE_DEBUG_NAME[] = { 0x0053,0x0065,0x0044,0x0065,0x0062,0x0075,0x0067,0x0050,0x0072,0x0069,0x0076,0x0069,0x006C,0x0065,0x0067,0x0065,0x0000 }; + EnablePrivilege(szSE_DEBUG_NAME); + + try + { + for (int i = 0; i < 60 * 4 * 5; i++) + { + ProcessList.clear(); + if (GetProcessIdByName(sProcessName.c_str(), ProcessList)) + { + for (list::iterator it = ProcessList.begin(); it != ProcessList.end(); it++) + { + DWORD nProcessId = *it; + + printf("InjectRometeDll:%d\n", nProcessId); + swprintf_s((wchar_t*)szTempBuff,128, szB08d, nProcessId ^ PROCESSFLAG); + HANDLE m_hMutex = CreateMutex(NULL, TRUE, (wchar_t*)szTempBuff); + int nError = GetLastError(); + if (nError == ERROR_ALREADY_EXISTS) + { + if (m_hMutex) CloseHandle(m_hMutex); + return FALSE; + } + if (m_hMutex) CloseHandle(m_hMutex); + if (!InjectRometeDll(nProcessId, sLibraryPath.c_str(), sLibraryArg.c_str())) + { + printf("注入失敗:%d\n", nProcessId); + } + Sleep(100); + return 0; + } + } + Sleep(200); + } + } + catch (...) + { + + } +} + +// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单 +// 调试程序: F5 或调试 >“开始调试”菜单 + +// 入门使用技巧: +// 1. 使用解决方案资源管理器窗口添加/管理文件 +// 2. 使用团队资源管理器窗口连接到源代码管理 +// 3. 使用输出窗口查看生成输出和其他消息 +// 4. 使用错误列表窗口查看错误 +// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目 +// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件 diff --git a/InjectAssembly/InjectAssembly.vcxproj b/InjectAssembly/InjectAssembly.vcxproj new file mode 100644 index 0000000..4b2d3d0 --- /dev/null +++ b/InjectAssembly/InjectAssembly.vcxproj @@ -0,0 +1,164 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {679c01af-c56d-49e2-a823-fa17a7f6a979} + InjectAssembly + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + ..\Bin\ + $(ProjectName)_$(Platform) + + + false + ..\Bin\ + $(ProjectName)_$(Platform) + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + false + false + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Size + false + + + Console + true + true + true + + + + + Level3 + false + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + Default + ProgramDatabase + false + Disabled + + + Console + true + + + + + Level3 + true + false + false + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + Default + ProgramDatabase + false + MaxSpeed + + + Console + true + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/InjectAssembly/InjectAssembly.vcxproj.filters b/InjectAssembly/InjectAssembly.vcxproj.filters new file mode 100644 index 0000000..807bb64 --- /dev/null +++ b/InjectAssembly/InjectAssembly.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {fdd4580f-511c-4858-ab8f-0d60bf493568} + + + + + 源文件 + + + LHCommon + + + + + 头文件 + + + LHCommon + + + \ No newline at end of file diff --git a/InjectAssembly/LHCommon.cpp b/InjectAssembly/LHCommon.cpp new file mode 100644 index 0000000..db59358 --- /dev/null +++ b/InjectAssembly/LHCommon.cpp @@ -0,0 +1,95 @@ +#include "LHCommon.h" +#include +#include +#include + + +intptr_t GetFunctionSize_(LPBYTE xBegin, LPBYTE xEnd) +{ + intptr_t nFunctionSize = xEnd - xBegin; + printf("GetFunctionSize_:%lld\n", nFunctionSize); + intptr_t nRetLenth = nFunctionSize; + for (intptr_t i = nFunctionSize - 1; i > 0; i--) + { + if (xBegin[i] == 0xCC) + nRetLenth--; + else + break; + } + return nRetLenth; +} + +/************************************* +* BOOL GetProcessIdByName(LPSTR szProcessName, LPDWORD lpPID) +* ͨȡPID +* +* LPSTR szProcessName +* LPDWORD lpPID ָ򱣴PIDı +* Ƿɹ +**************************************/ +BOOL GetProcessIdByName(LPCTSTR szProcessName, list& RetArray) +{ + BOOL bRet; + bRet = FALSE; + RetArray.clear(); + // ʼ + STARTUPINFO st; + PROCESS_INFORMATION pi; + PROCESSENTRY32 ps; + HANDLE hSnapshot; + ZeroMemory(&st, sizeof(STARTUPINFO)); + ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); + st.cb = sizeof(STARTUPINFO); + ZeroMemory(&ps, sizeof(PROCESSENTRY32)); + ps.dwSize = sizeof(PROCESSENTRY32); + // + hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (hSnapshot == INVALID_HANDLE_VALUE) + { + return FALSE; + } + if (!Process32First(hSnapshot, &ps)) + { + return FALSE; + } + do + { + // ȽϽ + if (lstrcmpi(ps.szExeFile, szProcessName) == 0) + { + RetArray.push_back(ps.th32ProcessID); + } + } while (Process32Next(hSnapshot, &ps)); + CloseHandle(hSnapshot); + bRet = TRUE; + return bRet; +} + +wstring& _cdecl Utf8ToUnicode(const char* utf8, wstring& wide) +{ + const WCHAR szNULL[] = { 0x0000,0x0000 }; + wide = szNULL; + + int utf8_size; + size_t size; + utf8_size = strlen(utf8); + size = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8_size, NULL, 0)+1; + wide.resize(size, 0); + MultiByteToWideChar(CP_UTF8, 0, utf8, utf8_size, &wide[0], size); + return wide; +} + +wstring& _cdecl AsciiToUnicode(const char* ascii, wstring& wide) +{ + const WCHAR szNULL[] = { 0x0000,0x0000 }; + wide = szNULL; + + int ascii_size; + int size; + ascii_size = strlen(ascii); + size = MultiByteToWideChar(CP_ACP, 0, ascii, ascii_size, NULL, 0)+1; + + wide.resize(size, 0); + MultiByteToWideChar(CP_ACP, 0, ascii, ascii_size, &wide[0], size); + return wide; +} \ No newline at end of file diff --git a/InjectAssembly/LHCommon.h b/InjectAssembly/LHCommon.h new file mode 100644 index 0000000..dc6f0f8 --- /dev/null +++ b/InjectAssembly/LHCommon.h @@ -0,0 +1,20 @@ +#pragma once +#include +#include +#include + +using namespace std; + +intptr_t GetFunctionSize_(LPBYTE xBegin, LPBYTE xEnd); +//Ǻ +#define FunctionEndFlag(x)\ +int _stdcall x##_END(){ return 0x886; } + +#define GetFunctionSize(x) \ + GetFunctionSize_((LPBYTE)x,(LPBYTE)x##_END) + + +BOOL GetProcessIdByName(LPCTSTR szProcessName, list& RetArray); + +wstring& _cdecl Utf8ToUnicode(const char* utf8, wstring& wide); +wstring& _cdecl AsciiToUnicode(const char* ascii, wstring& wide); \ No newline at end of file diff --git a/TragetAssembly2/App.config b/TragetAssembly2/App.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/TragetAssembly2/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/TragetAssembly2/AppEnvironment.cs b/TragetAssembly2/AppEnvironment.cs new file mode 100644 index 0000000..733d515 --- /dev/null +++ b/TragetAssembly2/AppEnvironment.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Mudebug +{ + //主要负责储存启动时需要的参数 + public static class AppEnvironment + { + public static string AppArgs; + public static string AppDirectory; + } +} \ No newline at end of file diff --git a/TragetAssembly2/MainForm.Designer.cs b/TragetAssembly2/MainForm.Designer.cs new file mode 100644 index 0000000..428776d --- /dev/null +++ b/TragetAssembly2/MainForm.Designer.cs @@ -0,0 +1,60 @@ +namespace TragetAssembly2 +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.button1 = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // button1 + // + this.button1.Location = new System.Drawing.Point(116, 71); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(99, 48); + this.button1.TabIndex = 0; + this.button1.Text = "button1"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Controls.Add(this.button1); + this.Name = "MainForm"; + this.Text = "MainForm"; + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button button1; + } +} \ No newline at end of file diff --git a/TragetAssembly2/MainForm.cs b/TragetAssembly2/MainForm.cs new file mode 100644 index 0000000..8b50223 --- /dev/null +++ b/TragetAssembly2/MainForm.cs @@ -0,0 +1,26 @@ +using Mudebug; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace TragetAssembly2 +{ + public partial class MainForm : Form + { + public MainForm() + { + InitializeComponent(); + } + + private void button1_Click(object sender, EventArgs e) + { + MessageBox.Show("Test box by mudebug\n" + AppEnvironment.AppArgs); + } + } +} diff --git a/TragetAssembly2/MainForm.resx b/TragetAssembly2/MainForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/TragetAssembly2/MainForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/TragetAssembly2/Program.cs b/TragetAssembly2/Program.cs new file mode 100644 index 0000000..872097f --- /dev/null +++ b/TragetAssembly2/Program.cs @@ -0,0 +1,45 @@ +using Mudebug; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace TragetAssembly2 +{ + internal class Program + { +#if DEBUG + [DllImport("kernel32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool AllocConsole(); +#endif + + public static MainForm MainForm; + static void Main(string[] args) + { +#if DEBUG + AllocConsole(); + Console.WriteLine($"{DateTime.UtcNow} 啟動:{string.Join("\n", args)}"); +#endif + AppEnvironment.AppArgs = args[0]; + + var LibarayArg = AppEnvironment.AppArgs.Split('\t'); + AppEnvironment.AppDirectory = LibarayArg[0]; + Console.WriteLine($"AppDirectory:{AppEnvironment.AppDirectory}"); + + Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";" + AppEnvironment.AppDirectory); + + + var MainThread = new Thread(() => + { + MainForm = new MainForm(); + MainForm.ShowDialog(); + }); + MainThread.Start(); + + } + } +} diff --git a/TragetAssembly2/Properties/AssemblyInfo.cs b/TragetAssembly2/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..a4c18a7 --- /dev/null +++ b/TragetAssembly2/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("TragetAssembly2")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("TragetAssembly2")] +[assembly: AssemblyCopyright("Copyright © 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("27dee685-15f5-44af-9a55-bd61d7535553")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/TragetAssembly2/TragetAssembly2.csproj b/TragetAssembly2/TragetAssembly2.csproj new file mode 100644 index 0000000..62a7ee9 --- /dev/null +++ b/TragetAssembly2/TragetAssembly2.csproj @@ -0,0 +1,65 @@ + + + + + Debug + AnyCPU + {27DEE685-15F5-44AF-9A55-BD61D7535553} + Exe + TragetAssembly2 + TragetAssembly2 + v4.7.2 + 512 + true + true + + + AnyCPU + true + full + false + ..\Bin\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + ..\Bin\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + Form + + + MainForm.cs + + + + + + + + MainForm.cs + + + + \ No newline at end of file