├── rewolf-wow64ext ├── sample │ ├── build.bat │ └── main.cpp ├── src │ ├── wow64ext.rc │ ├── Debug │ │ ├── wow64ext.lastbuildstate │ │ ├── wow64ext.res │ │ ├── wow64ext.log │ │ ├── wow64ext.tlog │ │ │ └── wow64ext.lastbuildstate │ │ └── wow64ext.Build.CppClean.log │ ├── resource.h │ ├── wow64ext.sln │ ├── CMemPtr.h │ ├── internal.h │ ├── wow64ext.vcxproj │ ├── wow64ext.h │ └── wow64ext.cpp ├── bin │ ├── wow64ext.dll │ └── wow64ext.lib ├── lgpl-3.0.txt └── doc │ └── wow64ext.txt ├── x32FindTest.png ├── x64FindTest.png ├── AobScan ├── aobscan.h ├── aobscan.cpp ├── Demo.cpp ├── AobScan.vcxproj.filters └── AobScan.vcxproj ├── CleanTempFiles.bat ├── README.md └── AobScan.sln /rewolf-wow64ext/sample/build.bat: -------------------------------------------------------------------------------- 1 | cl /Zi /D "UNICODE" ../bin/wow64ext.lib main.cpp 2 | -------------------------------------------------------------------------------- /x32FindTest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanttobeno/x64_AOB_Search/HEAD/x32FindTest.png -------------------------------------------------------------------------------- /x64FindTest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanttobeno/x64_AOB_Search/HEAD/x64FindTest.png -------------------------------------------------------------------------------- /AobScan/aobscan.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanttobeno/x64_AOB_Search/HEAD/AobScan/aobscan.h -------------------------------------------------------------------------------- /CleanTempFiles.bat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanttobeno/x64_AOB_Search/HEAD/CleanTempFiles.bat -------------------------------------------------------------------------------- /AobScan/aobscan.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanttobeno/x64_AOB_Search/HEAD/AobScan/aobscan.cpp -------------------------------------------------------------------------------- /rewolf-wow64ext/src/wow64ext.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanttobeno/x64_AOB_Search/HEAD/rewolf-wow64ext/src/wow64ext.rc -------------------------------------------------------------------------------- /rewolf-wow64ext/bin/wow64ext.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanttobeno/x64_AOB_Search/HEAD/rewolf-wow64ext/bin/wow64ext.dll -------------------------------------------------------------------------------- /rewolf-wow64ext/bin/wow64ext.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanttobeno/x64_AOB_Search/HEAD/rewolf-wow64ext/bin/wow64ext.lib -------------------------------------------------------------------------------- /rewolf-wow64ext/src/Debug/wow64ext.lastbuildstate: -------------------------------------------------------------------------------- 1 | #v4.0:v100:false 2 | Debug|Win32|C:\Users\ZhanYue\Desktop\x64_AOB_Search\| 3 | -------------------------------------------------------------------------------- /rewolf-wow64ext/src/Debug/wow64ext.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanttobeno/x64_AOB_Search/HEAD/rewolf-wow64ext/src/Debug/wow64ext.res -------------------------------------------------------------------------------- /rewolf-wow64ext/src/Debug/wow64ext.log: -------------------------------------------------------------------------------- 1 | wow64ext.cpp 2 | wow64ext.vcxproj -> C:\Users\ZhanYue\Desktop\x64_AOB_Search\Debug\wow64ext.dll 3 | -------------------------------------------------------------------------------- /rewolf-wow64ext/src/Debug/wow64ext.tlog/wow64ext.lastbuildstate: -------------------------------------------------------------------------------- 1 | #TargetFrameworkVersion=v4.0:PlatformToolSet=v120_xp:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit 2 | Debug|Win32|C:\Users\ZhanYue\Desktop\x64_AOB_Search\| 3 | -------------------------------------------------------------------------------- /rewolf-wow64ext/src/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by wow64ext.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /AobScan/Demo.cpp: -------------------------------------------------------------------------------- 1 | #include "aobscan.h" 2 | 3 | int main(int argc, char* argv) 4 | { 5 | std::vector vResultContainer = AobScan::FindSigX32(6580, "E86D86??FF", 0, 0x7fffffff); 6 | int nSize1 = 0; 7 | for (auto it = vResultContainer.begin(); it != vResultContainer.end();it++) 8 | { 9 | wchar_t buf[64] = { 0 }; 10 | wsprintf(buf, L"%03d 0x%08X\n", nSize1, *it); 11 | OutputDebugString(buf); 12 | nSize1++; 13 | } 14 | 15 | std::vector dwRet = AobScan::FindSigX64("697469??6C697A65", 5648,0x77111000, -1); 16 | int nSize2 = 0; 17 | for (auto it = dwRet.begin(); it != dwRet.end(); it++) 18 | { 19 | wchar_t buf[64] = { 0 }; 20 | wsprintf(buf, L"%03d 0x%016I64X\n", nSize2, *it); 21 | OutputDebugString(buf); 22 | nSize2++; 23 | } 24 | return 0; 25 | } -------------------------------------------------------------------------------- /rewolf-wow64ext/src/wow64ext.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wow64ext", "wow64ext.vcxproj", "{9DA7F232-0096-45BC-A452-24C7F3AFA0F8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {9DA7F232-0096-45BC-A452-24C7F3AFA0F8}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {9DA7F232-0096-45BC-A452-24C7F3AFA0F8}.Debug|Win32.Build.0 = Debug|Win32 16 | {9DA7F232-0096-45BC-A452-24C7F3AFA0F8}.Release|Win32.ActiveCfg = Release|Win32 17 | {9DA7F232-0096-45BC-A452-24C7F3AFA0F8}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /AobScan/AobScan.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ##### 简介 3 | 4 | 搜索算法,速度很快,支持通配符。同是支持32位和64位程序。 5 | 6 | 来自 7 | 8 | x64跨进程aob搜索 9 | 10 | https://bbs.pediy.com/thread-247517.htm 11 | 12 | ##### 环境 13 | 14 | Windows、VS2013 15 | 16 | 17 | ##### 修改说明 18 | 19 | - 1.修改接口,修复内存泄露 20 | 21 | - 2.修复64位无法读取内存 22 | 23 | - 3.添加x32和x64的地址控件限制 24 | 25 | 26 | 27 | ##### DemoX32 28 | 29 | ```c++ 30 | std::vector vResultContainer = AobScan::FindSigX32(6580, "E86D86??FF", 0, 0x7fffffff); 31 | int nSize1 = 0; 32 | for (auto it = vResultContainer.begin(); it != vResultContainer.end();it++) 33 | { 34 | wchar_t buf[64] = { 0 }; 35 | wsprintf(buf, L"%03d 0x%08X\n", nSize1, *it); 36 | OutputDebugString(buf); 37 | nSize1++; 38 | } 39 | ``` 40 | 41 | 在Notepad2 4.2.25中搜索E86D86??FF的结果,右侧的是X32dbg结果 42 | 43 | ![x32FindTest.png](./x32FindTest.png) 44 | 45 | 46 | 47 | ##### DemoX64 48 | 49 | ```c++ 50 | std::vector dwRet = AobScan::FindSigX64("697469??6C697A65", 5648,0x77111000, -1); 51 | int nSize2 = 0; 52 | for (auto it = dwRet.begin(); it != dwRet.end(); it++) 53 | { 54 | wchar_t buf[64] = { 0 }; 55 | wsprintf(buf, L"%03d 0x%016I64X\n", nSize2, *it); 56 | OutputDebugString(buf); 57 | nSize2++; 58 | } 59 | ``` 60 | 61 | 62 | DemoX64结果 63 | 64 | 在Notepad2 4.2.25中搜索697469??6C697A65的结果,右侧的是X64dbg结果 65 | 66 | ![x64FindTest.png](./x64FindTest.png) 67 | 68 | 69 | 70 | ##### 可优化项说明 71 | 72 | - 搜索段与段之间会漏掉一些匹配项,自己去改。 73 | 74 | - 重复内存分配和释放 75 | 76 | 77 | -------------------------------------------------------------------------------- /rewolf-wow64ext/src/CMemPtr.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * WOW64Ext Library 4 | * 5 | * Copyright (c) 2014 ReWolf 6 | * http://blog.rewolf.pl/ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU Lesser General Public License as published 10 | * by the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | * 21 | */ 22 | #pragma once 23 | 24 | class CMemPtr 25 | { 26 | private: 27 | void** m_ptr; 28 | bool watchActive; 29 | 30 | public: 31 | CMemPtr(void** ptr) : m_ptr(ptr), watchActive(true) {} 32 | 33 | ~CMemPtr() 34 | { 35 | if (*m_ptr && watchActive) 36 | { 37 | free(*m_ptr); 38 | *m_ptr = 0; 39 | } 40 | } 41 | 42 | void disableWatch() { watchActive = false; } 43 | }; 44 | 45 | #define WATCH(ptr) \ 46 | CMemPtr watch_##ptr((void**)&ptr) 47 | 48 | #define DISABLE_WATCH(ptr) \ 49 | watch_##ptr.disableWatch() 50 | -------------------------------------------------------------------------------- /AobScan.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AobScan", "AobScan\AobScan.vcxproj", "{D6637ABE-82E5-4BF8-A632-CB17027B459E}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {9DA7F232-0096-45BC-A452-24C7F3AFA0F8} = {9DA7F232-0096-45BC-A452-24C7F3AFA0F8} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wow64ext", "rewolf-wow64ext\src\wow64ext.vcxproj", "{9DA7F232-0096-45BC-A452-24C7F3AFA0F8}" 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|Win32 = Debug|Win32 16 | Release|Win32 = Release|Win32 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {D6637ABE-82E5-4BF8-A632-CB17027B459E}.Debug|Win32.ActiveCfg = Debug|Win32 20 | {D6637ABE-82E5-4BF8-A632-CB17027B459E}.Debug|Win32.Build.0 = Debug|Win32 21 | {D6637ABE-82E5-4BF8-A632-CB17027B459E}.Release|Win32.ActiveCfg = Release|Win32 22 | {D6637ABE-82E5-4BF8-A632-CB17027B459E}.Release|Win32.Build.0 = Release|Win32 23 | {9DA7F232-0096-45BC-A452-24C7F3AFA0F8}.Debug|Win32.ActiveCfg = Debug|Win32 24 | {9DA7F232-0096-45BC-A452-24C7F3AFA0F8}.Debug|Win32.Build.0 = Debug|Win32 25 | {9DA7F232-0096-45BC-A452-24C7F3AFA0F8}.Release|Win32.ActiveCfg = Release|Win32 26 | {9DA7F232-0096-45BC-A452-24C7F3AFA0F8}.Release|Win32.Build.0 = Release|Win32 27 | EndGlobalSection 28 | GlobalSection(SolutionProperties) = preSolution 29 | HideSolutionNode = FALSE 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /rewolf-wow64ext/src/internal.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * WOW64Ext Library 4 | * 5 | * Copyright (c) 2014 ReWolf 6 | * http://blog.rewolf.pl/ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU Lesser General Public License as published 10 | * by the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | * 21 | */ 22 | #pragma once 23 | 24 | #define EMIT(a) __asm __emit (a) 25 | 26 | #define X64_Start_with_CS(_cs) \ 27 | { \ 28 | EMIT(0x6A) EMIT(_cs) /* push _cs */ \ 29 | EMIT(0xE8) EMIT(0) EMIT(0) EMIT(0) EMIT(0) /* call $+5 */ \ 30 | EMIT(0x83) EMIT(4) EMIT(0x24) EMIT(5) /* add dword [esp], 5 */ \ 31 | EMIT(0xCB) /* retf */ \ 32 | } 33 | 34 | #define X64_End_with_CS(_cs) \ 35 | { \ 36 | EMIT(0xE8) EMIT(0) EMIT(0) EMIT(0) EMIT(0) /* call $+5 */ \ 37 | EMIT(0xC7) EMIT(0x44) EMIT(0x24) EMIT(4) EMIT(_cs) EMIT(0) EMIT(0) EMIT(0) /* mov dword [rsp + 4], _cs */ \ 38 | EMIT(0x83) EMIT(4) EMIT(0x24) EMIT(0xD) /* add dword [rsp], 0xD */ \ 39 | EMIT(0xCB) /* retf */ \ 40 | } 41 | 42 | #define X64_Start() X64_Start_with_CS(0x33) 43 | #define X64_End() X64_End_with_CS(0x23) 44 | 45 | #define _RAX 0 46 | #define _RCX 1 47 | #define _RDX 2 48 | #define _RBX 3 49 | #define _RSP 4 50 | #define _RBP 5 51 | #define _RSI 6 52 | #define _RDI 7 53 | #define _R8 8 54 | #define _R9 9 55 | #define _R10 10 56 | #define _R11 11 57 | #define _R12 12 58 | #define _R13 13 59 | #define _R14 14 60 | #define _R15 15 61 | 62 | #define X64_Push(r) EMIT(0x48 | ((r) >> 3)) EMIT(0x50 | ((r) & 7)) 63 | #define X64_Pop(r) EMIT(0x48 | ((r) >> 3)) EMIT(0x58 | ((r) & 7)) 64 | 65 | #define REX_W EMIT(0x48) __asm 66 | 67 | //to fool M$ inline asm compiler I'm using 2 DWORDs instead of DWORD64 68 | //use of DWORD64 will generate wrong 'pop word ptr[]' and it will break stack 69 | union reg64 70 | { 71 | DWORD64 v; 72 | DWORD dw[2]; 73 | }; 74 | -------------------------------------------------------------------------------- /rewolf-wow64ext/src/Debug/wow64ext.Build.CppClean.log: -------------------------------------------------------------------------------- 1 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.obj 2 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\vc100.pdb 3 | c:\users\zhanyue\desktop\x64_aob_search\debug\wow64ext.ilk 4 | c:\users\zhanyue\desktop\x64_aob_search\debug\wow64ext.dll 5 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.dll.intermediate.manifest 6 | c:\users\zhanyue\desktop\x64_aob_search\debug\wow64ext.pdb 7 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.dll.embed.manifest 8 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.res 9 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.dll.embed.manifest.res 10 | c:\users\zhanyue\desktop\x64_aob_search\debug\wow64ext.lib 11 | c:\users\zhanyue\desktop\x64_aob_search\debug\wow64ext.exp 12 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\vc120.pdb 13 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\vc120.idb 14 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\cl.command.1.tlog 15 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\cl.read.1.tlog 16 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\cl.write.1.tlog 17 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\link-cvtres.read.1.tlog 18 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\link-cvtres.write.1.tlog 19 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\link.command.1.tlog 20 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\link.read.1.tlog 21 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\link.write.1.tlog 22 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\mt.command.1.tlog 23 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\mt.read.1.tlog 24 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\mt.write.1.tlog 25 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\rc.command.1.tlog 26 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\rc.read.1.tlog 27 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\rc.write.1.tlog 28 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.write.1.tlog 29 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\vc100.idb 30 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext_manifest.rc 31 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.tlog\cl.command.1.tlog 32 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.tlog\cl.read.1.tlog 33 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.tlog\cl.write.1.tlog 34 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.tlog\link-cvtres.read.1.tlog 35 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.tlog\link-cvtres.write.1.tlog 36 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.tlog\link-rc.read.1.tlog 37 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.tlog\link-rc.write.1.tlog 38 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.tlog\link.command.1.tlog 39 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.tlog\link.read.1.tlog 40 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.tlog\link.write.1.tlog 41 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.tlog\rc.command.1.tlog 42 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.tlog\rc.read.1.tlog 43 | c:\users\zhanyue\desktop\x64_aob_search\rewolf-wow64ext\src\debug\wow64ext.tlog\rc.write.1.tlog 44 | -------------------------------------------------------------------------------- /AobScan/AobScan.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {D6637ABE-82E5-4BF8-A632-CB17027B459E} 15 | Win32Proj 16 | x64_AOB_Search 17 | AobScan 18 | 19 | 20 | 21 | Application 22 | true 23 | v120_xp 24 | Unicode 25 | 26 | 27 | Application 28 | false 29 | v120_xp 30 | true 31 | Unicode 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | true 45 | 46 | 47 | false 48 | 49 | 50 | 51 | 52 | 53 | Level3 54 | Disabled 55 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 56 | 57 | 58 | Console 59 | true 60 | 61 | 62 | 63 | 64 | Level3 65 | 66 | 67 | MaxSpeed 68 | true 69 | true 70 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 71 | 72 | 73 | Console 74 | true 75 | true 76 | true 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /rewolf-wow64ext/src/wow64ext.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {9DA7F232-0096-45BC-A452-24C7F3AFA0F8} 15 | Win32Proj 16 | wow64ext 17 | 18 | 19 | 20 | DynamicLibrary 21 | true 22 | Unicode 23 | v120_xp 24 | 25 | 26 | DynamicLibrary 27 | false 28 | true 29 | Unicode 30 | v120_xp 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | 45 | 46 | false 47 | 48 | 49 | 50 | 51 | 52 | Level3 53 | Disabled 54 | WIN32;_DEBUG;_WINDOWS;_USRDLL;WOW64EXT_EXPORTS;%(PreprocessorDefinitions) 55 | MultiThreadedDebug 56 | 57 | 58 | Windows 59 | true 60 | 61 | 62 | 63 | 64 | Level3 65 | 66 | 67 | MaxSpeed 68 | true 69 | true 70 | WIN32;NDEBUG;_WINDOWS;_USRDLL;WOW64EXT_EXPORTS;%(PreprocessorDefinitions) 71 | MultiThreaded 72 | 73 | 74 | Windows 75 | true 76 | true 77 | true 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /rewolf-wow64ext/sample/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../src/wow64ext.h" 5 | 6 | #define FNFAIL(a) printf(a " failed\n") 7 | 8 | void AllocTest(HANDLE hProcess) 9 | { 10 | static const size_t TEST_SIZE = 0x2000; 11 | printf("Requesting 0x%08X bytes of memory at 0x70000020000 ...\n", TEST_SIZE); 12 | DWORD64 mem = VirtualAllocEx64(hProcess, 0x70000020000, TEST_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 13 | if (0 == mem) 14 | { 15 | printf("VirtualAllocEx64 failed.\n"); 16 | return; 17 | } 18 | printf("Memory allocated at: %016I64X\n", mem); 19 | 20 | MEMORY_BASIC_INFORMATION64 mbi64 = { 0 }; 21 | VirtualQueryEx64(hProcess, mem, &mbi64, sizeof(mbi64)); 22 | printf("Query memory: %016I64X %016I64X %08X %08X %08X\n", mbi64.BaseAddress, mbi64.RegionSize, mbi64.Protect, mbi64.Type, mbi64.State); 23 | printf("Changing protection from %08X to %08X...\n", PAGE_READWRITE, PAGE_EXECUTE_READWRITE); 24 | DWORD oldProtect = 0; 25 | VirtualProtectEx64(hProcess, mem, mbi64.RegionSize, PAGE_EXECUTE_READWRITE, &oldProtect); 26 | VirtualQueryEx64(hProcess, mem, &mbi64, sizeof(mbi64)); 27 | printf("Query memory: %016I64X %016I64X %08X %08X %08X\n", mbi64.BaseAddress, mbi64.RegionSize, mbi64.Protect, mbi64.Type, mbi64.State); 28 | 29 | printf("WriteProcessMemory64 test: "); 30 | BYTE testBuf[TEST_SIZE]; 31 | for (int i = 0; i < TEST_SIZE; i++) 32 | testBuf[i] = (BYTE)i; 33 | 34 | SIZE_T wrSz = 0; 35 | if (!WriteProcessMemory64(hProcess, mem, testBuf, TEST_SIZE, &wrSz) || (wrSz != TEST_SIZE)) 36 | { 37 | printf("FAILED on WriteProcessMemory64\n"); 38 | } 39 | else 40 | { 41 | BYTE cmpBuf[TEST_SIZE]; 42 | if (!ReadProcessMemory64(hProcess, mem, cmpBuf, TEST_SIZE, &wrSz) || (wrSz != TEST_SIZE)) 43 | printf("FAILED on ReadProcessMemory64\n"); 44 | else 45 | { 46 | if (0 == memcmp(testBuf, cmpBuf, TEST_SIZE)) 47 | printf("SUCCESS\n"); 48 | else 49 | printf("FAILED on memcmp.\n"); 50 | } 51 | } 52 | 53 | printf("Freeing memory: %s\n", VirtualFreeEx64(hProcess, mem, 0, MEM_RELEASE) ? "success" : "failure"); 54 | VirtualQueryEx64(hProcess, mem, &mbi64, sizeof(mbi64)); 55 | printf("Query memory: %016I64X %016I64X %08X %08X %08X\n", mbi64.BaseAddress, mbi64.RegionSize, mbi64.Protect, mbi64.Type, mbi64.State); 56 | } 57 | 58 | int main (int argc, char* argv[]) 59 | { 60 | DWORD64 s = GetProcAddress64(GetModuleHandle64(L"wow64cpu.dll"),"TurboDispatchJumpAddressStart"); 61 | printf("tt: %016I64X\n", s); 62 | 63 | if (2 != argc) 64 | { 65 | printf("Usage:\n\t%s hex_process_ID\n", argv[0]); 66 | return 0; 67 | } 68 | 69 | DWORD procID = 0; 70 | if (1 != sscanf_s(argv[1], "%X", &procID)) 71 | { 72 | printf("Invalid process ID.\n"); 73 | return 0; 74 | } 75 | 76 | printf("Process ID: %08X\n", procID); 77 | HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID); 78 | if (0 == hProcess) 79 | { 80 | printf("Can't open process %08X.\n", procID); 81 | return 0; 82 | } 83 | 84 | MEMORY_BASIC_INFORMATION64 mbi64 = { 0 }; 85 | DWORD64 crAddr = 0; 86 | bool printMemMap = true; 87 | while (VirtualQueryEx64(hProcess, crAddr, &mbi64, sizeof(mbi64))) 88 | { 89 | if (mbi64.Protect && !(mbi64.Protect & (PAGE_NOACCESS | PAGE_GUARD))) 90 | { 91 | if (printMemMap) 92 | printf("[D] : "); 93 | 94 | BYTE* mem = (BYTE*)VirtualAlloc(0, (SIZE_T)mbi64.RegionSize, MEM_COMMIT, PAGE_READWRITE); 95 | if (mem == 0) 96 | { 97 | FNFAIL("VirtualAlloc"); 98 | crAddr = crAddr + mbi64.RegionSize; 99 | continue; 100 | } 101 | SIZE_T rdPM = 0; 102 | if ((0 == ReadProcessMemory64(hProcess, mbi64.BaseAddress, mem, (SIZE_T)mbi64.RegionSize, &rdPM)) || (rdPM != mbi64.RegionSize)) 103 | { 104 | if (printMemMap) 105 | printf("%016I64X : %016I64X : %08X : ", mbi64.BaseAddress, mbi64.RegionSize, mbi64.Protect); 106 | FNFAIL("ReadProcessMemory"); 107 | VirtualFree(mem, 0, MEM_RELEASE); 108 | crAddr = crAddr + mbi64.RegionSize; 109 | continue; 110 | } 111 | 112 | wchar_t fName[0x200]; 113 | swprintf_s(fName, L"%08X_%016I64X_%08X.bin", procID, mbi64.BaseAddress, mbi64.Protect); 114 | HANDLE hFile = CreateFile(fName, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 115 | DWORD tmp = 0; 116 | WriteFile(hFile, mem, (DWORD)mbi64.RegionSize, &tmp, 0); 117 | CloseHandle(hFile); 118 | 119 | VirtualFree(mem, 0, MEM_RELEASE); 120 | } 121 | else 122 | { 123 | if (printMemMap) 124 | printf("[ ] : "); 125 | } 126 | 127 | if (printMemMap) 128 | printf("%016I64X : %016I64X : %08X\n", mbi64.BaseAddress, mbi64.RegionSize, mbi64.Protect); 129 | crAddr = crAddr + mbi64.RegionSize; 130 | } 131 | 132 | DWORD64 ntdll64 = GetModuleHandle64(L"ntdll.dll"); 133 | printf("\nNTDLL64: %016I64X\n\n", ntdll64); 134 | 135 | DWORD64 rtlcrc32 = GetProcAddress64(ntdll64, "RtlComputeCrc32"); 136 | printf("RtlComputeCrc32 address: %016I64X\n", rtlcrc32); 137 | 138 | if (0 != rtlcrc32) 139 | { 140 | DWORD64 ret = X64Call(rtlcrc32, 3, (DWORD64)0, (DWORD64)"ReWolf", (DWORD64)6); 141 | printf("CRC32(\"ReWolf\") = %016I64X\n\n", ret); 142 | } 143 | 144 | printf("Alloc/Protect/Write/Free test:\n"); 145 | AllocTest(hProcess); 146 | 147 | printf("\nAlloc/Protect/Write/Free over 4GB inside WoW64 test:\n"); 148 | AllocTest(GetCurrentProcess()); 149 | 150 | printf("\n\nGet/Set Context test:\n"); 151 | 152 | _CONTEXT64 ctx = { 0 }; 153 | ctx.ContextFlags = CONTEXT64_ALL; 154 | GetThreadContext64(GetCurrentThread(), &ctx); 155 | 156 | printf("rsp: %016I64X\n", ctx.Rsp); 157 | printf("rip: %016I64X\n", ctx.Rip); 158 | printf("r8 : %016I64X\n", ctx.R8); 159 | printf("r9 : %016I64X\n", ctx.R9); 160 | printf("r12: %016I64X\n", ctx.R12); 161 | 162 | //below code will crash application, it is sufficient prove that SetThreadContext64 is working fine :) 163 | //ctx.Rip = 0; 164 | //SetThreadContext64(GetCurrentThread(), &ctx); 165 | 166 | CloseHandle(hProcess); 167 | return 0; 168 | } 169 | -------------------------------------------------------------------------------- /rewolf-wow64ext/lgpl-3.0.txt: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /rewolf-wow64ext/doc/wow64ext.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | Name....: WOW64Ext Library 3 | Author..: ReWolf 4 | Rel.Date: 12.I.2012 5 | Update..: 04.VII.2014 6 | Version.: 1.0.0.6 7 | 8 | 9 | e.mail..: rewolf@rewolf.pl 10 | www.....: http://blog.rewolf.pl 11 | -------------------------------------------------------------------------------- 12 | 13 | WOW64Ext is a helper library for x86 programs that runs under WOW64 layer on 14 | x64 versions of Microsoft Windows operating systems. It enables x86 applications 15 | to read, write and enumerate memory of a native x64 applications. There is also 16 | possibility to call any x64 function from 64-bits version of NTDLL through 17 | a special function called X64Call(). As a bonus, wow64ext.h contains definitions 18 | of some structures that might be useful for programs that want to access PEB, 19 | TEB, TIB etc. 20 | 21 | Sample application that uses this library can be found in \sample\ directory, it 22 | is simple memory dumper. 23 | 24 | -------------------------------------------------------------------------------- 25 | 26 | Functions: 27 | 28 | -------------------------------------------------------------------------------- 29 | 30 | DWORD64 X64Call(DWORD64 func, int argC, ...); 31 | 32 | Low level function that can call any x64 API from NTDLL. 33 | 34 | func - address of x64 function, can be obtained by GetProcAddress64() 35 | argC - number of arguments that will be passed to the 'func' 36 | ... - rest of arguments for 'func', all values should be casted to DWORD64 37 | 38 | -------------------------------------------------------------------------------- 39 | 40 | DWORD64 GetModuleHandle64(wchar_t* lpModuleName); 41 | 42 | Behaviour similar to x86 version of GetModuleHandle, but it looks for the module 43 | name in the list of loaded x64 libraries. Usually x86 processes under WOW64 44 | layer have four x64 libraries: ntdll.dll, wow64.dll, wow64cpu.dll and 45 | wow64win.dll 46 | 47 | lpModuleName - unicode string that represents module name 48 | 49 | -------------------------------------------------------------------------------- 50 | 51 | DWORD64 GetProcAddress64(DWORD64 hModule, char* funcName); 52 | 53 | Behaviour similar to x86 version of GetProcAddress(), internally it uses x64 54 | version of LdrGetProcedureAddress() from NTDLL. 55 | 56 | hModule - base of x64 module 57 | funcName - function name 58 | 59 | -------------------------------------------------------------------------------- 60 | 61 | SIZE_T VirtualQueryEx64(HANDLE hProcess, DWORD64 lpAddress, 62 | MEMORY_BASIC_INFORMATION64* lpBuffer, SIZE_T dwLength) 63 | 64 | Behaviour similar to x86 version of VirtualQueryEx(), internally it uses x64 65 | version of NtQueryVirtualMemory() from NTDLL. 66 | 67 | hProcess - handle of the process, can be obtained by standard x86 version of 68 | OpenProcess() function 69 | lpAddress - base address of the region of pages to be queried 70 | lpBuffer - a pointer to a MEMORY_BASIC_INFORMATION64 structure, it is defined 71 | in the standard SDK headers 72 | dwLength - size of the buffer pointed to by the lpBuffer parameter 73 | 74 | -------------------------------------------------------------------------------- 75 | 76 | DWORD64 VirtualAllocEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, 77 | DWORD flAllocationType, DWORD flProtect) 78 | 79 | Behaviour similar to x86 version of VirtualAllocEx64(), internally it uses x64 80 | version of NtAllocateVirtualMemory() from NTDLL. 81 | 82 | hProcess - handle of the process, can be obtained by standard x86 83 | version of OpenProcess() function 84 | lpAddress - desired base address of the region that will be allocated 85 | dwSize - size of the region that will be allocated 86 | flAllocationType - type of memory allocation 87 | flProtect - memory protection for the region 88 | 89 | -------------------------------------------------------------------------------- 90 | 91 | BOOL VirtualFreeEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, 92 | DWORD dwFreeType) 93 | 94 | Behaviour similar to x86 version of VirtualFreeEx64(), internally it uses x64 95 | version of NtFreeVirtualMemory() from NTDLL. 96 | 97 | hProcess - handle of the process, can be obtained by standard x86 version of 98 | OpenProcess() function 99 | lpAddress - base address of the memory region to free 100 | dwSize - size (in bytes) of the memory region to free 101 | dwFreeType - type of free operation (MEM_RELEASE, MEM_DECOMMIT) 102 | 103 | -------------------------------------------------------------------------------- 104 | 105 | BOOL VirtualProtectEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, 106 | DWORD flNewProtect, DWORD* lpflOldProtect); 107 | 108 | Behaviour similar to x86 version of VirtualProtectEx64(), internally it uses 109 | x64 version of NtProtectVirtualMemory() from NTDLL. 110 | 111 | hProcess - handle of the process, can be obtained by standard x86 112 | version of OpenProcess() function 113 | lpAddress - base address of the memory region that will have changed 114 | protection 115 | dwSize - size (in bytes) of the memory region that will have changed 116 | protection 117 | flNewProtect - the memory protection option (see MSDN) 118 | lpflOldProtect - pointer to the variable that receives old protection value 119 | 120 | -------------------------------------------------------------------------------- 121 | 122 | BOOL ReadProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, 123 | LPVOID lpBuffer, SIZE_T nSize, 124 | SIZE_T *lpNumberOfBytesRead); 125 | 126 | Behaviour similar to x86 version of ReadProcessMemory(), internally it uses x64 127 | version of NtReadVirtualMemory() from NTDLL. 128 | 129 | hProcess - handle of the process, can be obtained by standard x86 130 | version of OpenProcess() function 131 | lpBaseAddress - base address of the region that will be read 132 | lpBuffer - output memory buffer for the read data 133 | nSize - number of bytes to be read 134 | lpNumberOfBytesRead - pointer to a variable that receives number of read bytes 135 | 136 | -------------------------------------------------------------------------------- 137 | 138 | BOOL WriteProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, 139 | LPVOID lpBuffer, SIZE_T nSize, 140 | SIZE_T *lpNumberOfBytesWritten); 141 | 142 | Behaviour similar to x86 version of WriteProcessMemory(), internally it uses x64 143 | version of NtWriteVirtualMemory() from NTDLL. 144 | 145 | hProcess - handle of the process, can be obtained by standard x86 146 | version of OpenProcess() function 147 | lpBaseAddress - base address of the region that will be written 148 | lpBuffer - input memory buffer with the data to write 149 | nSize - number of bytes that will be written 150 | lpNumberOfBytesRead - pointer to variable that receives number of written bytes 151 | 152 | -------------------------------------------------------------------------------- 153 | 154 | BOOL GetThreadContext64(HANDLE hThread, _CONTEXT64* lpContext); 155 | 156 | Behaviour similar to x86 version of GetThreadContext(), internally it uses x64 157 | version of NtGetContextThread() from NTDLL. Definition of _CONTEXT64 can be 158 | found in wow64ext.h file. 159 | 160 | hThread - handle of the process, can be obtained by standard x86 161 | version of OpenProcess() function 162 | lpContext - A pointer to a _CONTEXT64 structure that will receive 163 | context data from specified thread. Structure will be 164 | filled according to ContextFlags field. 165 | 166 | -------------------------------------------------------------------------------- 167 | 168 | BOOL SetThreadContext64(HANDLE hThread, _CONTEXT64* lpContext); 169 | 170 | Behaviour similar to x86 version of SetThreadContext(), internally it uses x64 171 | version of NtSetContextThread() from NTDLL. Definition of _CONTEXT64 can be 172 | found in wow64ext.h file. 173 | 174 | hThread - handle of the process, can be obtained by standard x86 175 | version of OpenProcess() function 176 | lpContext - A pointer to a _CONTEXT64 structure that will be used 177 | to fill context data in specified thread. Structure will 178 | use only fields defined by ContextFlags. 179 | 180 | -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- /rewolf-wow64ext/src/wow64ext.h: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * WOW64Ext Library 4 | * 5 | * Copyright (c) 2014 ReWolf 6 | * http://blog.rewolf.pl/ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU Lesser General Public License as published 10 | * by the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | * 21 | */ 22 | #pragma once 23 | 24 | #ifndef STATUS_SUCCESS 25 | # define STATUS_SUCCESS 0 26 | #endif 27 | 28 | #pragma pack(push) 29 | #pragma pack(1) 30 | template 31 | struct _LIST_ENTRY_T 32 | { 33 | T Flink; 34 | T Blink; 35 | }; 36 | 37 | template 38 | struct _UNICODE_STRING_T 39 | { 40 | union 41 | { 42 | struct 43 | { 44 | WORD Length; 45 | WORD MaximumLength; 46 | }; 47 | T dummy; 48 | }; 49 | T Buffer; 50 | }; 51 | 52 | template 53 | struct _NT_TIB_T 54 | { 55 | T ExceptionList; 56 | T StackBase; 57 | T StackLimit; 58 | T SubSystemTib; 59 | T FiberData; 60 | T ArbitraryUserPointer; 61 | T Self; 62 | }; 63 | 64 | template 65 | struct _CLIENT_ID 66 | { 67 | T UniqueProcess; 68 | T UniqueThread; 69 | }; 70 | 71 | template 72 | struct _TEB_T_ 73 | { 74 | _NT_TIB_T NtTib; 75 | T EnvironmentPointer; 76 | _CLIENT_ID ClientId; 77 | T ActiveRpcHandle; 78 | T ThreadLocalStoragePointer; 79 | T ProcessEnvironmentBlock; 80 | DWORD LastErrorValue; 81 | DWORD CountOfOwnedCriticalSections; 82 | T CsrClientThread; 83 | T Win32ThreadInfo; 84 | DWORD User32Reserved[26]; 85 | //rest of the structure is not defined for now, as it is not needed 86 | }; 87 | 88 | template 89 | struct _LDR_DATA_TABLE_ENTRY_T 90 | { 91 | _LIST_ENTRY_T InLoadOrderLinks; 92 | _LIST_ENTRY_T InMemoryOrderLinks; 93 | _LIST_ENTRY_T InInitializationOrderLinks; 94 | T DllBase; 95 | T EntryPoint; 96 | union 97 | { 98 | DWORD SizeOfImage; 99 | T dummy01; 100 | }; 101 | _UNICODE_STRING_T FullDllName; 102 | _UNICODE_STRING_T BaseDllName; 103 | DWORD Flags; 104 | WORD LoadCount; 105 | WORD TlsIndex; 106 | union 107 | { 108 | _LIST_ENTRY_T HashLinks; 109 | struct 110 | { 111 | T SectionPointer; 112 | T CheckSum; 113 | }; 114 | }; 115 | union 116 | { 117 | T LoadedImports; 118 | DWORD TimeDateStamp; 119 | }; 120 | T EntryPointActivationContext; 121 | T PatchInformation; 122 | _LIST_ENTRY_T ForwarderLinks; 123 | _LIST_ENTRY_T ServiceTagLinks; 124 | _LIST_ENTRY_T StaticLinks; 125 | T ContextInformation; 126 | T OriginalBase; 127 | _LARGE_INTEGER LoadTime; 128 | }; 129 | 130 | template 131 | struct _PEB_LDR_DATA_T 132 | { 133 | DWORD Length; 134 | DWORD Initialized; 135 | T SsHandle; 136 | _LIST_ENTRY_T InLoadOrderModuleList; 137 | _LIST_ENTRY_T InMemoryOrderModuleList; 138 | _LIST_ENTRY_T InInitializationOrderModuleList; 139 | T EntryInProgress; 140 | DWORD ShutdownInProgress; 141 | T ShutdownThreadId; 142 | 143 | }; 144 | 145 | template 146 | struct _PEB_T 147 | { 148 | union 149 | { 150 | struct 151 | { 152 | BYTE InheritedAddressSpace; 153 | BYTE ReadImageFileExecOptions; 154 | BYTE BeingDebugged; 155 | BYTE BitField; 156 | }; 157 | T dummy01; 158 | }; 159 | T Mutant; 160 | T ImageBaseAddress; 161 | T Ldr; 162 | T ProcessParameters; 163 | T SubSystemData; 164 | T ProcessHeap; 165 | T FastPebLock; 166 | T AtlThunkSListPtr; 167 | T IFEOKey; 168 | T CrossProcessFlags; 169 | T UserSharedInfoPtr; 170 | DWORD SystemReserved; 171 | DWORD AtlThunkSListPtr32; 172 | T ApiSetMap; 173 | T TlsExpansionCounter; 174 | T TlsBitmap; 175 | DWORD TlsBitmapBits[2]; 176 | T ReadOnlySharedMemoryBase; 177 | T HotpatchInformation; 178 | T ReadOnlyStaticServerData; 179 | T AnsiCodePageData; 180 | T OemCodePageData; 181 | T UnicodeCaseTableData; 182 | DWORD NumberOfProcessors; 183 | union 184 | { 185 | DWORD NtGlobalFlag; 186 | NGF dummy02; 187 | }; 188 | LARGE_INTEGER CriticalSectionTimeout; 189 | T HeapSegmentReserve; 190 | T HeapSegmentCommit; 191 | T HeapDeCommitTotalFreeThreshold; 192 | T HeapDeCommitFreeBlockThreshold; 193 | DWORD NumberOfHeaps; 194 | DWORD MaximumNumberOfHeaps; 195 | T ProcessHeaps; 196 | T GdiSharedHandleTable; 197 | T ProcessStarterHelper; 198 | T GdiDCAttributeList; 199 | T LoaderLock; 200 | DWORD OSMajorVersion; 201 | DWORD OSMinorVersion; 202 | WORD OSBuildNumber; 203 | WORD OSCSDVersion; 204 | DWORD OSPlatformId; 205 | DWORD ImageSubsystem; 206 | DWORD ImageSubsystemMajorVersion; 207 | T ImageSubsystemMinorVersion; 208 | T ActiveProcessAffinityMask; 209 | T GdiHandleBuffer[A]; 210 | T PostProcessInitRoutine; 211 | T TlsExpansionBitmap; 212 | DWORD TlsExpansionBitmapBits[32]; 213 | T SessionId; 214 | ULARGE_INTEGER AppCompatFlags; 215 | ULARGE_INTEGER AppCompatFlagsUser; 216 | T pShimData; 217 | T AppCompatInfo; 218 | _UNICODE_STRING_T CSDVersion; 219 | T ActivationContextData; 220 | T ProcessAssemblyStorageMap; 221 | T SystemDefaultActivationContextData; 222 | T SystemAssemblyStorageMap; 223 | T MinimumStackCommit; 224 | T FlsCallback; 225 | _LIST_ENTRY_T FlsListHead; 226 | T FlsBitmap; 227 | DWORD FlsBitmapBits[4]; 228 | T FlsHighIndex; 229 | T WerRegistrationData; 230 | T WerShipAssertPtr; 231 | T pContextData; 232 | T pImageHeaderHash; 233 | T TracingFlags; 234 | }; 235 | 236 | typedef _LDR_DATA_TABLE_ENTRY_T LDR_DATA_TABLE_ENTRY32; 237 | typedef _LDR_DATA_TABLE_ENTRY_T LDR_DATA_TABLE_ENTRY64; 238 | 239 | typedef _TEB_T_ TEB32; 240 | typedef _TEB_T_ TEB64; 241 | 242 | typedef _PEB_LDR_DATA_T PEB_LDR_DATA32; 243 | typedef _PEB_LDR_DATA_T PEB_LDR_DATA64; 244 | 245 | typedef _PEB_T PEB32; 246 | typedef _PEB_T PEB64; 247 | 248 | struct _XSAVE_FORMAT64 249 | { 250 | WORD ControlWord; 251 | WORD StatusWord; 252 | BYTE TagWord; 253 | BYTE Reserved1; 254 | WORD ErrorOpcode; 255 | DWORD ErrorOffset; 256 | WORD ErrorSelector; 257 | WORD Reserved2; 258 | DWORD DataOffset; 259 | WORD DataSelector; 260 | WORD Reserved3; 261 | DWORD MxCsr; 262 | DWORD MxCsr_Mask; 263 | _M128A FloatRegisters[8]; 264 | _M128A XmmRegisters[16]; 265 | BYTE Reserved4[96]; 266 | }; 267 | 268 | struct _CONTEXT64 269 | { 270 | DWORD64 P1Home; 271 | DWORD64 P2Home; 272 | DWORD64 P3Home; 273 | DWORD64 P4Home; 274 | DWORD64 P5Home; 275 | DWORD64 P6Home; 276 | DWORD ContextFlags; 277 | DWORD MxCsr; 278 | WORD SegCs; 279 | WORD SegDs; 280 | WORD SegEs; 281 | WORD SegFs; 282 | WORD SegGs; 283 | WORD SegSs; 284 | DWORD EFlags; 285 | DWORD64 Dr0; 286 | DWORD64 Dr1; 287 | DWORD64 Dr2; 288 | DWORD64 Dr3; 289 | DWORD64 Dr6; 290 | DWORD64 Dr7; 291 | DWORD64 Rax; 292 | DWORD64 Rcx; 293 | DWORD64 Rdx; 294 | DWORD64 Rbx; 295 | DWORD64 Rsp; 296 | DWORD64 Rbp; 297 | DWORD64 Rsi; 298 | DWORD64 Rdi; 299 | DWORD64 R8; 300 | DWORD64 R9; 301 | DWORD64 R10; 302 | DWORD64 R11; 303 | DWORD64 R12; 304 | DWORD64 R13; 305 | DWORD64 R14; 306 | DWORD64 R15; 307 | DWORD64 Rip; 308 | _XSAVE_FORMAT64 FltSave; 309 | _M128A Header[2]; 310 | _M128A Legacy[8]; 311 | _M128A Xmm0; 312 | _M128A Xmm1; 313 | _M128A Xmm2; 314 | _M128A Xmm3; 315 | _M128A Xmm4; 316 | _M128A Xmm5; 317 | _M128A Xmm6; 318 | _M128A Xmm7; 319 | _M128A Xmm8; 320 | _M128A Xmm9; 321 | _M128A Xmm10; 322 | _M128A Xmm11; 323 | _M128A Xmm12; 324 | _M128A Xmm13; 325 | _M128A Xmm14; 326 | _M128A Xmm15; 327 | _M128A VectorRegister[26]; 328 | DWORD64 VectorControl; 329 | DWORD64 DebugControl; 330 | DWORD64 LastBranchToRip; 331 | DWORD64 LastBranchFromRip; 332 | DWORD64 LastExceptionToRip; 333 | DWORD64 LastExceptionFromRip; 334 | }; 335 | 336 | // Below defines for .ContextFlags field are taken from WinNT.h 337 | #ifndef CONTEXT_AMD64 338 | #define CONTEXT_AMD64 0x100000 339 | #endif 340 | 341 | #define CONTEXT64_CONTROL (CONTEXT_AMD64 | 0x1L) 342 | #define CONTEXT64_INTEGER (CONTEXT_AMD64 | 0x2L) 343 | #define CONTEXT64_SEGMENTS (CONTEXT_AMD64 | 0x4L) 344 | #define CONTEXT64_FLOATING_POINT (CONTEXT_AMD64 | 0x8L) 345 | #define CONTEXT64_DEBUG_REGISTERS (CONTEXT_AMD64 | 0x10L) 346 | #define CONTEXT64_FULL (CONTEXT64_CONTROL | CONTEXT64_INTEGER | CONTEXT64_FLOATING_POINT) 347 | #define CONTEXT64_ALL (CONTEXT64_CONTROL | CONTEXT64_INTEGER | CONTEXT64_SEGMENTS | CONTEXT64_FLOATING_POINT | CONTEXT64_DEBUG_REGISTERS) 348 | #define CONTEXT64_XSTATE (CONTEXT_AMD64 | 0x20L) 349 | 350 | #pragma pack(pop) 351 | 352 | #ifdef WOW64EXT_EXPORTS 353 | # define SPEC dllexport 354 | #else 355 | # define SPEC dllimport 356 | #endif 357 | 358 | extern "C" 359 | { 360 | __declspec(SPEC) DWORD64 X64Call(DWORD64 func, int argC, ...); 361 | __declspec(SPEC) DWORD64 GetModuleHandle64(wchar_t* lpModuleName); 362 | __declspec(SPEC) DWORD64 GetProcAddress64(DWORD64 hModule, char* funcName); 363 | __declspec(SPEC) SIZE_T VirtualQueryEx64(HANDLE hProcess, DWORD64 lpAddress, MEMORY_BASIC_INFORMATION64* lpBuffer, SIZE_T dwLength); 364 | __declspec(SPEC) DWORD64 VirtualAllocEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); 365 | __declspec(SPEC) BOOL VirtualFreeEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD dwFreeType); 366 | __declspec(SPEC) BOOL VirtualProtectEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* lpflOldProtect); 367 | __declspec(SPEC) BOOL ReadProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead); 368 | __declspec(SPEC) BOOL WriteProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten); 369 | __declspec(SPEC) BOOL GetThreadContext64(HANDLE hThread, _CONTEXT64* lpContext); 370 | __declspec(SPEC) BOOL SetThreadContext64(HANDLE hThread, _CONTEXT64* lpContext); 371 | __declspec(SPEC) VOID SetLastErrorFromX64Call(DWORD64 status); 372 | } 373 | -------------------------------------------------------------------------------- /rewolf-wow64ext/src/wow64ext.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * WOW64Ext Library 4 | * 5 | * Copyright (c) 2014 ReWolf 6 | * http://blog.rewolf.pl/ 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU Lesser General Public License as published 10 | * by the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | * 21 | */ 22 | 23 | #include 24 | #include 25 | #include "internal.h" 26 | #include "wow64ext.h" 27 | #include "CMemPtr.h" 28 | 29 | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 30 | { 31 | return TRUE; 32 | } 33 | 34 | #pragma warning(push) 35 | #pragma warning(disable : 4409) 36 | extern "C" __declspec(dllexport) DWORD64 X64Call(DWORD64 func, int argC, ...) 37 | { 38 | va_list args; 39 | va_start(args, argC); 40 | reg64 _rcx = { (argC > 0) ? argC--, va_arg(args, DWORD64) : 0 }; 41 | reg64 _rdx = { (argC > 0) ? argC--, va_arg(args, DWORD64) : 0 }; 42 | reg64 _r8 = { (argC > 0) ? argC--, va_arg(args, DWORD64) : 0 }; 43 | reg64 _r9 = { (argC > 0) ? argC--, va_arg(args, DWORD64) : 0 }; 44 | reg64 _rax = { 0 }; 45 | 46 | reg64 restArgs = { (DWORD64)&va_arg(args, DWORD64) }; 47 | 48 | // conversion to QWORD for easier use in inline assembly 49 | reg64 _argC = { argC }; 50 | DWORD back_esp = 0; 51 | 52 | __asm 53 | { 54 | ;// keep original esp in back_esp variable 55 | mov back_esp, esp 56 | 57 | ;// align esp to 0x10, without aligned stack some syscalls may return errors ! 58 | ;// (actually, for syscalls it is sufficient to align to 8, but SSE opcodes 59 | ;// requires 0x10 alignment), it will be further adjusted according to the 60 | ;// number of arguments above 4 61 | and esp, 0xFFFFFFF0 62 | 63 | X64_Start(); 64 | 65 | ;// below code is compiled as x86 inline asm, but it is executed as x64 code 66 | ;// that's why it need sometimes REX_W() macro, right column contains detailed 67 | ;// transcription how it will be interpreted by CPU 68 | 69 | ;// fill first four arguments 70 | REX_W mov ecx, _rcx.dw[0] ;// mov rcx, qword ptr [_rcx] 71 | REX_W mov edx, _rdx.dw[0] ;// mov rdx, qword ptr [_rdx] 72 | push _r8.v ;// push qword ptr [_r8] 73 | X64_Pop(_R8); ;// pop r8 74 | push _r9.v ;// push qword ptr [_r9] 75 | X64_Pop(_R9); ;// pop r9 76 | ;// 77 | REX_W mov eax, _argC.dw[0] ;// mov rax, qword ptr [_argC] 78 | ;// 79 | ;// final stack adjustment, according to the ;// 80 | ;// number of arguments above 4 ;// 81 | test al, 1 ;// test al, 1 82 | jnz _no_adjust ;// jnz _no_adjust 83 | sub esp, 8 ;// sub rsp, 8 84 | _no_adjust: ;// 85 | ;// 86 | push edi ;// push rdi 87 | REX_W mov edi, restArgs.dw[0] ;// mov rdi, qword ptr [restArgs] 88 | ;// 89 | ;// put rest of arguments on the stack ;// 90 | REX_W test eax, eax ;// test rax, rax 91 | jz _ls_e ;// je _ls_e 92 | REX_W lea edi, dword ptr [edi + 8*eax - 8] ;// lea rdi, [rdi + rax*8 - 8] 93 | ;// 94 | _ls: ;// 95 | REX_W test eax, eax ;// test rax, rax 96 | jz _ls_e ;// je _ls_e 97 | push dword ptr [edi] ;// push qword ptr [rdi] 98 | REX_W sub edi, 8 ;// sub rdi, 8 99 | REX_W sub eax, 1 ;// sub rax, 1 100 | jmp _ls ;// jmp _ls 101 | _ls_e: ;// 102 | ;// 103 | ;// create stack space for spilling registers ;// 104 | REX_W sub esp, 0x20 ;// sub rsp, 20h 105 | ;// 106 | call func ;// call qword ptr [func] 107 | ;// 108 | ;// cleanup stack ;// 109 | REX_W mov ecx, _argC.dw[0] ;// mov rcx, qword ptr [_argC] 110 | REX_W lea esp, dword ptr [esp + 8*ecx + 0x20] ;// lea rsp, [rsp + rcx*8 + 20h] 111 | ;// 112 | pop edi ;// pop rdi 113 | ;// 114 | // set return value ;// 115 | REX_W mov _rax.dw[0], eax ;// mov qword ptr [_rax], rax 116 | 117 | X64_End(); 118 | 119 | mov esp, back_esp 120 | } 121 | return _rax.v; 122 | } 123 | #pragma warning(pop) 124 | 125 | void getMem64(void* dstMem, DWORD64 srcMem, size_t sz) 126 | { 127 | if ((nullptr == dstMem) || (0 == srcMem) || (0 == sz)) 128 | return; 129 | 130 | reg64 _src = { srcMem }; 131 | 132 | __asm 133 | { 134 | X64_Start(); 135 | 136 | ;// below code is compiled as x86 inline asm, but it is executed as x64 code 137 | ;// that's why it need sometimes REX_W() macro, right column contains detailed 138 | ;// transcription how it will be interpreted by CPU 139 | 140 | push edi ;// push rdi 141 | push esi ;// push rsi 142 | ;// 143 | mov edi, dstMem ;// mov edi, dword ptr [dstMem] ; high part of RDI is zeroed 144 | REX_W mov esi, _src.dw[0] ;// mov rsi, qword ptr [_src] 145 | mov ecx, sz ;// mov ecx, dword ptr [sz] ; high part of RCX is zeroed 146 | ;// 147 | mov eax, ecx ;// mov eax, ecx 148 | and eax, 3 ;// and eax, 3 149 | shr ecx, 2 ;// shr ecx, 2 150 | ;// 151 | rep movsd ;// rep movs dword ptr [rdi], dword ptr [rsi] 152 | ;// 153 | test eax, eax ;// test eax, eax 154 | je _move_0 ;// je _move_0 155 | cmp eax, 1 ;// cmp eax, 1 156 | je _move_1 ;// je _move_1 157 | ;// 158 | movsw ;// movs word ptr [rdi], word ptr [rsi] 159 | cmp eax, 2 ;// cmp eax, 2 160 | je _move_0 ;// je _move_0 161 | ;// 162 | _move_1: ;// 163 | movsb ;// movs byte ptr [rdi], byte ptr [rsi] 164 | ;// 165 | _move_0: ;// 166 | pop esi ;// pop rsi 167 | pop edi ;// pop rdi 168 | 169 | X64_End(); 170 | } 171 | } 172 | 173 | bool cmpMem64(void* dstMem, DWORD64 srcMem, size_t sz) 174 | { 175 | if ((nullptr == dstMem) || (0 == srcMem) || (0 == sz)) 176 | return false; 177 | 178 | bool result = false; 179 | reg64 _src = { srcMem }; 180 | __asm 181 | { 182 | X64_Start(); 183 | 184 | ;// below code is compiled as x86 inline asm, but it is executed as x64 code 185 | ;// that's why it need sometimes REX_W() macro, right column contains detailed 186 | ;// transcription how it will be interpreted by CPU 187 | 188 | push edi ;// push rdi 189 | push esi ;// push rsi 190 | ;// 191 | mov edi, dstMem ;// mov edi, dword ptr [dstMem] ; high part of RDI is zeroed 192 | REX_W mov esi, _src.dw[0] ;// mov rsi, qword ptr [_src] 193 | mov ecx, sz ;// mov ecx, dword ptr [sz] ; high part of RCX is zeroed 194 | ;// 195 | mov eax, ecx ;// mov eax, ecx 196 | and eax, 3 ;// and eax, 3 197 | shr ecx, 2 ;// shr ecx, 2 198 | ;// 199 | repe cmpsd ;// repe cmps dword ptr [rsi], dword ptr [rdi] 200 | jnz _ret_false ;// jnz _ret_false 201 | ;// 202 | test eax, eax ;// test eax, eax 203 | je _move_0 ;// je _move_0 204 | cmp eax, 1 ;// cmp eax, 1 205 | je _move_1 ;// je _move_1 206 | ;// 207 | cmpsw ;// cmps word ptr [rsi], word ptr [rdi] 208 | jnz _ret_false ;// jnz _ret_false 209 | cmp eax, 2 ;// cmp eax, 2 210 | je _move_0 ;// je _move_0 211 | ;// 212 | _move_1: ;// 213 | cmpsb ;// cmps byte ptr [rsi], byte ptr [rdi] 214 | jnz _ret_false ;// jnz _ret_false 215 | ;// 216 | _move_0: ;// 217 | mov result, 1 ;// mov byte ptr [result], 1 218 | ;// 219 | _ret_false: ;// 220 | pop esi ;// pop rsi 221 | pop edi ;// pop rdi 222 | 223 | X64_End(); 224 | } 225 | 226 | return result; 227 | } 228 | 229 | DWORD64 getTEB64() 230 | { 231 | reg64 reg; 232 | reg.v = 0; 233 | 234 | X64_Start(); 235 | // R12 register should always contain pointer to TEB64 in WoW64 processes 236 | X64_Push(_R12); 237 | // below pop will pop QWORD from stack, as we're in x64 mode now 238 | __asm pop reg.dw[0] 239 | X64_End(); 240 | 241 | return reg.v; 242 | } 243 | 244 | extern "C" __declspec(dllexport) DWORD64 GetModuleHandle64(wchar_t* lpModuleName) 245 | { 246 | TEB64 teb64; 247 | getMem64(&teb64, getTEB64(), sizeof(TEB64)); 248 | 249 | PEB64 peb64; 250 | getMem64(&peb64, teb64.ProcessEnvironmentBlock, sizeof(PEB64)); 251 | PEB_LDR_DATA64 ldr; 252 | getMem64(&ldr, peb64.Ldr, sizeof(PEB_LDR_DATA64)); 253 | 254 | DWORD64 LastEntry = peb64.Ldr + offsetof(PEB_LDR_DATA64, InLoadOrderModuleList); 255 | LDR_DATA_TABLE_ENTRY64 head; 256 | head.InLoadOrderLinks.Flink = ldr.InLoadOrderModuleList.Flink; 257 | do 258 | { 259 | getMem64(&head, head.InLoadOrderLinks.Flink, sizeof(LDR_DATA_TABLE_ENTRY64)); 260 | 261 | wchar_t* tempBuf = (wchar_t*)malloc(head.BaseDllName.MaximumLength); 262 | if (nullptr == tempBuf) 263 | return 0; 264 | WATCH(tempBuf); 265 | getMem64(tempBuf, head.BaseDllName.Buffer, head.BaseDllName.MaximumLength); 266 | 267 | if (0 == _wcsicmp(lpModuleName, tempBuf)) 268 | return head.DllBase; 269 | } 270 | while (head.InLoadOrderLinks.Flink != LastEntry); 271 | 272 | return 0; 273 | } 274 | 275 | DWORD64 getNTDLL64() 276 | { 277 | static DWORD64 ntdll64 = 0; 278 | if (0 != ntdll64) 279 | return ntdll64; 280 | 281 | ntdll64 = GetModuleHandle64(L"ntdll.dll"); 282 | return ntdll64; 283 | } 284 | 285 | DWORD64 getLdrGetProcedureAddress() 286 | { 287 | DWORD64 modBase = getNTDLL64(); 288 | 289 | IMAGE_DOS_HEADER idh; 290 | getMem64(&idh, modBase, sizeof(idh)); 291 | 292 | IMAGE_NT_HEADERS64 inh; 293 | getMem64(&inh, modBase + idh.e_lfanew, sizeof(IMAGE_NT_HEADERS64)); 294 | 295 | IMAGE_DATA_DIRECTORY& idd = inh.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 296 | 297 | if (0 == idd.VirtualAddress) 298 | return 0; 299 | 300 | IMAGE_EXPORT_DIRECTORY ied; 301 | getMem64(&ied, modBase + idd.VirtualAddress, sizeof(ied)); 302 | 303 | DWORD* rvaTable = (DWORD*)malloc(sizeof(DWORD)*ied.NumberOfFunctions); 304 | if (nullptr == rvaTable) 305 | return 0; 306 | WATCH(rvaTable); 307 | getMem64(rvaTable, modBase + ied.AddressOfFunctions, sizeof(DWORD)*ied.NumberOfFunctions); 308 | 309 | WORD* ordTable = (WORD*)malloc(sizeof(WORD)*ied.NumberOfFunctions); 310 | if (nullptr == ordTable) 311 | return 0; 312 | WATCH(ordTable); 313 | getMem64(ordTable, modBase + ied.AddressOfNameOrdinals, sizeof(WORD)*ied.NumberOfFunctions); 314 | 315 | DWORD* nameTable = (DWORD*)malloc(sizeof(DWORD)*ied.NumberOfNames); 316 | if (nullptr == nameTable) 317 | return 0; 318 | WATCH(nameTable); 319 | getMem64(nameTable, modBase + ied.AddressOfNames, sizeof(DWORD)*ied.NumberOfNames); 320 | 321 | // lazy search, there is no need to use binsearch for just one function 322 | for (DWORD i = 0; i < ied.NumberOfFunctions; i++) 323 | { 324 | if (!cmpMem64("LdrGetProcedureAddress", modBase + nameTable[i], sizeof("LdrGetProcedureAddress"))) 325 | continue; 326 | else 327 | return modBase + rvaTable[ordTable[i]]; 328 | } 329 | return 0; 330 | } 331 | 332 | extern "C" __declspec(dllexport) VOID SetLastErrorFromX64Call(DWORD64 status) 333 | { 334 | typedef ULONG (WINAPI *RtlNtStatusToDosError_t)(NTSTATUS Status); 335 | typedef ULONG (WINAPI *RtlSetLastWin32Error_t)(NTSTATUS Status); 336 | 337 | static RtlNtStatusToDosError_t RtlNtStatusToDosError = nullptr; 338 | static RtlSetLastWin32Error_t RtlSetLastWin32Error = nullptr; 339 | 340 | if ((nullptr == RtlNtStatusToDosError) || (nullptr == RtlSetLastWin32Error)) 341 | { 342 | HMODULE ntdll = GetModuleHandleW(L"ntdll.dll"); 343 | RtlNtStatusToDosError = (RtlNtStatusToDosError_t)GetProcAddress(ntdll, "RtlNtStatusToDosError"); 344 | RtlSetLastWin32Error = (RtlSetLastWin32Error_t)GetProcAddress(ntdll, "RtlSetLastWin32Error"); 345 | } 346 | 347 | if ((nullptr != RtlNtStatusToDosError) && (nullptr != RtlSetLastWin32Error)) 348 | { 349 | RtlSetLastWin32Error(RtlNtStatusToDosError((DWORD)status)); 350 | } 351 | } 352 | 353 | extern "C" __declspec(dllexport) DWORD64 GetProcAddress64(DWORD64 hModule, char* funcName) 354 | { 355 | static DWORD64 _LdrGetProcedureAddress = 0; 356 | if (0 == _LdrGetProcedureAddress) 357 | { 358 | _LdrGetProcedureAddress = getLdrGetProcedureAddress(); 359 | if (0 == _LdrGetProcedureAddress) 360 | return 0; 361 | } 362 | 363 | _UNICODE_STRING_T fName = { 0 }; 364 | fName.Buffer = (DWORD64)funcName; 365 | fName.Length = strlen(funcName); 366 | fName.MaximumLength = fName.Length + 1; 367 | DWORD64 funcRet = 0; 368 | X64Call(_LdrGetProcedureAddress, 4, (DWORD64)hModule, (DWORD64)&fName, (DWORD64)0, (DWORD64)&funcRet); 369 | return funcRet; 370 | } 371 | 372 | extern "C" __declspec(dllexport) SIZE_T VirtualQueryEx64(HANDLE hProcess, DWORD64 lpAddress, MEMORY_BASIC_INFORMATION64* lpBuffer, SIZE_T dwLength) 373 | { 374 | static DWORD64 ntqvm = 0; 375 | if (0 == ntqvm) 376 | { 377 | ntqvm = GetProcAddress64(getNTDLL64(), "NtQueryVirtualMemory"); 378 | if (0 == ntqvm) 379 | return 0; 380 | } 381 | DWORD64 ret = 0; 382 | DWORD64 status = X64Call(ntqvm, 6, (DWORD64)hProcess, lpAddress, (DWORD64)0, (DWORD64)lpBuffer, (DWORD64)dwLength, (DWORD64)&ret); 383 | if (STATUS_SUCCESS != status) 384 | SetLastErrorFromX64Call(status); 385 | return (SIZE_T)ret; 386 | } 387 | 388 | extern "C" __declspec(dllexport) DWORD64 VirtualAllocEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect) 389 | { 390 | static DWORD64 ntavm = 0; 391 | if (0 == ntavm) 392 | { 393 | ntavm = GetProcAddress64(getNTDLL64(), "NtAllocateVirtualMemory"); 394 | if (0 == ntavm) 395 | return 0; 396 | } 397 | 398 | DWORD64 tmpAddr = lpAddress; 399 | DWORD64 tmpSize = dwSize; 400 | DWORD64 ret = X64Call(ntavm, 6, (DWORD64)hProcess, (DWORD64)&tmpAddr, (DWORD64)0, (DWORD64)&tmpSize, (DWORD64)flAllocationType, (DWORD64)flProtect); 401 | if (STATUS_SUCCESS != ret) 402 | { 403 | SetLastErrorFromX64Call(ret); 404 | return FALSE; 405 | } 406 | else 407 | return tmpAddr; 408 | } 409 | 410 | extern "C" __declspec(dllexport) BOOL VirtualFreeEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD dwFreeType) 411 | { 412 | static DWORD64 ntfvm = 0; 413 | if (0 == ntfvm) 414 | { 415 | ntfvm = GetProcAddress64(getNTDLL64(), "NtFreeVirtualMemory"); 416 | if (0 == ntfvm) 417 | return 0; 418 | } 419 | 420 | DWORD64 tmpAddr = lpAddress; 421 | DWORD64 tmpSize = dwSize; 422 | DWORD64 ret = X64Call(ntfvm, 4, (DWORD64)hProcess, (DWORD64)&tmpAddr, (DWORD64)&tmpSize, (DWORD64)dwFreeType); 423 | if (STATUS_SUCCESS != ret) 424 | { 425 | SetLastErrorFromX64Call(ret); 426 | return FALSE; 427 | } 428 | else 429 | return TRUE; 430 | } 431 | 432 | extern "C" __declspec(dllexport) BOOL VirtualProtectEx64(HANDLE hProcess, DWORD64 lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* lpflOldProtect) 433 | { 434 | static DWORD64 ntpvm = 0; 435 | if (0 == ntpvm) 436 | { 437 | ntpvm = GetProcAddress64(getNTDLL64(), "NtProtectVirtualMemory"); 438 | if (0 == ntpvm) 439 | return 0; 440 | } 441 | 442 | DWORD64 tmpAddr = lpAddress; 443 | DWORD64 tmpSize = dwSize; 444 | DWORD64 ret = X64Call(ntpvm, 5, (DWORD64)hProcess, (DWORD64)&tmpAddr, (DWORD64)&tmpSize, (DWORD64)flNewProtect, (DWORD64)lpflOldProtect); 445 | if (STATUS_SUCCESS != ret) 446 | { 447 | SetLastErrorFromX64Call(ret); 448 | return FALSE; 449 | } 450 | else 451 | return TRUE; 452 | } 453 | 454 | extern "C" __declspec(dllexport) BOOL ReadProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead) 455 | { 456 | static DWORD64 nrvm = 0; 457 | if (0 == nrvm) 458 | { 459 | nrvm = GetProcAddress64(getNTDLL64(), "NtReadVirtualMemory"); 460 | if (0 == nrvm) 461 | return 0; 462 | } 463 | DWORD64 numOfBytes = lpNumberOfBytesRead ? *lpNumberOfBytesRead : 0; 464 | DWORD64 ret = X64Call(nrvm, 5, (DWORD64)hProcess, lpBaseAddress, (DWORD64)lpBuffer, (DWORD64)nSize, (DWORD64)&numOfBytes); 465 | if (STATUS_SUCCESS != ret) 466 | { 467 | SetLastErrorFromX64Call(ret); 468 | return FALSE; 469 | } 470 | else 471 | { 472 | if (lpNumberOfBytesRead) 473 | *lpNumberOfBytesRead = (SIZE_T)numOfBytes; 474 | return TRUE; 475 | } 476 | } 477 | 478 | extern "C" __declspec(dllexport) BOOL WriteProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten) 479 | { 480 | static DWORD64 nrvm = 0; 481 | if (0 == nrvm) 482 | { 483 | nrvm = GetProcAddress64(getNTDLL64(), "NtWriteVirtualMemory"); 484 | if (0 == nrvm) 485 | return 0; 486 | } 487 | DWORD64 numOfBytes = lpNumberOfBytesWritten ? *lpNumberOfBytesWritten : 0; 488 | DWORD64 ret = X64Call(nrvm, 5, (DWORD64)hProcess, lpBaseAddress, (DWORD64)lpBuffer, (DWORD64)nSize, (DWORD64)&numOfBytes); 489 | if (STATUS_SUCCESS != ret) 490 | { 491 | SetLastErrorFromX64Call(ret); 492 | return FALSE; 493 | } 494 | else 495 | { 496 | if (lpNumberOfBytesWritten) 497 | *lpNumberOfBytesWritten = (SIZE_T)numOfBytes; 498 | return TRUE; 499 | } 500 | } 501 | 502 | extern "C" __declspec(dllexport) BOOL GetThreadContext64(HANDLE hThread, _CONTEXT64* lpContext) 503 | { 504 | static DWORD64 gtc = 0; 505 | if (0 == gtc) 506 | { 507 | gtc = GetProcAddress64(getNTDLL64(), "NtGetContextThread"); 508 | if (0 == gtc) 509 | return 0; 510 | } 511 | DWORD64 ret = X64Call(gtc, 2, (DWORD64)hThread, (DWORD64)lpContext); 512 | if(STATUS_SUCCESS != ret) 513 | { 514 | SetLastErrorFromX64Call(ret); 515 | return FALSE; 516 | } 517 | else 518 | return TRUE; 519 | } 520 | 521 | extern "C" __declspec(dllexport) BOOL SetThreadContext64(HANDLE hThread, _CONTEXT64* lpContext) 522 | { 523 | static DWORD64 stc = 0; 524 | if (0 == stc) 525 | { 526 | stc = GetProcAddress64(getNTDLL64(), "NtSetContextThread"); 527 | if (0 == stc) 528 | return 0; 529 | } 530 | DWORD64 ret = X64Call(stc, 2, (DWORD64)hThread, (DWORD64)lpContext); 531 | if (STATUS_SUCCESS != ret) 532 | { 533 | SetLastErrorFromX64Call(ret); 534 | return FALSE; 535 | } 536 | else 537 | return TRUE; 538 | } 539 | --------------------------------------------------------------------------------