├── X86emu_private.h ├── hde28c ├── Makefile ├── README ├── NEWS ├── LICENSE ├── hde32.h ├── table32.h └── hde32.cpp ├── os ├── os.h └── os.cpp ├── .gitattributes ├── macros.h ├── examples └── EmulatorTest │ ├── EmulatorTest.vcxproj.filters │ ├── EmulatorTest.vcproj │ ├── EmulatorTest.vcxproj │ └── main.cpp ├── main.cpp ├── stack.cpp ├── apis ├── apis.h ├── apis_emu.cpp └── apis.cpp ├── log.cpp ├── X86 Emulator.sln ├── disasm └── disassembler.h ├── dbg ├── asm │ └── asm_dbg.cpp └── dbg.cpp ├── .gitignore ├── system.cpp ├── seh.h ├── emu ├── fpu.cpp ├── emu.h ├── strings.cpp └── jmps.cpp ├── X86 Emulator.vcxproj.filters ├── seh.cpp ├── X86 Emulator.vcxproj ├── X86 Emulator.vcproj ├── thread.cpp ├── tib.h ├── vmem.cpp ├── pe.cpp └── pe.h /X86emu_private.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrThabet/x86Emulator/HEAD/X86emu_private.h -------------------------------------------------------------------------------- /hde28c/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -Wall -c 3 | 4 | hde32.o: hde32.c hde32.h table32.h 5 | $(CC) $(CFLAGS) $< 6 | -------------------------------------------------------------------------------- /hde28c/README: -------------------------------------------------------------------------------- 1 | Hacker Disassembler Engine 32 C 0.28.01 2 | 3 | This is C version of Hacker Disassembler Engine 32. Documentation, 4 | headers and example files you can get from original (i386-assembler) 5 | version of HDE32, which available at http://patkov-site.narod.ru/ 6 | 7 | --- 8 | Author: Vyacheslav Patkov 9 | E-mail: patkov-mail@mail.ru 10 | Jabber: patkov@jabber.ru 11 | -------------------------------------------------------------------------------- /os/os.h: -------------------------------------------------------------------------------- 1 | #ifndef __OS__ 2 | #define __OS__ 1 3 | struct FileMapping{ 4 | unsigned long hFile; 5 | unsigned long hMapping; 6 | unsigned long BaseAddress; 7 | unsigned long FileLength; 8 | }; 9 | //unsigned long LoadProcess(string); 10 | unsigned long GetTime(); 11 | FileMapping* OpenFile(const char*); 12 | FileMapping* OpenFile2(const char*); 13 | FileMapping* CreateNewFile(const char* Filename,unsigned long size); 14 | unsigned long CloseFile(FileMapping*); 15 | #endif -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /hde28c/NEWS: -------------------------------------------------------------------------------- 1 | version 0.28.01 [2009.03.09] 2 | + updated to HDE32 0.28 3 | 4 | version 0.27.01 [2009.01.02] 5 | + fixed bug: error setting 0x800000 flag to "hde32s.flags" when no prefixes 6 | 7 | version 0.25.01 [2008.10.08] 8 | + updated to HDE32 0.25 9 | 10 | version 0.24.01 [2008.09.11] 11 | + updated to HDE32 0.24 12 | 13 | version 0.20.01 [2008.09.06] 14 | + updated to HDE32 0.20 15 | 16 | version 0.19.01 [2008.08.28] 17 | + updated to HDE32 0.19 18 | 19 | version 0.15.01 [2008.08.16] 20 | + updated to HDE32 0.15 21 | + new version format: x.xx.yy, x.xx - base HDE32 version, yy - HDE32C version 22 | 23 | version 0.02 [2008.08.09] (new version format: 0.13.02) 24 | + added readme.txt and license.txt 25 | 26 | version 0.01 [2008.08.04] (new version format: 0.13.01) 27 | + first release 28 | -------------------------------------------------------------------------------- /macros.h: -------------------------------------------------------------------------------- 1 | #define EMU_WRITE_MEM(x,y,z) \ 2 | int writememError = thread.mem->write_virtual_mem(x,y,z); \ 3 | if (writememError != 0)return writememError; 4 | 5 | #define EMU_READ_MEM(ptr,x) \ 6 | ptr =(DWORD*)thread.mem->read_virtual_mem((DWORD)x); \ 7 | if(ptr == 0)return EXP_INVALIDPOINTER; 8 | 9 | 10 | 11 | #define API_WRITE_MEM(x,y,z) \ 12 | int writememError = thread->mem->write_virtual_mem(x,y,z); \ 13 | if (writememError != 0)return writememError; 14 | 15 | #define API_READ_MEM(ptr,x) \ 16 | ptr =(DWORD*)thread->mem->read_virtual_mem((DWORD)x); \ 17 | if(ptr == 0)return 0; 18 | 19 | 20 | 21 | #define SEH_WRITE_MEM(x,y,z) \ 22 | int writememError = this->mem->write_virtual_mem(x,y,z); \ 23 | if (writememError != 0)return writememError; 24 | 25 | #define SEH_READ_MEM(ptr,x) \ 26 | ptr=(DWORD*)this->mem->read_virtual_mem((DWORD)x); \ 27 | if(ptr == 0)return EXP_INVALIDPOINTER; 28 | 29 | -------------------------------------------------------------------------------- /examples/EmulatorTest/EmulatorTest.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;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 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | #define __MAIN__ 21 | // #include 22 | // #include 23 | // #include "x86emu.h" 24 | // using namespace std; 25 | 26 | bool DllMain(unsigned long hInst /* Library instance handle. */, unsigned long reason /* Reason this function is being called. */, unsigned long reserved /* Not used. */) { 27 | /* Returns TRUE on success, FALSE on failure */ 28 | return true; 29 | } 30 | -------------------------------------------------------------------------------- /stack.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | #include "x86emu.h" 21 | Stack::Stack(Thread & s) { 22 | thread = &s; 23 | } 24 | 25 | void Stack::push(DWORD value) { 26 | thread->mem->write_virtual_mem(thread->Exx[4] - 4, (DWORD) 4, (unsigned char *) &value); 27 | thread->Exx[4] -= 4; 28 | } 29 | 30 | int Stack::pop() { 31 | int value; 32 | int * ptr = (int *) thread->mem->read_virtual_mem(thread->Exx[4]); 33 | 34 | thread->Exx[4] += 4; 35 | memcpy(&value, ptr, 4); 36 | return value; 37 | } 38 | -------------------------------------------------------------------------------- /apis/apis.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | #define __APIS__ 2 21 | 22 | //class Thread{}; 23 | //APIs Emulation 24 | //------------- 25 | int GetProcAddress_emu(Thread* thread,DWORD* Args); 26 | int GetModuleHandleA_emu(Thread* thread,DWORD* Args); 27 | int LoadLibraryA_emu(Thread* thread,DWORD* Args); 28 | int VirtualAlloc_emu(Thread* thread,DWORD* Args); 29 | int VirtualFree_emu(Thread* thread,DWORD* Args); 30 | int VirtualProtect_emu(Thread* thread,DWORD* Args); 31 | int SetUnhandledExceptionFilter_emu(Thread* thread,DWORD* Args); 32 | -------------------------------------------------------------------------------- /log.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | #include "x86emu.h" 21 | Log::Log(DWORD firstentry) { 22 | cur = 0; 23 | log[cur] = firstentry; 24 | cur++; 25 | } 26 | 27 | void Log::addlog(DWORD entry) { 28 | log[cur] = entry; 29 | cur++; 30 | if (cur == 10) { 31 | cur = 0; 32 | } 33 | } 34 | 35 | DWORD Log::getlog(int index) { 36 | if ((index < 0) || (index > 10)) { 37 | return 0; 38 | } 39 | index = cur - index - 1; 40 | if (index < 0) { 41 | index += 10; 42 | } 43 | return log[index]; 44 | } 45 | -------------------------------------------------------------------------------- /X86 Emulator.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual C++ Express 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "X86 Emulator", "X86 Emulator.vcxproj", "{480D2E91-BE84-4D0D-A4C4-78F0CA8ABFE0}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EmulatorTest", "examples\EmulatorTest\EmulatorTest.vcxproj", "{C1F83850-A9E2-49A3-8C88-8B527BAFC40E}" 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 | {480D2E91-BE84-4D0D-A4C4-78F0CA8ABFE0}.Debug|Win32.ActiveCfg = Release|Win32 15 | {480D2E91-BE84-4D0D-A4C4-78F0CA8ABFE0}.Debug|Win32.Build.0 = Release|Win32 16 | {480D2E91-BE84-4D0D-A4C4-78F0CA8ABFE0}.Release|Win32.ActiveCfg = Release|Win32 17 | {480D2E91-BE84-4D0D-A4C4-78F0CA8ABFE0}.Release|Win32.Build.0 = Release|Win32 18 | {C1F83850-A9E2-49A3-8C88-8B527BAFC40E}.Debug|Win32.ActiveCfg = Release|Win32 19 | {C1F83850-A9E2-49A3-8C88-8B527BAFC40E}.Debug|Win32.Build.0 = Release|Win32 20 | {C1F83850-A9E2-49A3-8C88-8B527BAFC40E}.Release|Win32.ActiveCfg = Release|Win32 21 | {C1F83850-A9E2-49A3-8C88-8B527BAFC40E}.Release|Win32.Build.0 = Release|Win32 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /hde28c/LICENSE: -------------------------------------------------------------------------------- 1 | License agreement 2 | 3 | Hacker Disassembler Engine 32 C 4 | Copyright (c) 2008-2009, Vyacheslav Patkov. 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions 9 | are met: 10 | 11 | 1. Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | 2. Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in the 15 | documentation and/or other materials provided with the distribution. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 20 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 21 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /disasm/disassembler.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | #ifndef __DISASSEMBLER__ 7 | 8 | 9 | #define __DISASSEMBLER__ 1 10 | 11 | 12 | /* 13 | * 14 | * Copyright (C) 2010-2011 Amr Thabet 15 | * 16 | * This program is free software; you can redistribute it and/or modify 17 | * it under the terms of the GNU General Public License as published by 18 | * the Free Software Foundation; either version 2 of the License, or 19 | * (at your option) any later version. 20 | * 21 | * This program is distributed in the hope that it will be useful, 22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | * GNU General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU General Public License 27 | * along with this program; if not, write to Amr Thabet 28 | * amr.thabet@student.alx.edu.eg 29 | * 30 | */ 31 | 32 | 33 | //int imm_to_dec(string); 34 | extern string reg32[8]; 35 | #ifdef __DISASM__ 36 | //int dis_entries; 37 | //FLAGTABLE* FlagTable; 38 | //extern int dis_entries; 39 | //extern FLAGTABLE FlagTable[512*7]; 40 | 41 | extern string reg16[8]; 42 | extern string reg8[8]; 43 | extern string seg[6]; 44 | extern string rm_sizes[3]; 45 | extern string numbers[10]; 46 | extern string prefixes[3]; 47 | #endif 48 | #endif 49 | -------------------------------------------------------------------------------- /dbg/asm/asm_dbg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | 21 | #include "../../x86emu.h" 22 | int AsmDebugger::AddBp(string s) { 23 | bp[nbp].ptr = parser(s); 24 | bp[nbp].state = BP_RUN; 25 | string str; 26 | DWORD n = bp[nbp].ptr; 27 | 28 | /* 29 | for (int i=0;i<24;i++){ 30 | DISASM_INSTRUCTION* ins=process->getsystem()->disasm((DISASM_INSTRUCTION*)malloc(sizeof(DISASM_INSTRUCTION)),(char*)n,str); 31 | n+=ins->hde.len; 32 | //cout << str <<"\n"; 33 | }; 34 | */ 35 | nbp++; 36 | return nbp - 1; 37 | } 38 | 39 | bool AsmDebugger::TestBp(int num, Thread & thread, DISASM_INSTRUCTION * ins) { 40 | if (num >= nbp) { 41 | return false; // outside the limits 42 | } 43 | int b = call_to_func(bp[num].ptr, (DWORD) & thread, (DWORD) ins); 44 | if (b != 0) { 45 | return true; 46 | } 47 | return false; 48 | } 49 | 50 | bool AsmDebugger::TestBp(Thread & thread, DISASM_INSTRUCTION * ins) { 51 | bool b = false; 52 | 53 | for (int n = 0; n < nbp; n++) { 54 | int i = n; 55 | if (bp[i].state == BP_RUN) { 56 | b = TestBp(i, thread, ins); 57 | } 58 | if (b == true) { 59 | goto YES; 60 | } 61 | } 62 | return false; 63 | YES: 64 | return true; 65 | } 66 | 67 | AsmDebugger::AsmDebugger(Process & c) { 68 | process = &c; 69 | func_entries = 0; 70 | init_funcs(); 71 | nbp = 0; 72 | lasterror = ""; 73 | } 74 | 75 | int call_to_func(DWORD mem, DWORD a, DWORD c) { 76 | int b = 0; 77 | 78 | // cout << a << "\n"; 79 | __asm 80 | { 81 | mov eax,mem 82 | mov ecx, a 83 | mov edx, c 84 | push ecx 85 | call eax 86 | pop ecx 87 | mov b,eax 88 | } 89 | // cout << n << "\n"; 90 | return b; 91 | } 92 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | 66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 67 | #packages/ 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper* 82 | 83 | # Installshield output folder 84 | [Ee]xpress 85 | 86 | # DocProject is a documentation generator add-in 87 | DocProject/buildhelp/ 88 | DocProject/Help/*.HxT 89 | DocProject/Help/*.HxC 90 | DocProject/Help/*.hhc 91 | DocProject/Help/*.hhk 92 | DocProject/Help/*.hhp 93 | DocProject/Help/Html2 94 | DocProject/Help/html 95 | 96 | # Click-Once directory 97 | publish 98 | 99 | # Others 100 | [Bb]in 101 | [Oo]bj 102 | sql 103 | TestResults 104 | *.Cache 105 | ClientBin 106 | stylecop.* 107 | ~$* 108 | *.dbmdl 109 | Generated_Code #added for RIA/Silverlight projects 110 | 111 | # Backup & report files from converting an old project file to a newer 112 | # Visual Studio version. Backup files are not needed, because we have git ;-) 113 | _UpgradeReport_Files/ 114 | Backup*/ 115 | UpgradeLog*.XML 116 | 117 | 118 | 119 | ############ 120 | ## Windows 121 | ############ 122 | 123 | # Windows image file caches 124 | Thumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | 130 | ############# 131 | ## Python 132 | ############# 133 | 134 | *.py[co] 135 | 136 | # Packages 137 | *.egg 138 | *.egg-info 139 | dist 140 | build 141 | eggs 142 | parts 143 | bin 144 | var 145 | sdist 146 | develop-eggs 147 | .installed.cfg 148 | 149 | # Installer logs 150 | pip-log.txt 151 | 152 | # Unit test / coverage reports 153 | .coverage 154 | .tox 155 | 156 | #Translations 157 | *.mo 158 | 159 | #Mr Developer 160 | .mr.developer.cfg 161 | 162 | # Mac crap 163 | .DS_Store 164 | -------------------------------------------------------------------------------- /system.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | 21 | #include "x86emu.h" 22 | #ifdef WIN32 23 | #include "windows.h" 24 | #endif 25 | System::System(EnviromentVariables * v) 26 | { 27 | dis_entries = 0; 28 | 29 | // 1.initialize the opcodes 30 | 31 | opcodes_init(); 32 | // 2.initalize the environment variables 33 | 34 | init_vars(v); 35 | // 3.initalize the API calls 36 | dll_entries = 0; 37 | api_entries = 0; 38 | init_apis(enVars.dllspath); 39 | } 40 | 41 | // For disassembling and assembling only 42 | 43 | System::System() 44 | { 45 | dis_entries = 0; 46 | 47 | // initialize the opcodes 48 | 49 | opcodes_init(); 50 | dll_entries = 0; 51 | api_entries = 0; 52 | } 53 | 54 | System::~System() { 55 | for (int i = 0; i < dll_entries; i++) { 56 | #ifdef WIN32 57 | VirtualFree((void *) DLLs[0].imagebase, DLLs[0].size, MEM_DECOMMIT); 58 | #else 59 | free((void *) DLLs[i].imagebase); 60 | #endif 61 | } 62 | } 63 | 64 | //Here just initialize the addresses 65 | void System::init_vars(EnviromentVariables * v) 66 | { 67 | if (v->kernel32 != 0) { 68 | this->enVars.kernel32 = v->kernel32; 69 | } else { 70 | this->enVars.kernel32 = 0x75EE0000; 71 | } 72 | if (v->ntdll != 0) { 73 | this->enVars.ntdll = v->ntdll; 74 | } else { 75 | this->enVars.ntdll = 0x77580000; 76 | } 77 | if (v->user32 != 0) { 78 | this->enVars.user32 = v->user32; 79 | } else { 80 | this->enVars.user32 = 0x759D0000; 81 | } 82 | if ((DWORD) v->dllspath == 0) { 83 | this->enVars.dllspath = ""; 84 | } else { 85 | this->enVars.dllspath = v->dllspath; 86 | } 87 | if ((DWORD) v->MaxIterations == 0) { 88 | this->enVars.MaxIterations = 10000000; // 10 million iterations 89 | } else { 90 | this->enVars.MaxIterations = v->MaxIterations; 91 | } 92 | } 93 | 94 | string System::getversion() { 95 | return "1.20"; 96 | } 97 | 98 | string System::getCopyrights() { 99 | return "Pokas x86 Emulator v. 1.20 \n \ 100 | Copyrights � by AmrThabet @ 2010 and all rights reserved to him\n"; 101 | } 102 | -------------------------------------------------------------------------------- /hde28c/hde32.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 32 3 | * Copyright (c) 2006-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | * hde32.h: C/C++ header file 7 | * 8 | */ 9 | 10 | #ifndef _HDE32_H_ 11 | #define _HDE32_H_ 12 | 13 | /* stdint.h - C99 standard header 14 | * http://en.wikipedia.org/wiki/stdint.h 15 | * 16 | * if your compiler doesn't contain "stdint.h" header (for 17 | * example, Microsoft Visual C++), you can download file: 18 | * http://www.azillionmonkeys.com/qed/pstdint.h 19 | * and change next line to: 20 | * #include "pstdint.h" 21 | */ 22 | 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | //#include 29 | 30 | #define F_MODRM 0x00000001 31 | #define F_SIB 0x00000002 32 | #define F_IMM8 0x00000004 33 | #define F_IMM16 0x00000008 34 | #define F_IMM32 0x00000010 35 | #define F_DISP8 0x00000020 36 | #define F_DISP16 0x00000040 37 | #define F_DISP32 0x00000080 38 | #define F_RELATIVE 0x00000100 39 | #define F_2IMM16 0x00000800 40 | #define F_ERROR 0x00001000 41 | #define F_ERROR_OPCODE 0x00002000 42 | #define F_ERROR_LENGTH 0x00004000 43 | #define F_ERROR_LOCK 0x00008000 44 | #define F_ERROR_OPERAND 0x00010000 45 | #define F_PREFIX_REPNZ 0x01000000 46 | #define F_PREFIX_REPX 0x02000000 47 | #define F_PREFIX_REP 0x03000000 48 | #define F_PREFIX_66 0x04000000 49 | #define F_PREFIX_67 0x08000000 50 | #define F_PREFIX_LOCK 0x10000000 51 | #define F_PREFIX_SEG 0x20000000 52 | #define F_PREFIX_ANY 0x3f000000 53 | 54 | #define PREFIX_SEGMENT_CS 0x2e 55 | #define PREFIX_SEGMENT_SS 0x36 56 | #define PREFIX_SEGMENT_DS 0x3e 57 | #define PREFIX_SEGMENT_ES 0x26 58 | #define PREFIX_SEGMENT_FS 0x64 59 | #define PREFIX_SEGMENT_GS 0x65 60 | #define PREFIX_LOCK 0xf0 61 | #define PREFIX_REPNZ 0xf2 62 | #define PREFIX_REPX 0xf3 63 | #define PREFIX_OPERAND_SIZE 0x66 64 | #define PREFIX_ADDRESS_SIZE 0x67 65 | 66 | #pragma pack(push,1) 67 | 68 | struct hde32s{ 69 | unsigned char len; 70 | unsigned char p_rep; 71 | unsigned char p_lock; 72 | unsigned char p_seg; 73 | unsigned char p_66; 74 | unsigned char p_67; 75 | unsigned char opcode; 76 | unsigned char opcode2; 77 | unsigned char modrm; 78 | unsigned char modrm_mod; 79 | unsigned char modrm_reg; 80 | unsigned char modrm_rm; 81 | unsigned char sib; 82 | unsigned char sib_scale; 83 | unsigned char sib_index; 84 | unsigned char sib_base; 85 | union { 86 | unsigned char imm8; 87 | unsigned short imm16; 88 | unsigned long imm32; 89 | } imm; 90 | union { 91 | unsigned char disp8; 92 | unsigned short disp16; 93 | unsigned long disp32; 94 | } disp; 95 | unsigned long flags; 96 | }; 97 | #pragma pack(pop) 98 | /* __cdecl */ 99 | unsigned long hde32_disasm(const void *code,struct hde32s *hs); 100 | 101 | #ifdef __cplusplus 102 | } 103 | #endif 104 | #else 105 | struct hde32s; 106 | unsigned int hde32_disasm(const void *code,hde32s *hs); 107 | #endif /* _HDE32_H_ */ 108 | -------------------------------------------------------------------------------- /seh.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | 21 | 22 | #define SEH_MAGIC 0xBBBBBBBB 23 | 24 | #define SIZEOF_387_REGS 80 25 | #define MAXIMUM_EXTENSION 512 26 | 27 | //Some exception codes 28 | 29 | //Read or write memory violation 30 | #define MEM_ACCESS 0xC0000005 31 | 32 | //Divide by zero 33 | #define DIV_ZERO_EXCEPTION 0xC0000094 34 | 35 | //Divide overflow 36 | #define DIV_OFLOW 0xC0000095 37 | 38 | //The stack went beyond the maximum available size 39 | #define STACK_OVERFLOW 0xC00000FD 40 | 41 | //Violation of a guard page in memory set up using Virtual Alloc 42 | #define GUARD_ERROR 0x80000001 43 | 44 | 45 | #define CONTINUABLE 0 46 | #define NON_CONTINUABLE 1 47 | #define STACK_UNWINDING 2 48 | 49 | #ifndef WIN32 50 | struct FLOATING_SAVE_AREA { 51 | DWORD ControlWord; 52 | DWORD StatusWord; 53 | DWORD TagWord; 54 | DWORD ErrorOffset; 55 | DWORD ErrorSelector; 56 | DWORD DataOffset; 57 | DWORD DataSelector; 58 | byte RegisterArea[SIZEOF_387_REGS]; 59 | DWORD Cr0NpxState; 60 | }; 61 | 62 | 63 | struct CONTEXT { 64 | 65 | DWORD ContextFlags; 66 | 67 | DWORD Dr0; 68 | DWORD Dr1; 69 | DWORD Dr2; 70 | DWORD Dr3; 71 | DWORD Dr6; 72 | DWORD Dr7; 73 | 74 | FLOATING_SAVE_AREA FloatSave; 75 | 76 | DWORD SegGs; 77 | DWORD SegFs; 78 | DWORD SegEs; 79 | DWORD SegDs; 80 | 81 | DWORD Edi; //0x9C 82 | DWORD Esi; //0xA0 83 | DWORD Ebx; //0xA4 84 | DWORD Edx; //0xA8 85 | DWORD Ecx; //0xAC 86 | DWORD Eax; //0xB0 87 | DWORD Ebp; //0xB4 88 | DWORD Eip; //0xB8 89 | DWORD SegCs; 90 | DWORD EFlags; 91 | DWORD Esp; 92 | DWORD SegSs; 93 | byte ExtendedRegisters[MAXIMUM_EXTENSION]; 94 | 95 | }; 96 | 97 | 98 | #else 99 | #include 100 | #endif 101 | 102 | #define MAXIMUM_PARMS 15 103 | 104 | struct EMU_EXCEPTION_RECORD { 105 | DWORD exceptionCode; 106 | DWORD exceptionFlags; 107 | DWORD exceptionRecord; //struct _EXCEPTION_RECORD *ExceptionRecord 108 | DWORD exceptionAddress; 109 | DWORD numberParameters; 110 | DWORD exceptionInformation[MAXIMUM_PARMS]; 111 | }; 112 | 113 | struct EMU_EXCEPTION_POINTERS { 114 | EMU_EXCEPTION_RECORD *exceptionRecord; 115 | CONTEXT *contextRecord; 116 | }; 117 | 118 | struct ERR { 119 | DWORD nextErr; //struct _ERR *nextErr; 120 | DWORD handler; //pointer to handler 121 | }; 122 | -------------------------------------------------------------------------------- /emu/fpu.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | 21 | #include "../x86emu.h" 22 | 23 | DWORD FPU_push(Thread & thread, double value) { 24 | for (int i = 0; i < 6; i++) { 25 | thread.ST[i + 1] = thread.ST[i]; 26 | } 27 | thread.ST[0] = value; 28 | // cout << value << "\n"; 29 | // cout << thread.SelectedReg << "\n"; 30 | // cout << thread.ST[thread.SelectedReg] << "\n"; 31 | thread.SelectedReg++; 32 | return 0; 33 | } 34 | 35 | DWORD FPU_pop(Thread & thread) { 36 | if ((thread.SelectedReg == 1) || (thread.SelectedReg == 0)) { 37 | thread.SelectedReg = 0; 38 | return 0; 39 | } 40 | for (int i = 0; i < thread.SelectedReg - 1; i++) { 41 | thread.ST[i] = thread.ST[i + 1]; 42 | } 43 | thread.SelectedReg--; 44 | return 0; 45 | } 46 | 47 | int op_faddp(Thread & thread, DISASM_INSTRUCTION * s) { 48 | thread.ST[s->ndest - 1] += thread.ST[0]; 49 | FPU_pop(thread); 50 | thread.FpuUpdateFlags(s); 51 | return 0; 52 | } 53 | 54 | int op_fild(Thread & thread, DISASM_INSTRUCTION * s) { 55 | DWORD * ptr; 56 | 57 | EMU_READ_MEM(ptr, (DWORD) modrm_calc(thread, s)); 58 | DWORD n = *ptr; 59 | // system("pause"); 60 | if (s->flags & FPU_BITS32) { 61 | double value = 0.0; 62 | value = n; 63 | FPU_push(thread, n); 64 | } else { 65 | FPU_push(thread, (n & 0xFFFF)); 66 | } 67 | thread.FpuUpdateFlags(s); 68 | return 0; 69 | } 70 | 71 | int op_fistp(Thread & thread, DISASM_INSTRUCTION * s) { 72 | int ST_in_int = thread.ST[0]; 73 | 74 | if (s->flags & FPU_BITS32) { 75 | EMU_WRITE_MEM((DWORD) modrm_calc(thread, s), 4, (unsigned char *) &ST_in_int); 76 | } else { 77 | ST_in_int &= 0xFFFF; 78 | EMU_WRITE_MEM((DWORD) modrm_calc(thread, s), 2, (unsigned char *) &ST_in_int); 79 | } 80 | FPU_pop(thread); 81 | thread.FpuUpdateFlags(s); 82 | return 0; 83 | } 84 | 85 | int op_fimul(Thread & thread, DISASM_INSTRUCTION * s) { 86 | DWORD * ptr; 87 | 88 | EMU_READ_MEM(ptr, (DWORD) modrm_calc(thread, s)); 89 | DWORD n = *ptr; 90 | if (s->flags & FPU_BITS32) { 91 | thread.ST[0] *= n; 92 | } else { 93 | thread.ST[0] *= (n & 0xFFFF); 94 | } 95 | thread.FpuUpdateFlags(s); 96 | return 0; 97 | } 98 | 99 | int op_fnstenv(Thread &thread, DISASM_INSTRUCTION * s) { 100 | 101 | EMU_WRITE_MEM((DWORD) modrm_calc(thread, s), sizeof(thread.FpuEnv), (unsigned char *) &thread.FpuEnv); 102 | thread.FpuUpdateFlags(s); 103 | return 0; 104 | } -------------------------------------------------------------------------------- /hde28c/table32.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 32 C 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | */ 7 | 8 | #define C_NONE 0x00 9 | #define C_MODRM 0x01 10 | #define C_IMM8 0x02 11 | #define C_IMM16 0x04 12 | #define C_IMM_P66 0x10 13 | #define C_REL8 0x20 14 | #define C_REL32 0x40 15 | #define C_GROUP 0x80 16 | #define C_ERROR 0xff 17 | 18 | #define PRE_ANY 0x00 19 | #define PRE_NONE 0x01 20 | #define PRE_F2 0x02 21 | #define PRE_F3 0x04 22 | #define PRE_66 0x08 23 | #define PRE_67 0x10 24 | #define PRE_LOCK 0x20 25 | #define PRE_SEG 0x40 26 | #define PRE_ALL 0xff 27 | 28 | #define DELTA_OPCODES 0x4a 29 | #define DELTA_FPU_REG 0xf1 30 | #define DELTA_FPU_MODRM 0xf8 31 | #define DELTA_PREFIXES 0x130 32 | #define DELTA_OP_LOCK_OK 0x1a1 33 | #define DELTA_OP2_LOCK_OK 0x1b9 34 | #define DELTA_OP_ONLY_MEM 0x1cb 35 | #define DELTA_OP2_ONLY_MEM 0x1da 36 | 37 | unsigned char hde32_table[] = { 38 | 0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3, 39 | 0xa8,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xac,0xaa,0xb2,0xaa,0x9f,0x9f, 40 | 0x9f,0x9f,0xb5,0xa3,0xa3,0xa4,0xaa,0xaa,0xba,0xaa,0x96,0xaa,0xa8,0xaa,0xc3, 41 | 0xc3,0x96,0x96,0xb7,0xae,0xd6,0xbd,0xa3,0xc5,0xa3,0xa3,0x9f,0xc3,0x9c,0xaa, 42 | 0xaa,0xac,0xaa,0xbf,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0x90, 43 | 0x82,0x7d,0x97,0x59,0x59,0x59,0x59,0x59,0x7f,0x59,0x59,0x60,0x7d,0x7f,0x7f, 44 | 0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x9a,0x88,0x7d, 45 | 0x59,0x50,0x50,0x50,0x50,0x59,0x59,0x59,0x59,0x61,0x94,0x61,0x9e,0x59,0x59, 46 | 0x85,0x59,0x92,0xa3,0x60,0x60,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59, 47 | 0x59,0x59,0x9f,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xcc,0x01,0xbc,0x03,0xf0, 48 | 0x10,0x10,0x10,0x10,0x50,0x50,0x50,0x50,0x14,0x20,0x20,0x20,0x20,0x01,0x01, 49 | 0x01,0x01,0xc4,0x02,0x10,0x00,0x00,0x00,0x00,0x01,0x01,0xc0,0xc2,0x10,0x11, 50 | 0x02,0x03,0x11,0x03,0x03,0x04,0x00,0x00,0x14,0x00,0x02,0x00,0x00,0xc6,0xc8, 51 | 0x02,0x02,0x02,0x02,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xca, 52 | 0x01,0x01,0x01,0x00,0x06,0x00,0x04,0x00,0xc0,0xc2,0x01,0x01,0x03,0x01,0xff, 53 | 0xff,0x01,0x00,0x03,0xc4,0xc4,0xc6,0x03,0x01,0x01,0x01,0xff,0x03,0x03,0x03, 54 | 0xc8,0x40,0x00,0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00, 55 | 0x00,0x00,0x00,0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00, 56 | 0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 57 | 0x00,0xff,0xff,0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 58 | 0x7f,0x00,0x00,0xff,0x4a,0x4a,0x4a,0x4a,0x4b,0x52,0x4a,0x4a,0x4a,0x4a,0x4f, 59 | 0x4c,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x55,0x45,0x40,0x4a,0x4a,0x4a, 60 | 0x45,0x59,0x4d,0x46,0x4a,0x5d,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a, 61 | 0x4a,0x4a,0x4a,0x4a,0x4a,0x61,0x63,0x67,0x4e,0x4a,0x4a,0x6b,0x6d,0x4a,0x4a, 62 | 0x45,0x6d,0x4a,0x4a,0x44,0x45,0x4a,0x4a,0x00,0x00,0x00,0x02,0x0d,0x06,0x06, 63 | 0x06,0x06,0x0e,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x00,0x06,0x06,0x02,0x06, 64 | 0x00,0x0a,0x0a,0x07,0x07,0x06,0x02,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, 65 | 0x04,0x04,0x00,0x00,0x00,0x0e,0x05,0x06,0x06,0x06,0x01,0x06,0x00,0x00,0x08, 66 | 0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01, 67 | 0x86,0x00,0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba, 68 | 0xf8,0xbb,0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00, 69 | 0xc4,0xff,0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00, 70 | 0x13,0x09,0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07, 71 | 0xb2,0xff,0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf, 72 | 0xe7,0x08,0x00,0xf0,0x02,0x00 73 | }; 74 | -------------------------------------------------------------------------------- /emu/emu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | 21 | struct DISASM_INSTRUCTION; 22 | 23 | //all emulation functions 24 | 25 | 26 | int undefined_opcode(Thread&,DISASM_INSTRUCTION*); 27 | //math 28 | int op_add(Thread&,DISASM_INSTRUCTION*); 29 | int op_or (Thread&,DISASM_INSTRUCTION*); 30 | int op_adc(Thread&,DISASM_INSTRUCTION*); 31 | int op_sbb(Thread&,DISASM_INSTRUCTION*); 32 | int op_and(Thread&,DISASM_INSTRUCTION*); 33 | int op_sub(Thread&,DISASM_INSTRUCTION*); 34 | int op_xor(Thread&,DISASM_INSTRUCTION*); 35 | int op_cmp(Thread&,DISASM_INSTRUCTION*); 36 | int op_test(Thread&,DISASM_INSTRUCTION*); 37 | int op_mov(Thread&,DISASM_INSTRUCTION*); 38 | int op_lea(Thread&,DISASM_INSTRUCTION*); 39 | int op_movzx(Thread&,DISASM_INSTRUCTION*); 40 | int op_movsx(Thread&,DISASM_INSTRUCTION*); 41 | //---------------- 42 | int op_inc(Thread&,DISASM_INSTRUCTION*); 43 | int op_dec(Thread&,DISASM_INSTRUCTION*); 44 | int op_not(Thread&,DISASM_INSTRUCTION*); 45 | int op_neg(Thread&,DISASM_INSTRUCTION*); 46 | //---------------- 47 | int op_xchg(Thread&,DISASM_INSTRUCTION*); 48 | int op_bswap(Thread&,DISASM_INSTRUCTION*); 49 | int op_xadd(Thread&,DISASM_INSTRUCTION*); 50 | int op_mul(Thread&,DISASM_INSTRUCTION*); 51 | int op_imul1(Thread&,DISASM_INSTRUCTION*); 52 | int op_imul2(Thread&,DISASM_INSTRUCTION*); 53 | int op_imul3(Thread&,DISASM_INSTRUCTION*); 54 | int op_div(Thread&,DISASM_INSTRUCTION*); 55 | int op_idiv(Thread&,DISASM_INSTRUCTION*); 56 | int op_cdq(Thread&,DISASM_INSTRUCTION*); 57 | //---------------- 58 | //stack 59 | int op_push(Thread&,DISASM_INSTRUCTION*); 60 | int op_pop (Thread&,DISASM_INSTRUCTION*); 61 | int op_pushad(Thread&,DISASM_INSTRUCTION*); 62 | int op_popad (Thread&,DISASM_INSTRUCTION*); 63 | int op_pushfd(Thread&,DISASM_INSTRUCTION*); 64 | int op_popfd (Thread&,DISASM_INSTRUCTION*); 65 | int op_leave(Thread&,DISASM_INSTRUCTION*); 66 | int op_enter(Thread&,DISASM_INSTRUCTION*); 67 | //------------------ 68 | //jumps 69 | int op_jcc (Thread&,DISASM_INSTRUCTION*); 70 | int op_setcc (Thread&,DISASM_INSTRUCTION*); 71 | int op_call(Thread&,DISASM_INSTRUCTION*); 72 | int op_ret (Thread&,DISASM_INSTRUCTION*); 73 | //-------------------- 74 | //strings 75 | int op_lods(Thread&,DISASM_INSTRUCTION*); 76 | int op_stos(Thread&,DISASM_INSTRUCTION*); 77 | int op_movs(Thread&,DISASM_INSTRUCTION*); 78 | int op_cmps(Thread&,DISASM_INSTRUCTION*); 79 | int op_scas(Thread&,DISASM_INSTRUCTION*); 80 | //-------------------- 81 | //binary 82 | int op_shl(Thread&,DISASM_INSTRUCTION*); 83 | int op_shr(Thread&,DISASM_INSTRUCTION*); 84 | int op_rol(Thread&,DISASM_INSTRUCTION*); 85 | int op_ror(Thread&,DISASM_INSTRUCTION*); 86 | int op_sar(Thread&,DISASM_INSTRUCTION*); 87 | int op_rcl(Thread&,DISASM_INSTRUCTION*); 88 | int op_rcr(Thread&,DISASM_INSTRUCTION*); 89 | //--------------------- 90 | //flags 91 | int op_stc(Thread&,DISASM_INSTRUCTION*); 92 | int op_clc(Thread&,DISASM_INSTRUCTION*); 93 | //--------------------- 94 | //FPU 95 | int op_faddp(Thread& thread,DISASM_INSTRUCTION* s); 96 | int op_fild(Thread& thread,DISASM_INSTRUCTION* s); 97 | int op_fistp(Thread& thread,DISASM_INSTRUCTION* s); 98 | int op_fimul(Thread& thread,DISASM_INSTRUCTION* s); 99 | int op_fnstenv(Thread &thread, DISASM_INSTRUCTION * s); -------------------------------------------------------------------------------- /dbg/dbg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | #include "../x86emu.h" 21 | 22 | string Debugger::GetLastError() { 23 | return lasterror; 24 | } 25 | 26 | void Debugger::RemoveBp(int index) { 27 | if (index < nbp) { 28 | bp[index].state = BP_REMOVE; 29 | free((DWORD *) bp[index].ptr); 30 | } 31 | } 32 | 33 | void Debugger::PauseBp(int index) { 34 | if (index < nbp) { 35 | bp[index].state = BP_PAUSE; 36 | } 37 | } 38 | 39 | void Debugger::ActivateBp(int index) { 40 | if (index < nbp) { 41 | if (bp[index].state != BP_REMOVE) { 42 | bp[index].state = BP_RUN; 43 | } 44 | } 45 | } 46 | 47 | Debugger::Debugger() {} 48 | 49 | bool Debugger::TestBp(Thread & thread, DISASM_INSTRUCTION * ins) { 50 | return false; 51 | } 52 | 53 | int Debugger::AddBp(string s) { 54 | return 0; 55 | } 56 | 57 | int Debugger::define_func(string name, int params, DWORD func, int flags) { 58 | funcs[func_entries].name = name.append("("); 59 | funcs[func_entries].params = params; 60 | funcs[func_entries].dbg_func = func; 61 | funcs[func_entries].flags = flags; 62 | func_entries++; 63 | return (func_entries-1); 64 | } 65 | 66 | DWORD readfunc(Thread * thread, DISASM_INSTRUCTION * ins, DWORD ptr) { 67 | try { 68 | DWORD * ptr2 = (DWORD *) thread->mem->read_virtual_mem((DWORD) ptr); 69 | return *ptr2; 70 | } catch (...) { 71 | return 0; 72 | } 73 | } 74 | 75 | bool isapi(Thread * thread, DISASM_INSTRUCTION * ins) { 76 | if (ins->flags & API_CALL) { 77 | return true; 78 | } 79 | return false; 80 | } 81 | 82 | bool isapiequal(Thread * thread, DISASM_INSTRUCTION * ins, char * s) { 83 | if (ins->flags & API_CALL) { 84 | char * s2 = (char *) to_lower_case(thread->process->getsystem()->GetTiggeredAPI(*thread)).c_str(); 85 | if (!strcmp(s, s2)) { 86 | return true; 87 | } 88 | } 89 | return false; 90 | } 91 | 92 | bool lastaccessed(Thread * thread, DWORD ins, int index) { 93 | // return thread->mem->get_memory_flags(ptr); 94 | return thread->mem->get_last_accessed(index); 95 | } 96 | 97 | DWORD lastmodified(Thread * thread, DWORD ins, int index) { 98 | return thread->mem->get_last_modified(index); 99 | } 100 | 101 | DWORD dispfunc(Thread * thread, DISASM_INSTRUCTION * ins) { 102 | for (int i = 0; i < ins->modrm.length; i++) { 103 | if (ins->modrm.flags[i] & RM_DISP) { 104 | return ins->modrm.items[i]; 105 | } 106 | } 107 | return 0; 108 | } 109 | 110 | DWORD immfunc(Thread * thread, DISASM_INSTRUCTION * ins) { 111 | if (ins->flags & DEST_IMM) { 112 | return ins->ndest; 113 | } 114 | if (ins->flags & SRC_IMM) { 115 | return ins->nsrc; 116 | } 117 | return 0; 118 | } 119 | 120 | int isdirty(Thread * thread, DWORD ins, int ptr) { 121 | return thread->mem->get_memory_flags(ptr); 122 | } 123 | 124 | int Debugger::init_funcs() { 125 | define_func("isdirty", 1, (DWORD) & isdirty, 0); 126 | define_func("lastmodified", 1, (DWORD) & lastmodified, 0); 127 | define_func("lastwritten", 1, (DWORD) & lastmodified, 0); 128 | define_func("lastaccessed", 1, (DWORD) & lastaccessed, 0); 129 | define_func("isapi", 0, (DWORD) & isapi, 0); 130 | define_func("rm", 0, (DWORD) & modrm_calc, 0); 131 | define_func("disp", 0, (DWORD) & dispfunc, 0); 132 | define_func("imm", 0, (DWORD) & immfunc, 0); 133 | define_func("read", 1, (DWORD) & readfunc, 0); 134 | define_func("isapiequal", 1, (DWORD) & isapiequal, 0); 135 | return 0; 136 | } 137 | -------------------------------------------------------------------------------- /X86 Emulator.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 6 | h;hpp;hxx;hm;inl;inc;xsd 7 | 8 | 9 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 10 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx 11 | 12 | 13 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 14 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | 56 | 57 | Source Files 58 | 59 | 60 | Source Files 61 | 62 | 63 | Source Files 64 | 65 | 66 | Source Files 67 | 68 | 69 | Source Files 70 | 71 | 72 | Source Files 73 | 74 | 75 | Source Files 76 | 77 | 78 | Source Files 79 | 80 | 81 | Source Files 82 | 83 | 84 | Source Files 85 | 86 | 87 | Source Files 88 | 89 | 90 | Source Files 91 | 92 | 93 | Source Files 94 | 95 | 96 | Source Files 97 | 98 | 99 | Source Files 100 | 101 | 102 | Source Files 103 | 104 | 105 | Source Files 106 | 107 | 108 | Source Files 109 | 110 | 111 | Source Files 112 | 113 | 114 | Source Files 115 | 116 | 117 | Source Files 118 | 119 | 120 | Source Files 121 | 122 | 123 | Source Files 124 | 125 | 126 | Source Files 127 | 128 | 129 | Source Files 130 | 131 | 132 | -------------------------------------------------------------------------------- /examples/EmulatorTest/EmulatorTest.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 27 | 30 | 33 | 36 | 39 | 42 | 56 | 59 | 62 | 65 | 73 | 76 | 79 | 82 | 85 | 88 | 91 | 94 | 95 | 103 | 106 | 109 | 112 | 115 | 118 | 129 | 132 | 135 | 138 | 147 | 150 | 153 | 156 | 159 | 162 | 165 | 168 | 169 | 170 | 171 | 172 | 173 | 178 | 181 | 182 | 183 | 188 | 191 | 192 | 193 | 198 | 199 | 200 | 201 | 202 | 203 | -------------------------------------------------------------------------------- /seh.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | #include "x86emu.h" 21 | DWORD processToContext(Thread* thread) { 22 | CONTEXT* ctx=(CONTEXT*)malloc(sizeof(CONTEXT)); 23 | byte* ptr = (byte*) ctx; 24 | DWORD addr, i; 25 | DWORD ctx_size = (sizeof(CONTEXT) + 3) & ~3; //round up to next DWORD 26 | memset(ctx, 0, sizeof(ctx)); ; 27 | 28 | ctx->Eax = thread->Exx[0]; 29 | ctx->Ecx = thread->Exx[1]; 30 | ctx->Edx = thread->Exx[2]; 31 | ctx->Ebx = thread->Exx[3]; 32 | ctx->Esp = thread->Exx[4]; 33 | ctx->Ebp = thread->Exx[5]; 34 | ctx->Esi = thread->Exx[6]; 35 | ctx->Edi = thread->Exx[7]; 36 | ctx->Eip = thread->Eip; //use address at which exception occurred 37 | ctx->EFlags = thread->EFlags; 38 | ctx->SegFs = thread->GetFS(); 39 | addr = thread->Exx[4] -= ctx_size; 40 | for (i = 0; i < sizeof(CONTEXT); i++) { 41 | API_WRITE_MEM(addr++,1,(unsigned char*)ptr++); 42 | } 43 | free(ctx); 44 | return thread->Exx[4]; 45 | }; 46 | 47 | //Copy from CONTEXT structure into CPU state for Windows Exception Handling 48 | //Note that the global ctx struct is the only place that Debug and Floating 49 | //point registers are currently defined 50 | int contextToCpu(Thread* thread) { 51 | CONTEXT* ctx=(CONTEXT*)malloc(sizeof(CONTEXT)); 52 | byte *ptr = (byte*) ctx; 53 | DWORD addr, i; 54 | DWORD ctx_size = (sizeof(CONTEXT) + 3) & ~3; //round up to next DWORD 55 | addr = thread->Exx[4]; 56 | char* s; 57 | DWORD* readptr = NULL; 58 | API_READ_MEM(readptr,addr); 59 | s=(char*)readptr; 60 | for (i = 0; i < sizeof(CONTEXT); i++) { 61 | *ptr++ = *s++; 62 | } 63 | thread->Exx[4] += ctx_size; 64 | thread->Exx[0] = ctx->Eax; 65 | thread->Exx[1] = ctx->Ecx; 66 | thread->Exx[2] = ctx->Edx; 67 | thread->Exx[3] = ctx->Ebx; 68 | thread->Exx[4] = ctx->Esp; 69 | thread->Exx[5] = ctx->Ebp; 70 | thread->Exx[6] = ctx->Esi; 71 | thread->Exx[7] = ctx->Edi; 72 | thread->Eip = ctx->Eip; //use address at which exception occurred 73 | thread->EFlags = ctx->EFlags; 74 | free(ctx); 75 | }; 76 | int popExceptionRecord(Thread* thread,EXCEPTION_RECORD* rec) { 77 | byte *ptr = (byte*) rec; 78 | DWORD addr, i; 79 | DWORD rec_size = (sizeof(EMU_EXCEPTION_RECORD) + 3) & ~3; //round up to next DWORD 80 | addr = thread->Exx[4]; 81 | char* s; 82 | DWORD* readptr; 83 | API_READ_MEM(readptr,addr); 84 | s=(char*)readptr; 85 | for (i = 0; i < sizeof(EMU_EXCEPTION_RECORD); i++) { 86 | *ptr++ = (byte) *s++; 87 | } 88 | thread->Exx[4] += rec_size; 89 | }; 90 | 91 | DWORD pushExceptionRecord(Thread* thread,EMU_EXCEPTION_RECORD *rec) { 92 | byte *ptr = (byte*) rec; 93 | DWORD addr, i; 94 | DWORD rec_size = (sizeof(EMU_EXCEPTION_RECORD) + 3) & ~3; //round up to next DWORD 95 | addr = thread->Exx[4] -= rec_size; 96 | for (i = 0; i < sizeof(EMU_EXCEPTION_RECORD); i++) { 97 | API_WRITE_MEM( addr++,1,(unsigned char*)ptr++); 98 | } 99 | return thread->Exx[4]; 100 | }; 101 | 102 | int Thread::doException(DWORD record) { 103 | EMU_EXCEPTION_RECORD* rec=(EMU_EXCEPTION_RECORD*)record; 104 | DWORD* ptr; 105 | SEH_READ_MEM(ptr,this->GetFS()); 106 | DWORD err_ptr = *ptr; 107 | SEH_READ_MEM(ptr,err_ptr+4); 108 | DWORD handler = *ptr; //err->handler 109 | DWORD ctx_ptr = processToContext(this); 110 | DWORD rec_ptr = pushExceptionRecord(this,rec); 111 | stack->push(ctx_ptr); 112 | stack->push(err_ptr); //err_ptr == fsBase?? 113 | stack->push(rec_ptr); 114 | stack->push(SEH_MAGIC); //handler return address 115 | //need to execute exception handler here setup flag to trap ret 116 | //set eip to start of exception handler and resume fetching 117 | this->Eip = handler; 118 | log->addlog(Eip); 119 | } 120 | 121 | void Thread::sehReturn() { 122 | EXCEPTION_RECORD rec; 123 | //need to check eax here to see if exception was handled 124 | //or if it needs to be kicked up to next SEH handler 125 | 126 | this->Exx[4] += 3 * 4; //clear off exception pointers 127 | 128 | popExceptionRecord(this,&rec); 129 | 130 | contextToCpu(this); 131 | log->addlog(Eip); 132 | //eip is now restored to pre exception location 133 | 134 | //need to fake an iret here 135 | //doInterruptReturn(); //this clobbers EIP, CS, EFLAGS 136 | //so restore them here from ctx values 137 | } 138 | void Thread::generateException(DWORD code) { 139 | if (seh_enable) { 140 | EMU_EXCEPTION_RECORD rec; 141 | rec.exceptionCode = code; 142 | rec.exceptionFlags = CONTINUABLE; //nothing sophisticated here 143 | rec.exceptionRecord = 0; //NULL 144 | rec.exceptionAddress = Eip; 145 | rec.numberParameters = 0; 146 | doException((DWORD)&rec); 147 | }; 148 | }; 149 | -------------------------------------------------------------------------------- /examples/EmulatorTest/EmulatorTest.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {C1F83850-A9E2-49A3-8C88-8B527BAFC40E} 15 | EmulatorTest 16 | Win32Proj 17 | 18 | 19 | 20 | Application 21 | Unicode 22 | true 23 | v110 24 | 25 | 26 | Application 27 | false 28 | NotSet 29 | v110 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | <_ProjectFileVersion>10.0.30319.1 43 | $(SolutionDir)$(Configuration)\ 44 | $(Configuration)\ 45 | true 46 | $(SolutionDir)$(Configuration)\ 47 | $(Configuration)\ 48 | false 49 | 50 | 51 | 52 | Disabled 53 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 54 | true 55 | Default 56 | MultiThreadedDebugDLL 57 | false 58 | false 59 | false 60 | 61 | 62 | TurnOffAllWarnings 63 | 64 | 65 | 66 | 67 | true 68 | Console 69 | MachineX86 70 | 71 | 72 | 73 | 74 | MaxSpeed 75 | true 76 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 77 | MultiThreadedDLL 78 | true 79 | 80 | 81 | TurnOffAllWarnings 82 | ProgramDatabase 83 | 84 | 85 | true 86 | Console 87 | true 88 | true 89 | MachineX86 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | {480d2e91-be84-4d0d-a4c4-78f0ca8abfe0} 101 | false 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /apis/apis_emu.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | #include "../x86emu.h" 21 | 22 | int GetProcAddress_emu(Thread * thread, DWORD * Args) { 23 | char * str = 0; 24 | Process * c = thread->GetProcess(); 25 | DWORD * readptr; 26 | 27 | API_READ_MEM(readptr, Args[1]); 28 | str = (char *) readptr; 29 | if (str[0] == 0) { 30 | return 0; // if the string begins with zero 31 | } 32 | // invalid pointer return 0 33 | // if valid don't return zero but return any address 34 | if (Args[0] == 0) { 35 | return 0xBBBB0000 + c->imports[c->nimports - 1]->napis << 8 + c->nimports; 36 | } 37 | API_READ_MEM(readptr, Args[0]); 38 | DWORD dllhandle = (DWORD) readptr; 39 | DWORD ptr = thread->process->getsystem()->GetAPI(str, dllhandle); 40 | ptr = thread->mem->get_virtual_pointer(ptr); 41 | if (c->imports[c->nimports - 1]->napis == (MAX_NUM_APIS_PER_DLL - 1)) { 42 | return ptr; 43 | } 44 | c->imports[c->nimports - 1]->apis[c->imports[c->nimports - 1]->napis] = Args[1]; 45 | c->imports[c->nimports - 1]->napis++; 46 | if (ptr == 0) { 47 | // A magic number to search again for it to reconstruct the import table 48 | // cout << (int*)(0xBBBB0000+((c->imports[c->nimports-1]->napis-1) << 8) +c->nimports-1)<<"\n"; 49 | return 0xBBBB0000 + ((c->imports[c->nimports - 1]->napis - 1) << 8) + c->nimports - 1; 50 | } 51 | free(Args); 52 | return ptr; 53 | } 54 | 55 | int GetModuleHandleA_emu(Thread * thread, DWORD * Args) { 56 | if (Args[0] == 0) { 57 | return thread->GetProcess()->GetImagebase(); 58 | } 59 | DWORD * readptr; 60 | API_READ_MEM(readptr, Args[0]); 61 | char * str = (char *) readptr; 62 | DWORD ptr = thread->process->getsystem()->GetDllBase(str); 63 | ptr = thread->mem->get_virtual_pointer(ptr); 64 | Process * c = thread->process; 65 | c->imports[c->nimports] = (Imports *) malloc(sizeof(Imports)); 66 | memset(c->imports[c->nimports], 0, sizeof(Imports)); 67 | c->imports[c->nimports]->name = Args[0]; 68 | c->imports[c->nimports]->addr = ptr; 69 | c->imports[c->nimports]->defined = true; 70 | if (ptr == 0) { 71 | ptr = thread->process->getsystem()->DLLs[0].vAddr; 72 | c->imports[c->nimports]->addr = 0xBBBBBB00 + c->nimports; 73 | c->imports[c->nimports]->defined = false; 74 | } 75 | c->nimports++; 76 | return ptr; 77 | } 78 | 79 | int LoadLibraryA_emu(Thread * thread, DWORD * Args) { 80 | DWORD * readptr; 81 | 82 | API_READ_MEM(readptr, Args[0]); 83 | char * str = (char *) readptr; 84 | DWORD ptr = thread->process->getsystem()->GetDllBase(str); 85 | ptr = thread->mem->get_virtual_pointer(ptr); 86 | Process * c = thread->process; 87 | c->imports[c->nimports] = (Imports *) malloc(sizeof(Imports)); 88 | memset(c->imports[c->nimports], 0, sizeof(Imports)); 89 | c->imports[c->nimports]->name = Args[0]; 90 | c->imports[c->nimports]->addr = ptr; 91 | c->imports[c->nimports]->defined = true; 92 | if (ptr == 0) { 93 | ptr = thread->process->getsystem()->DLLs[0].vAddr; 94 | c->imports[c->nimports]->addr = 0xBBBBBB00 + c->nimports; 95 | c->imports[c->nimports]->defined = false; 96 | } 97 | c->nimports++; 98 | return ptr; 99 | } 100 | 101 | int VirtualAlloc_emu(Thread * thread, DWORD * Args) { 102 | 103 | if ((Args[1] & 0x0FFF) != 0) 104 | { 105 | Args[1] = (Args[1] & 0xFFFFF000) + 0x1000; // round it to 0x1000 106 | } 107 | #ifdef WIN32 108 | DWORD ptr = (DWORD) VirtualAlloc(NULL, Args[1], MEM_COMMIT, PAGE_READWRITE); // the virtual place 109 | #else 110 | DWORD ptr = (DWORD) malloc(Args[1]); // the virtual place 111 | #endif 112 | memset((void *) ptr, 0, Args[1]); 113 | DWORD addr = Args[0]; // the address 114 | 115 | if ((addr == 0) || (thread->mem->read_virtual_mem(addr) == 0)) 116 | { 117 | addr = thread->mem->create_memory_address(VMEM_TYPE_ALLOC); 118 | } 119 | thread->mem->add_pointer(ptr, addr, Args[1]); 120 | return addr; 121 | } 122 | 123 | int VirtualFree_emu(Thread * thread, DWORD * Args) { 124 | thread->mem->delete_pointer(Args[0]); 125 | return 1; 126 | } 127 | 128 | int VirtualProtect_emu(Thread * thread, DWORD * Args) { 129 | DWORD vptr = Args[0]; 130 | DWORD * readptr; 131 | 132 | API_READ_MEM(readptr, Args[0]); 133 | DWORD rptr = (DWORD) readptr; 134 | if ((Args[1] & 0x0FFF) != 0) { 135 | Args[1] = (Args[1] & 0xFFFFF000) + 0x1000; // round it to 0x1000 136 | } 137 | DWORD size = Args[1]; 138 | //cout << "Virtual Protect:\n" << "Read Ptr: " << (int*)rptr << "\nVirtual Ptr: " << (int*)vptr << "\nSize: " << (int*)size << "\n"; 139 | thread->mem->add_pointer(rptr, vptr, size, MEM_VIRTUALPROTECT); 140 | return 1; 141 | } 142 | 143 | int SetUnhandledExceptionFilter_emu(Thread * thread, DWORD * Args) { 144 | thread->stack->push(Args[0]); 145 | thread->stack->push(*thread->mem->read_virtual_mem(thread->GetFS())); 146 | *thread->mem->read_virtual_mem(thread->GetFS()) = thread->Exx[4]; 147 | return 1; 148 | } 149 | -------------------------------------------------------------------------------- /X86 Emulator.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {480D2E91-BE84-4D0D-A4C4-78F0CA8ABFE0} 15 | Win32Proj 16 | 17 | 18 | 19 | DynamicLibrary 20 | v110 21 | 22 | 23 | DynamicLibrary 24 | v110 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | <_ProjectFileVersion>10.0.30319.1 38 | Debug\ 39 | Debug\ 40 | true 41 | Release\ 42 | Release\ 43 | true 44 | 45 | 46 | 47 | Disabled 48 | WIN32;_DEBUG;_WINDOWS;_USRDLL;X86EMULATOR_EXPORTS;BUILDING_DLL;%(PreprocessorDefinitions) 49 | true 50 | EnableFastChecks 51 | true 52 | MultiThreadedDebugDLL 53 | false 54 | /J 55 | false 56 | 57 | 58 | TurnOffAllWarnings 59 | EditAndContinue 60 | 61 | 62 | false 63 | Windows 64 | false 65 | MachineX86 66 | false 67 | 68 | 69 | 70 | 71 | /D "BUILDING_DLL" %(AdditionalOptions) 72 | WIN32;NDEBUG;_WINDOWS;_USRDLL;X86EMULATOR_EXPORTS;%(PreprocessorDefinitions) 73 | MultiThreadedDLL 74 | 75 | 76 | TurnOffAllWarnings 77 | ProgramDatabase 78 | 79 | 80 | true 81 | Windows 82 | true 83 | true 84 | true 85 | MachineX86 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /os/os.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | #include "../pe.h" 21 | #include 22 | 23 | #include "os.h" 24 | 25 | #ifdef WIN32 26 | #include 27 | #include 28 | 29 | using namespace std; 30 | 31 | // unsigned long LoadProcess(string filename){ 32 | // unsigned long n=(unsigned long)LoadLibraryA (filename.c_str()); 33 | // return n; 34 | // }; 35 | unsigned long GetTime() { 36 | return (unsigned long) GetTickCount(); 37 | } 38 | 39 | FileMapping * OpenFile(const char * Filename) { 40 | HANDLE hFile; 41 | HANDLE hMapping; 42 | unsigned long BaseAddress; 43 | DWORD FileLength; 44 | 45 | hFile = CreateFileA(Filename, 46 | GENERIC_READ, 47 | FILE_SHARE_READ | FILE_SHARE_WRITE, 48 | NULL, 49 | OPEN_EXISTING, 50 | FILE_ATTRIBUTE_NORMAL, 51 | 0); 52 | if (hFile == INVALID_HANDLE_VALUE) { 53 | return 0; 54 | } 55 | hMapping = CreateFileMappingW(hFile, 56 | NULL, 57 | PAGE_READONLY, 58 | 0, 59 | 0, 60 | NULL); 61 | if (hMapping == 0) { 62 | CloseHandle(hFile); 63 | return 0; 64 | } 65 | BaseAddress = (unsigned long) MapViewOfFile(hMapping, 66 | FILE_MAP_READ, 67 | 0, 68 | 0, 69 | 0); 70 | if (hMapping == 0) { 71 | UnmapViewOfFile(hMapping); 72 | CloseHandle(hFile); 73 | return 0; 74 | } 75 | FileMapping * hMap = (FileMapping *) malloc(sizeof(FileMapping)); 76 | hMap->hFile = (unsigned long) hFile; 77 | hMap->hMapping = (unsigned long) hMapping; 78 | hMap->BaseAddress = (unsigned long) BaseAddress; 79 | hMap->FileLength = (unsigned long) GetFileSize(hFile, 80 | NULL); 81 | return hMap; 82 | } 83 | 84 | // ------------------------------------------------------------------------------ 85 | FileMapping * CreateNewFile(const char * Filename, unsigned long size) { 86 | HANDLE hFile; 87 | HANDLE hMapping; 88 | unsigned long BaseAddress; 89 | DWORD FileLength; 90 | 91 | hFile = CreateFileA(Filename, 92 | GENERIC_READ | GENERIC_WRITE, 93 | FILE_SHARE_READ | FILE_SHARE_WRITE, 94 | NULL, 95 | CREATE_ALWAYS, 96 | FILE_ATTRIBUTE_NORMAL, 97 | 0); 98 | if (hFile == INVALID_HANDLE_VALUE) { 99 | return 0; 100 | } 101 | hMapping = CreateFileMappingW(hFile, 102 | NULL, 103 | PAGE_READWRITE, 104 | 0, 105 | size, 106 | NULL); 107 | if (hMapping == 0) { 108 | CloseHandle(hFile); 109 | return 0; 110 | } 111 | BaseAddress = (unsigned long) MapViewOfFile(hMapping, 112 | FILE_MAP_ALL_ACCESS, 113 | 0, 114 | 0, 115 | 0); 116 | if (hMapping == 0) { 117 | UnmapViewOfFile(hMapping); 118 | CloseHandle(hFile); 119 | return 0; 120 | } 121 | FileMapping * hMap = (FileMapping *) malloc(sizeof(FileMapping)); 122 | hMap->hFile = (unsigned long) hFile; 123 | hMap->hMapping = (unsigned long) hMapping; 124 | hMap->BaseAddress = (unsigned long) BaseAddress; 125 | hMap->FileLength = (unsigned long) size; 126 | return hMap; 127 | } 128 | 129 | // ------------------------------------------------------------------------------ 130 | unsigned long CloseFile(FileMapping * hMap) { 131 | UnmapViewOfFile((void *) hMap->BaseAddress); 132 | CloseHandle((void *) hMap->hMapping); 133 | CloseHandle((void *) hMap->hFile); 134 | return 0; 135 | } 136 | 137 | #else 138 | #include 139 | #include 140 | #include 141 | #include 142 | #include 143 | #include 144 | #include 145 | #include 146 | #include 147 | 148 | unsigned long GetTime() { 149 | return 0; 150 | } 151 | 152 | FileMapping * OpenFile(const char * Filename) { 153 | char c; 154 | int file_in; 155 | FileMapping * s = (FileMapping *) malloc(sizeof(FileMapping)); 156 | 157 | memset(s, 0, sizeof(FileMapping)); 158 | file_in = open(Filename, O_RDONLY); 159 | // Getting the size 160 | int count = 0; 161 | 162 | while (1) { 163 | int n = read(file_in, &c, 1); 164 | if (n == 0) { 165 | break; 166 | } 167 | count++; 168 | } 169 | s->FileLength = count; 170 | char * buffer = (char *) malloc(count); 171 | s->BaseAddress = (unsigned long) buffer; 172 | s->hMapping = 0; // File was opened for read 173 | close(file_in); 174 | file_in = open(Filename, O_RDONLY); 175 | read(file_in, buffer, count); 176 | close(file_in); 177 | return s; 178 | } 179 | 180 | FileMapping * CreateNewFile(const char * Filename, unsigned long size) { 181 | int file_out; 182 | FileMapping * s = (FileMapping *) malloc(sizeof(FileMapping)); 183 | char del[90] = "rm -rf "; 184 | int delsize = strlen(del); 185 | 186 | strcpy(&del[delsize], (char *) Filename); 187 | system(del); 188 | file_out = open(Filename, O_RDWR | O_CREAT); 189 | s->FileLength = size; 190 | s->BaseAddress = (unsigned long) 0; 191 | s->hMapping = 1; // File was opened for write 192 | s->hFile = (unsigned long) file_out; 193 | return s; 194 | } 195 | 196 | unsigned long CloseFile(FileMapping * hMap) { 197 | if (hMap->hMapping == 1) { // file opened for write 198 | int file_out = (int) hMap->hFile; 199 | int n = write(file_out, (char *) hMap->BaseAddress, hMap->FileLength); 200 | // cout << (int*)n << " "<< (int*)hMap->FileLength << "\n"; 201 | close(file_out); 202 | } 203 | } 204 | 205 | #endif 206 | -------------------------------------------------------------------------------- /X86 Emulator.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 24 | 27 | 30 | 33 | 36 | 39 | 56 | 59 | 62 | 65 | 75 | 78 | 81 | 84 | 87 | 90 | 93 | 96 | 97 | 103 | 106 | 109 | 112 | 115 | 118 | 128 | 131 | 134 | 137 | 147 | 150 | 153 | 156 | 159 | 162 | 165 | 168 | 169 | 170 | 171 | 172 | 173 | 178 | 181 | 182 | 185 | 186 | 189 | 190 | 193 | 194 | 197 | 198 | 201 | 202 | 205 | 206 | 209 | 210 | 213 | 214 | 217 | 218 | 221 | 222 | 225 | 226 | 227 | 232 | 233 | 238 | 241 | 242 | 245 | 246 | 249 | 250 | 253 | 254 | 257 | 258 | 261 | 262 | 265 | 266 | 269 | 270 | 273 | 274 | 277 | 278 | 281 | 282 | 285 | 286 | 289 | 290 | 293 | 294 | 297 | 298 | 301 | 302 | 305 | 306 | 309 | 310 | 313 | 314 | 317 | 318 | 321 | 322 | 325 | 326 | 329 | 330 | 333 | 334 | 337 | 338 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | -------------------------------------------------------------------------------- /examples/EmulatorTest/main.cpp: -------------------------------------------------------------------------------- 1 | #include "../../x86emu.h" 2 | 3 | #include 4 | #include 5 | //#include 6 | 7 | using namespace std; 8 | 9 | unsigned long GetTime(){ 10 | return GetTickCount(); 11 | }; 12 | static unsigned char test[64] = { 13 | 0x8B, 0xCB, 0x8B, 0xC3, 0xC1, 0xF9, 0x05, 0x83, 14 | 0xE0, 0x1F, 0x8B, 0x0C, 0x8D, 0x40, 0xC2, 0x43, 15 | 0x00, 0x8D, 0x04, 0xC0, 0x8D, 0x04, 0x81, 0xEB, 16 | 0x05, 0xB8, 0x30, 0x6B, 0x42, 0x00, 0xF6, 0x40, 17 | 0x04, 0x20, 0x74, 0x0D, 0x6A, 0x02, 0x6A, 0x00, 18 | 0x53, 0xE8, 0x48, 0x52, 0x00, 0x00, 0x83, 0xC4, 19 | 0x0C, 0x8B, 0x46, 0x08, 0x8A, 0x4D, 0x08, 0x88, 20 | 0x08, 0xEB, 0x14, 0x6A, 0x01, 0x8D, 0x45, 0x08}; 21 | 22 | 23 | int main(int argc, char *argv[]) 24 | { 25 | EnviromentVariables* vars; 26 | System* sys; 27 | Process* process; 28 | DISASM_INSTRUCTION ins; 29 | vars = (EnviromentVariables*)malloc(sizeof(EnviromentVariables)); 30 | memset( vars,0,sizeof(EnviromentVariables)); 31 | 32 | vars->dllspath="C:\\Windows\\System32\\"; 33 | vars->kernel32=(DWORD)GetModuleHandleA("kernel32.dll"); 34 | vars->user32=(DWORD)LoadLibraryA("user32.dll"); 35 | vars->MaxIterations=100000000; //100 Million Instructions per encryption layer 36 | 37 | sys=new System(vars); 38 | string str; 39 | bytes * s ; 40 | for (int i = 0;i < 64; i+= s->length) 41 | { 42 | sys->disasm(&ins,(char*)&test[i],str); 43 | cout << str.c_str() << "\n"; 44 | s = sys->assembl(&ins); 45 | cout << hex << (int*)s->s[0] << " " << (int*)s->s[1] << " " << (int*)s->s[2] << " " << (int*)s->s[3] << " " << (int*)s->s[4] << " " << (int*)s->s[5] << "\n"; 46 | s = sys->assembl(str); 47 | cout << hex << (int*)s->s[0] << " " << (int*)s->s[1] << " " << (int*)s->s[2] << " " << (int*)s->s[3] << " " << (int*)s->s[4] << " " << (int*)s->s[5] << "\n"; 48 | } 49 | } 50 | /* 51 | Usage : 01.exe Xorer_sample.exe 52 | */ 53 | unsigned char XorerSignature[96] = { 54 | 0x64, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x50, 0x64, 55 | 0x89, 0x25, 0x00, 0x00, 0x00, 0x00, 0x83, 0xEC, 56 | 0x58, 0x53, 0x56, 0x57, 0x89, 0x65, 0xE8 57 | }; 58 | int main2(int argc, char *argv[]) 59 | { 60 | //The Main Variables 61 | ///* 62 | int YourNumber = 0x000001EB; 63 | for (short i=0x3030;i<0x7A7A;i++){ 64 | for (short l=0x3030;l<0x7A7A;l++){ 65 | unsigned char* n = (unsigned char*)&i; 66 | unsigned char* m = (unsigned char*)&l; 67 | if (((i * l)& 0xFFFF)==YourNumber){ 68 | //cout << (int*)i << " " << (int*)l<< "\n"; 69 | for(int s=0;s<2;s++){ 70 | if (!(((n[s] > 0x30 && n[s] < 0x39) || \ 71 | (n[s] > 0x41 && n[s] < 0x5A) || \ 72 | (n[s] > 0x61 && n[s] < 0x7A)) && \ 73 | ((m[s] > 0x30 && m[s] < 0x39) || \ 74 | (m[s] > 0x41 && m[s] < 0x5A) || \ 75 | (m[s] > 0x61 && m[s] < 0x7A)))) 76 | goto Not_Yet; 77 | } 78 | cout << (int*)i << " " << (int*)l << " " << (int*)((l*i) & 0xFFFF)<< "\n"; 79 | } 80 | 81 | Not_Yet: 82 | continue; 83 | } 84 | }; 85 | //return EXIT_SUCCESS; 86 | //*/ 87 | EnviromentVariables* vars; 88 | System* sys; 89 | Process* process; 90 | DWORD FileHandler; 91 | image_header* PEHeader; 92 | DWORD Imagesize; 93 | DWORD TimeElapsed; 94 | image_section_header* sections; 95 | char* PhysicalEip; 96 | int nSections; //Number of sections 97 | 98 | if(argc == 1) 99 | { 100 | cout << "Usage : 01.exe Xorer_sample.exe\n"; 101 | return EXIT_SUCCESS; 102 | } 103 | 104 | vars = (EnviromentVariables*)malloc(sizeof(EnviromentVariables)); 105 | memset( vars,0,sizeof(EnviromentVariables)); 106 | 107 | vars->dllspath="C:\\Windows\\System32\\"; 108 | vars->kernel32=(DWORD)GetModuleHandleA("kernel32.dll"); 109 | vars->user32=(DWORD)LoadLibraryA("user32.dll"); 110 | vars->MaxIterations=100000000; //100 Million Instructions per encryption layer 111 | 112 | sys=new System(vars); 113 | //---------------------------------------------------------------------------------------- 114 | // Creating The Process and Adding the Breakpoints 115 | 116 | try{ 117 | process=new Process(sys,string(argv[1])); 118 | }catch(int x){ 119 | cout << "Error : File name not found\n"; 120 | return EXIT_SUCCESS; 121 | }; 122 | 123 | try{ 124 | process->debugger->AddBp("__isdirty(eip)");//__isdirty(eip) 125 | //process->debugger->AddBp("__lastmodified(0) >= 0x10001000"); 126 | }catch(...){ 127 | cout << process->debugger->GetLastError().c_str() << "\n"; 128 | return EXIT_SUCCESS; 129 | } 130 | 131 | //---------------------------------------------------------------------------------------- 132 | //Emulating 133 | //PROCESS_DATA_ENTRY s; 134 | cout << "\nDecrypting The File ... \n\n"; 135 | TimeElapsed =GetTime(); //The Emulation Time 136 | int x=process->emulate();//"test.txt" 137 | cout << (int*)x << "\n"; 138 | ReconstructImportTable(process); 139 | PEDump(process->GetThread(0)->Eip,process,"test.exe"); //Dumping The File 140 | 141 | //---------------------------------------------------------------------------------------- 142 | //Scan The Infected File 143 | 144 | TimeElapsed=GetTime()-TimeElapsed; //The Emulation Time 145 | cout << "Scanning The File ...\n\n"; 146 | 147 | //Getting The PE Header Information 148 | 149 | FileHandler =(DWORD)process->SharedMem->read_virtual_mem(process->GetImagebase()); 150 | PEHeader = (image_header*)(((dos_header*)FileHandler)->e_lfanew + FileHandler); 151 | Imagesize = PEHeader->optional.size_of_image; 152 | 153 | //Scanning The Memory 154 | 155 | for (char* ptr = (char*)FileHandler; ptr <(char*)(FileHandler+Imagesize);ptr++){ 156 | for (int i = 0; i < 16; i++){ 157 | if((ptr[i]& 0xff) != (XorerSignature[i]& 0xff)) goto NextElement; // not equal to the signature ... continue searching 158 | }; 159 | //Now the signature is equal ... and the virus detected 160 | 161 | cout << "This File is Infected with Win32/Xorer\n\n"; 162 | cout << "The Operation ended successfully at "<<"Time (sec) = " << TimeElapsed <<" msecs\n\n"; 163 | delete process; 164 | delete sys; 165 | sys=new System(vars); 166 | cout << "YES\n"; 167 | return EXIT_SUCCESS; 168 | NextElement:; 169 | }; 170 | 171 | //it's not infected 172 | 173 | cout << "This File is Not Infected\n"; 174 | return EXIT_SUCCESS; 175 | 176 | } 177 | 178 | 179 | 180 | int main3(int argc, char *argv[]) 181 | { 182 | //First we will create the Environment Variables 183 | //the Environment Variables is just some parameters or setting will be passed to the System 184 | EnviromentVariables* vars= (EnviromentVariables*)malloc(sizeof(EnviromentVariables)); 185 | memset( vars,0,sizeof(EnviromentVariables)); 186 | //this variable should be adjusted to make the system perform well. this path is the path to the folder that contain 187 | //the important dlls which are ("kernel32.dll","ntdll.dll","user32.dll") 188 | vars->dllspath="C:\\Windows\\System32\\"; 189 | //here we will set the Imagebase of the kernel32.dll and user32.dll 190 | vars->kernel32=(DWORD)GetModuleHandleA("kernel32.dll"); 191 | vars->user32=(DWORD)LoadLibraryA("user32.dll"); 192 | //there's other variables but we can ignore the right now 193 | //now we will create the new system 194 | System* sys=new System(vars); 195 | //sys->define_dll("gdi32.dll",vars->dllspath,0x75DE0000); 196 | cout << "Running\n"; 197 | //now We Will create a new Process 198 | Process* c; 199 | try{ 200 | c=new Process(sys,"C:\\upx01.exe"); //process take two parameters system & the program filename 201 | }catch(int x){ 202 | cout << "Error : File name not found\n"; 203 | }; 204 | cout << "Running\n"; 205 | cout << (int*)c->GetThread(0)->Eip << "\n"; 206 | //Adding new breakpoint is an easy task 207 | try{ 208 | c->debugger->AddBp("__isdirty(eip)"); 209 | }catch(int x){ 210 | cout << x << "\n"; 211 | cout << c->debugger->GetLastError().c_str()<< "\n"; 212 | }; 213 | //there's two commands to emulate c->emulate() & emulatecommand(int) 214 | cout << "Running\n"; 215 | int x=c->emulate(string("test.txt"));// 216 | if (x!=EXP_BREAKPOINT){ //there are other exceptions like invalid pointer and so on return an error for them 217 | cout << "Error = " << x << "\n"; 218 | cout << (int*)c->GetThread(0)->Eip << "\n"; 219 | }else{ 220 | //Dump the PE file here 221 | cout << "The File Emulated Successfully\n"; 222 | ReconstructImportTable(c); 223 | PEDump(c->GetThread(0)->Eip,c,"test.exe"); 224 | } 225 | c->SharedMem->write_virtual_mem(0x4033b0,4,(unsigned char*)&c); 226 | system("PAUSE"); 227 | ExitProcess(0); 228 | return EXIT_SUCCESS; 229 | } -------------------------------------------------------------------------------- /thread.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | #include "x86emu.h" 21 | #ifdef WIN32 22 | #include "windows.h" 23 | #endif 24 | bool is_negative(DWORD num, DWORD ins_flags); 25 | 26 | char PF_Flags[256] = { 27 | 1, 0, 0, 1, 0, 1, 1, 0, 28 | 0, 1, 1, 0, 1, 0, 0, 1, 29 | 0, 1, 1, 0, 1, 0, 0, 1, 30 | 1, 0, 0, 1, 0, 1, 1, 0, 31 | 0, 1, 1, 0, 1, 0, 0, 1, 32 | 1, 0, 0, 1, 0, 1, 1, 0, 33 | 1, 0, 0, 1, 0, 1, 1, 0, 34 | 0, 1, 1, 0, 1, 0, 0, 1, 35 | 0, 1, 1, 0, 1, 0, 0, 1, 36 | 1, 0, 0, 1, 0, 1, 1, 0, 37 | 1, 0, 0, 1, 0, 1, 1, 0, 38 | 0, 1, 1, 0, 1, 0, 0, 1, 39 | 1, 0, 0, 1, 0, 1, 1, 0, 40 | 0, 1, 1, 0, 1, 0, 0, 1, 41 | 0, 1, 1, 0, 1, 0, 0, 1, 42 | 1, 0, 0, 1, 0, 1, 1, 0, 43 | 0, 1, 1, 0, 1, 0, 0, 1, 44 | 1, 0, 0, 1, 0, 1, 1, 0, 45 | 1, 0, 0, 1, 0, 1, 1, 0, 46 | 0, 1, 1, 0, 1, 0, 0, 1, 47 | 1, 0, 0, 1, 0, 1, 1, 0, 48 | 0, 1, 1, 0, 1, 0, 0, 1, 49 | 0, 1, 1, 0, 1, 0, 0, 1, 50 | 1, 0, 0, 1, 0, 1, 1, 0, 51 | 1, 0, 0, 1, 0, 1, 1, 0, 52 | 0, 1, 1, 0, 1, 0, 0, 1, 53 | 0, 1, 1, 0, 1, 0, 0, 1, 54 | 1, 0, 0, 1, 0, 1, 1, 0, 55 | 0, 1, 1, 0, 1, 0, 0, 1, 56 | 1, 0, 0, 1, 0, 1, 1, 0, 57 | 1, 0, 0, 1, 0, 1, 1, 0, 58 | 1, 0, 0, 1, 0, 1, 1, 0, 59 | }; 60 | Thread::Thread() { 61 | // this for the parser as we don't need anything from the thread just work in pointers 62 | } 63 | 64 | Process * Thread::GetProcess() { 65 | return process; 66 | } 67 | 68 | Thread::Thread(DWORD neip, Process & s) { 69 | // initialize the thread 70 | 71 | process = &s; 72 | // create the stack 73 | // it's created from tests only and I didn't use the Heap Commit & Reserve 74 | // I use Size = 0xA000 75 | seh_enable = true; 76 | #ifdef WIN32 77 | DWORD x = (DWORD) VirtualAlloc(NULL, 0xA000, MEM_COMMIT, PAGE_READWRITE); // the virtual place 78 | #else 79 | DWORD x = (DWORD) malloc(0xA000); // the virtual place 80 | #endif 81 | memset((void *) x, 0, 0xA000); 82 | stack = new Stack(*this); 83 | mem = process->SharedMem; 84 | DWORD StackAddr = mem->create_memory_address(VMEM_TYPE_STACK); 85 | mem->add_pointer(x, StackAddr, 0xA000); 86 | Exx[4] = StackAddr + 0x9F90; // esp 87 | Exx[5] = StackAddr + 0x9F94; // ebp 88 | 89 | // preparing the TIB,TEB 90 | CreateTEB(); 91 | 92 | still_tls = false; 93 | if (process->AppType != PROCESS_SHELLCODE) 94 | { 95 | DWORD image = (DWORD) s.SharedMem->read_virtual_mem(s.GetImagebase()); 96 | DWORD PEHeader_ptr = ((dos_header *) image)->e_lfanew + image; 97 | image_header * PEHeader = (image_header *) PEHeader_ptr; 98 | if (PEHeader->optional.data_directory[IMAGE_DIRECTORY_ENTRY_TLS].virtual_address != 0) { 99 | _IMAGE_TLS_DIRECTORY * tlsheader = (_IMAGE_TLS_DIRECTORY *) ((DWORD) PEHeader->optional.data_directory[IMAGE_DIRECTORY_ENTRY_TLS].virtual_address + image); 100 | if (tlsheader->AddressOfCallBacks != 0) { 101 | DWORD * callbacks = s.SharedMem->read_virtual_mem((DWORD) tlsheader->AddressOfCallBacks); 102 | if (callbacks[0] != 0) { 103 | stack->push(0); 104 | stack->push(1); 105 | stack->push(0); 106 | stack->push(TLS_MAGIC); 107 | this->Eip = callbacks[0]; 108 | log = new Log(this->Eip); 109 | still_tls = true; 110 | tls_callback_index++; 111 | } 112 | } 113 | } 114 | } 115 | entry_point = neip; 116 | if (still_tls == false) { 117 | this->Eip = neip; 118 | log = new Log(neip); 119 | if (process->IsDLL) { 120 | stack->push(0); 121 | stack->push(1); 122 | stack->push(process->GetImagebase()); 123 | } 124 | stack->push(mem->get_virtual_pointer(process->getsystem()->APITable[0].addr)); // pushes the pointer to ExitProcess (some viruses get the kernelbase from it 125 | } 126 | // preparing FPU 127 | SelectedReg = 0; 128 | for (int i = 0; i < 8; i++) 129 | { 130 | ST[i] = 0; 131 | } 132 | } 133 | 134 | void Thread::updateflags(DWORD dest, DWORD src, DWORD result, int flags, DWORD ins_flags) { 135 | bool CF = false; // reserve The CF 136 | 137 | if ((EFlags & EFLG_CF) && (flags != UPDATEFLAGS_ADD) && (flags != UPDATEFLAGS_SUB)) { 138 | CF = true; // save the CF before being deleted 139 | } 140 | this->EFlags = EFLG_SYS; 141 | // -------------------------------------------------- 142 | // ZF & SF & OF 143 | if (result == 0) { 144 | EFlags |= EFLG_ZF; // zero 145 | } 146 | if (is_negative(result, ins_flags)) { 147 | EFlags |= EFLG_SF; // negative 148 | } 149 | if ((flags == UPDATEFLAGS_ADD) && (is_negative(dest, ins_flags) == false) && (is_negative(result, ins_flags) == true)) { 150 | EFlags |= EFLG_OF; // From Positive to Negative 151 | } 152 | if ((flags == UPDATEFLAGS_SUB) && (is_negative(dest, ins_flags) == false) && (is_negative(src, ins_flags) == true) && (is_negative(result, ins_flags) == true)) { 153 | EFlags |= EFLG_OF; // from positive to negative 154 | } 155 | // -------------------------------------------------- 156 | // CF & AF 157 | if ((flags == UPDATEFLAGS_ADD) && (dest > result)) { 158 | EFlags |= EFLG_CF | EFLG_AF; // overflow of positive 159 | } 160 | if ((flags == UPDATEFLAGS_SUB) && (result > dest)) { 161 | EFlags |= EFLG_CF | EFLG_AF; // overflow of negative 162 | } 163 | // ------------------------------------------------- 164 | // PF 165 | char PFindex = result & 0xFF; 166 | if (PF_Flags[PFindex] == 1) { 167 | EFlags |= EFLG_PF; 168 | } 169 | 170 | if (CF) { 171 | EFlags |= EFLG_CF; // restore CF 172 | } 173 | } 174 | 175 | // This function determines if this number is positive or negative based on the operand size 176 | bool is_negative(DWORD num, DWORD ins_flags) { 177 | if (ins_flags & DEST_BITS8) { 178 | if (num & 0x80) { 179 | return true; 180 | } else { 181 | return false; 182 | } 183 | } else if (ins_flags & DEST_BITS16) { 184 | if (num & 0x8000) { 185 | return true; 186 | } else { 187 | return false; 188 | } 189 | } else { 190 | if (num & 0x80000000) { 191 | return true; 192 | } else { 193 | return false; 194 | } 195 | } 196 | return false; 197 | } 198 | 199 | void Thread::FpuUpdateFlags( DISASM_INSTRUCTION * s) 200 | { 201 | FpuEnv.LastInstructionPointer = Eip - s->hde.len; 202 | FpuEnv.LastOpcode = (s->hde.opcode - 0xD8) << 8 + s->hde.modrm; 203 | } 204 | void Thread::CreateTEB() { 205 | #ifdef WIN32 206 | tib = (TIB *) VirtualAlloc(NULL, sizeof(TEB) + sizeof(TIB), MEM_COMMIT, PAGE_READWRITE); // the virtual place 207 | #else 208 | tib = (TIB *) malloc(sizeof(TEB) + sizeof(TIB)); // the virtual place 209 | #endif 210 | memset(tib, 0, sizeof(TEB) + sizeof(TIB)); 211 | teb = (TEB *) ((DWORD) tib + (DWORD) sizeof(TIB)); 212 | tib->ExceptionList = (_PEXCEPTION_REGISTRATION_RECORD *) 0x0012FFC4; 213 | int n = 0xFFFFFFFF; // End of SEH Chain 214 | mem->write_virtual_mem((DWORD) tib->ExceptionList, (DWORD) 4, (unsigned char *) &n); 215 | mem->write_virtual_mem((DWORD) (tib->ExceptionList + 4), (DWORD) 4, (unsigned char *) &n); 216 | tib->TIBOffset = 0x7FFDF000; // pointer to SEH Chain 217 | teb->Peb = (PEB *) 0x7FFD5000; 218 | this->fs = 0x7FFDF000; // set the fs segment to this place 219 | mem->add_pointer((DWORD) tib, 0x7FFDF000, sizeof(TEB) + sizeof(TIB)); 220 | DWORD ptr = *mem->read_virtual_mem(GetFS()); 221 | } 222 | 223 | DWORD Thread::GetFS() { 224 | return fs; 225 | } 226 | 227 | void Thread::TLSContinue() { 228 | if (still_tls) { 229 | DWORD image = (DWORD) mem->read_virtual_mem(process->GetImagebase()); 230 | DWORD PEHeader_ptr = ((dos_header *) image)->e_lfanew + image; 231 | image_header * PEHeader = (image_header *) PEHeader_ptr; 232 | _IMAGE_TLS_DIRECTORY * tlsheader = (_IMAGE_TLS_DIRECTORY *) ((DWORD) PEHeader->optional.data_directory[IMAGE_DIRECTORY_ENTRY_TLS].virtual_address + image); 233 | DWORD * callbacks = mem->read_virtual_mem((DWORD) tlsheader->AddressOfCallBacks); 234 | if (callbacks[tls_callback_index] != 0) { 235 | stack->push(0); 236 | stack->push(1); 237 | stack->push(0); 238 | stack->push(TLS_MAGIC); 239 | this->Eip = callbacks[tls_callback_index]; 240 | log = new Log(this->Eip); 241 | still_tls = true; 242 | tls_callback_index++; 243 | } else { 244 | still_tls = false; 245 | this->Eip = entry_point; 246 | log = new Log(entry_point); 247 | } 248 | } 249 | } 250 | -------------------------------------------------------------------------------- /emu/strings.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | #include "../x86emu.h" 21 | // this file for emulating string opcodes (movs,lods,stos,cmps,scas) 22 | 23 | // LODS 24 | int op_lods(Thread & thread, DISASM_INSTRUCTION * s) { 25 | int rep = 1; // for repeat instructions 26 | 27 | if (s->hde.flags & F_PREFIX_REP) { 28 | rep = thread.Exx[1]; // ecx 29 | thread.Exx[1] = 0; // set it to zero 30 | } 31 | // now we will loop the read instruction 32 | for (int i = 0; i < rep; i++) { 33 | // one byte 34 | DWORD * ptr; 35 | EMU_READ_MEM(ptr, thread.Exx[6]); // esi 36 | if (s->opcode->substr(0, s->opcode->size()).compare("lodsb") == 0) { 37 | thread.Exx[0] = (thread.Exx[0] & 0xFFFFFF00) + (*ptr & 0xFF); 38 | thread.Exx[6] += 1; 39 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("lodsd") == 0) && (s->hde.flags & F_PREFIX_66)) { 40 | thread.Exx[0] = (thread.Exx[0] & 0xFFFF0000) + (*ptr & 0xFFFF); 41 | thread.Exx[6] += 2; 42 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("lodsd") == 0) && !(s->hde.flags & F_PREFIX_66)) { 43 | thread.Exx[0] = *ptr; 44 | thread.Exx[6] += 4; 45 | } 46 | } 47 | return 0; 48 | } 49 | 50 | // ----------------------------------------------------------------------------------------------------------------- 51 | // STOS 52 | int op_stos(Thread & thread, DISASM_INSTRUCTION * s) { 53 | int rep = 1; // for repeat instructions 54 | 55 | if (s->hde.flags & F_PREFIX_REP) { 56 | rep = thread.Exx[1]; // ecx 57 | thread.Exx[1] = 0; // set it to zero 58 | } 59 | // now we will loop the read instruction 60 | for (int i = 0; i < rep; i++) { 61 | // one byte 62 | if (s->opcode->substr(0, s->opcode->size()).compare("stosb") == 0) { 63 | EMU_WRITE_MEM(thread.Exx[7], 1, (unsigned char *) &thread.Exx[0]); 64 | thread.Exx[7] += 1; 65 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("stosd") == 0) && (s->hde.flags & F_PREFIX_66)) { 66 | EMU_WRITE_MEM(thread.Exx[7], 2, (unsigned char *) &thread.Exx[0]); 67 | thread.Exx[7] += 2; 68 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("stosd") == 0) && !(s->hde.flags & F_PREFIX_66)) { 69 | EMU_WRITE_MEM(thread.Exx[7], 4, (unsigned char *) &thread.Exx[0]); 70 | thread.Exx[7] += 4; 71 | } 72 | } 73 | return 0; 74 | } 75 | 76 | // ----------------------------------------------------------------------------------------------------------------- 77 | // MOVS 78 | int op_movs(Thread & thread, DISASM_INSTRUCTION * s) { 79 | int rep = 1; // for repeat instructions 80 | 81 | if (s->hde.flags & F_PREFIX_REP) { 82 | rep = thread.Exx[1]; // ecx 83 | thread.Exx[1] = 0; // set it to zero 84 | } 85 | // now we will loop the read instruction 86 | for (int i = 0; i < rep; i++) { 87 | // one byte 88 | DWORD * ptr; 89 | EMU_READ_MEM(ptr, thread.Exx[6]); // esi 90 | if (s->opcode->substr(0, s->opcode->size()).compare("movsb") == 0) { 91 | unsigned char n = (unsigned char) (*ptr & 0xFF); 92 | EMU_WRITE_MEM(thread.Exx[7], 1, (unsigned char *) &n); 93 | thread.Exx[6] += 1; 94 | thread.Exx[7] += 1; 95 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("movsd") == 0) && (s->hde.flags & F_PREFIX_66)) { 96 | unsigned short n = (unsigned short) (*ptr & 0xFFFF); 97 | EMU_WRITE_MEM(thread.Exx[7], 2, (unsigned char *) &n); 98 | thread.Exx[6] += 2; 99 | thread.Exx[7] += 2; 100 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("movsd") == 0) && !(s->hde.flags & F_PREFIX_66)) { 101 | DWORD n = *ptr; 102 | EMU_WRITE_MEM(thread.Exx[7], 4, (unsigned char *) &n); 103 | thread.Exx[6] += 4; 104 | thread.Exx[7] += 4; 105 | } 106 | // cout << "the result is = "<< (int*)thread.Exx[0]<< "\n"; 107 | // system("PAUSE"); 108 | } 109 | return 0; 110 | } 111 | 112 | // ----------------------------------------------------------------------------------------------------------------- 113 | // CMPS 114 | int op_cmps(Thread & thread, DISASM_INSTRUCTION * s) { 115 | int rep = 1; // for repeat instructions 116 | bool repe = false; 117 | bool ins_rep = false; 118 | 119 | if (s->hde.flags & F_PREFIX_REP) { 120 | rep = thread.Exx[1]; // ecx 121 | ins_rep = true; 122 | // thread.Exx[1]=0; //set it to zero 123 | } 124 | if (s->hde.flags & F_PREFIX_REPX) { 125 | repe = true; 126 | } 127 | // now we will loop the read instruction 128 | for (int i = 0; i < rep; i++) { 129 | // one byte 130 | DWORD * src; 131 | DWORD * dest; 132 | EMU_READ_MEM(src, thread.Exx[6]); // esi 133 | EMU_READ_MEM(dest, thread.Exx[7]); // edi 134 | // cout << (int*)*dest<<"\n"; 135 | DWORD result; 136 | if (s->opcode->substr(0, s->opcode->size()).compare("cmpsb") == 0) { 137 | result = (*src & 0xFF) - (*dest & 0xFF); 138 | if (ins_rep) { 139 | thread.Exx[1]--; 140 | } 141 | thread.Exx[6] += 1; 142 | thread.Exx[7] += 1; 143 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("cmpsd") == 0) && (s->hde.flags & F_PREFIX_66)) { 144 | result = (*src & 0xFFFF - *dest & 0xFFFF); 145 | if (ins_rep) { 146 | thread.Exx[1]--; 147 | } 148 | thread.Exx[6] += 2; 149 | thread.Exx[7] += 2; 150 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("cmpsd") == 0) && !(s->hde.flags & F_PREFIX_66)) { 151 | result = *src - *dest; 152 | if (ins_rep) { 153 | thread.Exx[1]--; 154 | } 155 | thread.Exx[6] += 4; 156 | thread.Exx[7] += 4; 157 | } 158 | thread.updateflags(*dest, 0, result, UPDATEFLAGS_SUB, s->flags); 159 | // system("PAUSE"); 160 | if (thread.EFlags & EFLG_ZF && (repe == false)) { 161 | break; 162 | } 163 | if (!(thread.EFlags & EFLG_ZF) && (repe == true)) { 164 | break; 165 | } 166 | // cout << "the result is = "<< (int*)thread.Exx[0]<< "\n"; 167 | // system("PAUSE"); 168 | } 169 | return 0; 170 | } 171 | 172 | // ----------------------------------------------------------------------------------------------------------------- 173 | // SCAS 174 | int op_scas(Thread & thread, DISASM_INSTRUCTION * s) { 175 | int rep = 1; // for repeat instructions 176 | bool ins_rep = false; 177 | bool repe = false; 178 | 179 | if (s->hde.flags & F_PREFIX_REP) { 180 | rep = thread.Exx[1]; // ecx 181 | ins_rep = true; 182 | // thread.Exx[1]=0; //set it to zero 183 | } 184 | if (s->hde.flags & F_PREFIX_REPX) { 185 | repe = true; 186 | } 187 | // now we will loop the read instruction 188 | for (int i = 0; i < rep; i++) { 189 | // one byte 190 | DWORD * dest; 191 | DWORD * src = (DWORD *) &thread.Exx[0]; // eax 192 | EMU_READ_MEM(dest, thread.Exx[7]); // edi 193 | // cout << (int*)*dest<<"\n"; 194 | DWORD result; 195 | if (s->opcode->substr(0, s->opcode->size()).compare("scasb") == 0) { 196 | result = (*src & 0xFF) - (*dest & 0xFF); 197 | if (ins_rep) { 198 | thread.Exx[1]--; 199 | } 200 | thread.Exx[7] += 1; 201 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("scasd") == 0) && (s->hde.flags & F_PREFIX_66)) { 202 | result = (*src & 0xFFFF - *dest & 0xFFFF); 203 | if (ins_rep) { 204 | thread.Exx[1]--; 205 | } 206 | thread.Exx[7] += 2; 207 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("scasd") == 0) && !(s->hde.flags & F_PREFIX_66)) { 208 | result = *src - *dest; 209 | if (ins_rep) { 210 | thread.Exx[1]--; 211 | } 212 | thread.Exx[7] += 4; 213 | } 214 | thread.updateflags(*dest, 0, result, UPDATEFLAGS_SUB, s->flags); 215 | // cout<< (int*)result << "\n"; 216 | // system("PAUSE"); 217 | if (thread.EFlags & EFLG_ZF && (repe == false)) { 218 | break; 219 | } 220 | if (!(thread.EFlags & EFLG_ZF) && (repe == true)) { 221 | break; 222 | } 223 | // cout << "the result is = "<< (int*)thread.Exx[0]<< "\n"; 224 | // system("PAUSE"); 225 | } 226 | return 0; 227 | } 228 | -------------------------------------------------------------------------------- /tib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | struct _PEXCEPTION_REGISTRATION_RECORD 21 | { 22 | _PEXCEPTION_REGISTRATION_RECORD* Next; 23 | DWORD Handler; 24 | }; 25 | struct TIB 26 | { 27 | _PEXCEPTION_REGISTRATION_RECORD* ExceptionList; //FS:[0x00] 28 | DWORD StackBase; //FS:[0x04] 29 | DWORD StackLimit; //FS:[0x08] 30 | DWORD SubSystemTib; //FS:[0x0C] 31 | DWORD FiberData; //FS:[0x10] 32 | DWORD ArbitraryUserPointer; //FS:[0x14] 33 | DWORD TIBOffset; //FS:[0x18] 34 | }; 35 | struct PEB; 36 | struct TEB { 37 | 38 | DWORD EnvironmentPointer; //+1C 39 | DWORD ProcessId; //+20 40 | DWORD threadId; //+24 41 | DWORD ActiveRpcInfo; //+28 42 | DWORD ThreadLocalStoragePointer; //+2C 43 | PEB* Peb; //+30 44 | DWORD LastErrorValue; //+34 45 | DWORD CountOfOwnedCriticalSections; //+38 46 | DWORD CsrClientThread; //+3C 47 | DWORD Win32ThreadInfo; //+40 48 | DWORD Win32ClientInfo[0x1F]; //+44 49 | DWORD WOW32Reserved; //+48 50 | DWORD CurrentLocale; //+4C 51 | DWORD FpSoftwareStatusRegister; //+50 52 | DWORD SystemReserved1[0x36]; //+54 53 | DWORD Spare1; //+58 54 | DWORD ExceptionCode; //+5C 55 | DWORD SpareBytes1[0x28]; //+60 56 | DWORD SystemReserved2[0xA]; //+64 57 | DWORD GdiRgn; //+68 58 | DWORD GdiPen; //+6C 59 | DWORD GdiBrush; //+70 60 | DWORD RealClientId1; //+74 61 | DWORD RealClientId2; //+78 62 | DWORD GdiCachedProcessHandle; //+7C 63 | DWORD GdiClientPID; //+80 64 | DWORD GdiClientTID; //+84 65 | DWORD GdiThreadLocaleInfo; //+88 66 | DWORD UserReserved[5]; //+8C 67 | DWORD GlDispatchTable[0x118]; //+90 68 | DWORD GlReserved1[0x1A]; //+94 69 | DWORD GlReserved2; //+98 70 | DWORD GlSectionInfo; //+9C 71 | DWORD GlSection; //+A0 72 | DWORD GlTable; //+A4 73 | DWORD GlCurrentRC; //+A8 74 | DWORD GlContext; //+AC 75 | DWORD LastStatusValue; //+B0 76 | char* StaticUnicodeString; //+B4 77 | char StaticUnicodeBuffer[0x105]; //+B8 78 | DWORD DeallocationStack; //+BC 79 | DWORD TlsSlots[0x40]; //+C0 80 | DWORD TlsLinks; //+C4 81 | DWORD Vdm; //+C8 82 | DWORD ReservedForNtRpc; //+CC 83 | DWORD DbgSsReserved[0x2]; //+D0 84 | DWORD HardErrorDisabled; 85 | DWORD Instrumentation[0x10]; 86 | DWORD WinSockData; 87 | DWORD GdiBatchCount; 88 | DWORD Spare2; 89 | DWORD Spare3; 90 | DWORD Spare4; 91 | DWORD ReservedForOle; 92 | DWORD WaitingOnLoaderLock; 93 | DWORD StackCommit; 94 | DWORD StackCommitMax; 95 | DWORD StackReserved; 96 | }; 97 | 98 | struct __LIST_ENTRY{ 99 | DWORD Flink; // Ptr32 _LIST_ENTRY 100 | DWORD Blink; // Ptr32 _LIST_ENTRY 101 | }; 102 | 103 | struct _LDR_DATA_TABLE_ENTRY{ 104 | __LIST_ENTRY InLoadOrderLinks; //+00 105 | __LIST_ENTRY InMemoryOrderLinks; //+08 106 | __LIST_ENTRY InInitializationOrderLinks; //+10 107 | DWORD DllBase; //+18 108 | DWORD EntryPoint; //+1C 109 | DWORD SizeOfImage; //+20 110 | DWORD FullDllNameLength; //+24 111 | char* FullDllName; // _UNICODE_STRING //+28 112 | DWORD BaseDllNameLength; //+2C 113 | char* BaseDllName; //_UNICODE_STRING //+30 114 | DWORD Flags; //+34 115 | short LoadCount; //+38 116 | short TlsIndex; //+3C 117 | union{ 118 | __LIST_ENTRY HashLinks; 119 | DWORD SectionPointer; 120 | }; 121 | DWORD CheckSum; 122 | union{ 123 | DWORD TimeDateStamp; 124 | DWORD LoadedImports; 125 | }; 126 | DWORD EntryPointActivationContext; 127 | DWORD PatchInformation; 128 | __LIST_ENTRY ForwarderLinks; 129 | __LIST_ENTRY ServiceTagLinks; 130 | __LIST_ENTRY StaticLinks; 131 | }; 132 | 133 | struct _PEB_LDR_DATA { 134 | DWORD Length_; //+00 135 | DWORD Initialized; //+04 136 | DWORD SsHandle; //+08 137 | __LIST_ENTRY InLoadOrderModuleList; //+0C 138 | __LIST_ENTRY InMemoryOrderModuleList; //+14 139 | __LIST_ENTRY InInitializationOrderModuleList;//+1C 140 | DWORD EntryInProgress; //+24 141 | DWORD ShutdownInProgress; //+28 142 | DWORD ShutdownThreadId; //+2C 143 | }; //size = 30 144 | 145 | struct PEB { 146 | char InheritedAddressSpace; //+00 147 | char ReadImageFileExecOptions; //+01 148 | char BeingDebugged; 149 | char Spare; 150 | DWORD Mutant; //+04 151 | DWORD ImageBaseAddress; //+08 152 | _PEB_LDR_DATA* LoaderData; //+0C 153 | DWORD ProcessParameters; //+10 154 | DWORD SubSystemData; //+14 155 | DWORD ProcessHeap; //+18 156 | DWORD FastPebLock; //+1C 157 | DWORD FastPebLockRoutine; //+20 158 | DWORD FastPebUnlockRoutine; //+24 159 | DWORD EnvironmentUpdateCount; //+28 160 | DWORD KernelCallbackTable; //+2C 161 | DWORD EventLogSection; //+30 162 | DWORD EventLog; //+34 163 | DWORD FreeList; //+38 164 | DWORD TlsExpansionCounter; //+3C 165 | DWORD TlsBitmap; //+40 166 | DWORD TlsBitmapBits[0x2]; 167 | DWORD ReadOnlySharedMemoryBase; 168 | DWORD ReadOnlySharedMemoryHeap; 169 | DWORD ReadOnlyStaticServerData; 170 | DWORD AnsiCodePageData; 171 | DWORD OemCodePageData; 172 | DWORD UnicodeCaseTableData; 173 | DWORD NumberOfProcessors; 174 | DWORD NtGlobalFlag; 175 | char Spare2[0x4]; 176 | DWORD CriticalSectionTimeout1; 177 | DWORD CriticalSectionTimeout2; 178 | DWORD HeapSegmentReserve; 179 | DWORD HeapSegmentCommit; 180 | DWORD HeapDeCommitTotalFreeThreshold; 181 | DWORD HeapDeCommitFreeBlockThreshold; 182 | DWORD NumberOfHeaps; //+88 183 | DWORD MaximumNumberOfHeaps; //+8C 184 | DWORD *ProcessHeaps; //+90 185 | DWORD GdiSharedHandleTable; 186 | DWORD ProcessStarterHelper; 187 | DWORD GdiDCAttributeList; 188 | DWORD LoaderLock; 189 | DWORD OSMajorVersion; 190 | DWORD OSMinorVersion; 191 | DWORD OSBuildNumber; 192 | DWORD OSPlatformId; 193 | DWORD ImageSubSystem; 194 | DWORD ImageSubSystemMajorVersion; 195 | DWORD ImageSubSystemMinorVersion; 196 | DWORD GdiHandleBuffer[0x22]; 197 | DWORD PostProcessInitRoutine; 198 | DWORD TlsExpansionBitmap; 199 | char TlsExpansionBitmapBits[0x80]; 200 | DWORD SessionId; 201 | }; 202 | -------------------------------------------------------------------------------- /vmem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | #include "x86emu.h" 21 | #define MAXIMUM_STATIC_SIZE 100 22 | 23 | #define VMEM_START_VALLOC 0x00870000 24 | #define VMEM_START_DLL 0x77000000 25 | #define VMEM_START_STACK 0x00126000 26 | 27 | VirtualMemory::VirtualMemory() 28 | { 29 | // it's a dynamic array to vMem* so we will initialize it 30 | vAllocCommittedPages = VMEM_START_VALLOC; 31 | DLLCommittedPages = VMEM_START_DLL; 32 | StackCommittedPages = VMEM_START_STACK; 33 | vmem = (vMem **) malloc(MAXIMUM_STATIC_SIZE * 4); 34 | memset((void *) vmem, 0, 4); 35 | vmem_length = 0; 36 | cmem = (cMem **) malloc(4); 37 | memset((void *) cmem, 0, 4); 38 | cmem_length = 0; 39 | last_accessed = new Log(0); 40 | last_modified = new Log(0); 41 | } 42 | 43 | //This function create a random address for DLL Imagebase, VirtualProtect or Stack 44 | DWORD VirtualMemory::create_memory_address(int Type) 45 | { 46 | DWORD* pCommitedPages = NULL; 47 | if (Type == VMEM_TYPE_STACK) 48 | { 49 | pCommitedPages = &StackCommittedPages; 50 | } 51 | else if (Type == VMEM_TYPE_DLL) 52 | { 53 | pCommitedPages = &DLLCommittedPages; 54 | } 55 | else if (Type == VMEM_TYPE_ALLOC) 56 | { 57 | pCommitedPages = &vAllocCommittedPages; 58 | } 59 | 60 | if (pCommitedPages == NULL)return 0; 61 | 62 | while(1) 63 | { 64 | if (read_virtual_mem(*pCommitedPages) != 0) 65 | { 66 | *pCommitedPages += 0x10000; 67 | } 68 | else 69 | { 70 | break; 71 | } 72 | } 73 | return *pCommitedPages; 74 | 75 | } 76 | // DWORD VirtualMemory::add_pointer(DWORD rptr,DWORD vptr,DWORD size){ 77 | // add_pointer(rptr,vptr,size,MEM_READWRITE); 78 | // }; 79 | void _cdecl VirtualMemory::add_pointer(DWORD rptr, DWORD vptr, DWORD size, int flags) { 80 | 81 | if (vmem_length == 0) { 82 | vmem[0] = (vMem *) malloc(MAXIMUM_STATIC_SIZE * sizeof(vMem)); 83 | vmem[0]->rmem = rptr; 84 | vmem[0]->vmem = vptr; 85 | vmem[0]->size = size; 86 | vmem[0]->flags = flags; 87 | vmem_length++; 88 | } else { 89 | if (vmem_length >= MAXIMUM_STATIC_SIZE) { 90 | DWORD c = (DWORD) vmem; 91 | vmem = (vMem **) realloc((void *) vmem, (vmem_length + 1) * 4); 92 | memcpy((void *) c, vmem, (vmem_length) * 4); 93 | vmem[vmem_length] = (vMem *) malloc(sizeof(vMem)); 94 | // if (vmem[vmem_length]==0)vmem[vmem_length]=(vMem*)alloc(sizeof(vMem)); 95 | memset(vmem[vmem_length], 0, 4); 96 | } else { 97 | // vmem=(vMem**)realloc((void*)vmem,(vmem_length+1)*4) ; 98 | vmem[vmem_length] = (vMem*)((DWORD)vmem[vmem_length - 1] + (DWORD)sizeof(vMem)); 99 | } 100 | vmem[vmem_length]->rmem = rptr; 101 | vmem[vmem_length]->vmem = vptr; 102 | vmem[vmem_length]->size = size; 103 | vmem[vmem_length]->flags = flags; // */ 104 | vmem_length++; 105 | } 106 | } 107 | 108 | DWORD VirtualMemory::get_virtual_pointer(DWORD ptr) { 109 | for (int i = this->vmem_length - 1; i >= 0; i--) { 110 | if ((ptr >= vmem[i]->rmem) && (ptr < (vmem[i]->rmem + vmem[i]->size)) && (vmem[i]->size != 0)) { 111 | ptr -= vmem[i]->rmem; 112 | ptr += vmem[i]->vmem; 113 | return ptr; 114 | } 115 | } 116 | // throw(EXP_INVALIDPOINTER); //we don't need errors this time 117 | return 0; 118 | } 119 | 120 | DWORD * VirtualMemory::read_virtual_mem(DWORD ptr) { 121 | DWORD vptr = ptr; 122 | 123 | for (int i = this->vmem_length - 1; i >= 0; i--) { 124 | // cout << (int*)vptr << " "<<(int*)vmem[i]->vmem << "\n"; 125 | if ((ptr >= vmem[i]->vmem) && (ptr < (vmem[i]->vmem + vmem[i]->size)) && (vmem[i]->size != 0)) { 126 | ptr -= vmem[i]->vmem; 127 | ptr += vmem[i]->rmem; 128 | last_accessed->addlog(vptr); 129 | return (DWORD *) ptr; 130 | } 131 | } 132 | return 0; 133 | } 134 | 135 | bool VirtualMemory::get_memory_flags(DWORD ptr) { 136 | for (int i = 0; i < this->cmem_length; i++) { 137 | if ((ptr >= cmem[i]->ptr) && (ptr < (cmem[i]->ptr + cmem[i]->size))) { 138 | return true; 139 | } 140 | } 141 | // cout << this->cmem_length <<"\n"; 142 | return false; 143 | } 144 | 145 | DWORD VirtualMemory::write_virtual_mem(DWORD ptr, DWORD size,unsigned char * buff) { 146 | int vptr = ptr; 147 | int entry = 0; 148 | 149 | for (int i = this->vmem_length - 1; i >= 0; i--) { 150 | if ((ptr >= vmem[i]->vmem) && (ptr < (vmem[i]->vmem + vmem[i]->size)) && (vmem[i]->size != 0)) { 151 | 152 | ptr -= vmem[i]->vmem; 153 | ptr += vmem[i]->rmem; 154 | entry = i; 155 | 156 | goto mem_found; 157 | } 158 | } 159 | return EXP_INVALIDPOINTER; 160 | mem_found: 161 | if (vmem[entry]->flags == MEM_IMAGEBASE) { 162 | if (!check_writeaccess(vptr, vmem[entry]->vmem)) { 163 | return EXP_WRITEACCESS_DENIED; 164 | } 165 | } 166 | if ((vmem[entry]->flags == MEM_READONLY) || (vmem[entry]->flags == MEM_DLLBASE)) { 167 | return EXP_WRITEACCESS_DENIED; 168 | } 169 | memcpy((void *) ptr, buff, size); 170 | last_modified->addlog(vptr); 171 | set_memory_flags((DWORD) vptr, size); 172 | return 0; 173 | } 174 | 175 | void VirtualMemory::set_memory_flags(DWORD ptr, int size) { 176 | for (int i = 0; i < this->cmem_length; i++) { 177 | if ((ptr >= cmem[i]->ptr) && (ptr < (cmem[i]->ptr + cmem[i]->size))) { 178 | // so it's allready written 179 | goto found_ptr; 180 | } else if (ptr == (cmem[i]->ptr + cmem[i]->size)) { // here if it's the next DWORD or the next byte (for loop on decrypting something 181 | cmem[i]->size += size; 182 | goto found_ptr; 183 | } else if ((ptr + size) == cmem[i]->ptr) { // the prev byte or DWORD (decrypting from the end to the top) 184 | cmem[i]->ptr -= size; 185 | cmem[i]->size += size; 186 | goto found_ptr; 187 | } 188 | } 189 | // if not found so add it 190 | if (cmem_length == 0) { 191 | cmem[0] = (cMem *) malloc(sizeof(cMem)); 192 | cmem[0]->ptr = ptr; 193 | cmem[0]->size = size; 194 | cmem_length++; 195 | } else { 196 | cmem = (cMem **) realloc((void *) cmem, (cmem_length + 1) * 4); 197 | cmem[cmem_length] = (cMem *) malloc(sizeof(cMem)); 198 | cmem[cmem_length]->ptr = ptr; 199 | cmem[cmem_length]->size = size; 200 | cmem_length++; 201 | } 202 | found_ptr:; 203 | } 204 | 205 | bool VirtualMemory::check_writeaccess(DWORD ptr, DWORD imagebase) { 206 | // cout << (int*)ptr << "\n"<< (int*)imagebase << "\n"; 207 | image_header * PEHeader; 208 | DWORD FileHandler, PEHeader_ptr; 209 | image_section_header * data; 210 | 211 | FileHandler = (DWORD) read_virtual_mem(imagebase); 212 | PEHeader_ptr = ((dos_header *) FileHandler)->e_lfanew + FileHandler; 213 | PEHeader = (image_header *) PEHeader_ptr; 214 | if (ptr < (imagebase + PEHeader->optional.section_alignment)) { 215 | return false; 216 | } 217 | ptr -= imagebase; 218 | image_section_header * sections = (image_section_header *) (PEHeader->header.size_of_optional_header + (DWORD) & PEHeader->optional); 219 | if (PEHeader->header.number_of_sections != 0) { 220 | for (int i = 0; i < PEHeader->header.number_of_sections - 1; i++) { 221 | if ((ptr >= sections[i].virtual_address) && (ptr < (sections[i + 1].virtual_address))) { 222 | if (sections[i].characteristics & IMAGE_SCN_MEM_WRITE) { 223 | return true; 224 | } else { 225 | /*if(ptr == 0x33b0 ){ 226 | cout << "Imagebase : "<< (int*)imagebase << "\n"; 227 | cout << "Section : "<< i << "\n"; 228 | cout << "Characteristics : "<< (int*)sections[i].characteristics << "\n"; 229 | cout << "VirtualAddress : " << (int*)sections[i].virtual_address << "\n"; 230 | cout << "VirtualSize : " << (int*)sections[i+1].virtual_address << "\n"; 231 | };//*/ 232 | return false; 233 | } 234 | } 235 | } 236 | int n = PEHeader->header.number_of_sections - 1; 237 | DWORD s = (DWORD) & sections[n]; 238 | s += sizeof(image_section_header) + 1; 239 | image_section_header * f = (image_section_header *) s; 240 | if ((ptr >= sections[n].virtual_address) && (ptr < (PEHeader->optional.size_of_image))) { 241 | if (sections[n].characteristics & IMAGE_SCN_MEM_WRITE) { // 242 | return true; 243 | } else { 244 | return false; 245 | } 246 | } 247 | } 248 | return false; 249 | } 250 | 251 | DWORD VirtualMemory::delete_pointer(DWORD ptr) { 252 | for (int i = this->vmem_length - 1; i >= 0; i--) { 253 | if ((ptr >= vmem[i]->vmem) && (ptr <= (vmem[i]->vmem + vmem[i]->size)) && (vmem[i]->size != 0)) { 254 | vmem[i]->size = 0; 255 | return 0; 256 | } 257 | } 258 | return -1; 259 | } 260 | 261 | DWORD VirtualMemory::get_last_accessed(int index) { 262 | return last_accessed->getlog(index); 263 | } 264 | 265 | DWORD VirtualMemory::get_last_modified(int index) { 266 | return last_modified->getlog(index); 267 | } 268 | 269 | VirtualMemory::~VirtualMemory() 270 | { 271 | for (int i = 0; i < vmem_length; i++) { 272 | #ifdef WIN32 273 | if (!(vmem[i]->flags & MEM_VIRTUALPROTECT)) { 274 | VirtualFree((void *) vmem[i]->rmem, vmem[i]->size, MEM_DECOMMIT); 275 | } 276 | #else 277 | free((void *) vmem[i]->rmem); 278 | #endif 279 | } 280 | } -------------------------------------------------------------------------------- /hde28c/hde32.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Hacker Disassembler Engine 32 C 3 | * Copyright (c) 2008-2009, Vyacheslav Patkov. 4 | * All rights reserved. 5 | * 6 | */ 7 | 8 | //#include 9 | //#include 10 | #include "hde32.h" 11 | #include "table32.h" 12 | #include 13 | using namespace std; 14 | #ifdef WIN32 15 | 16 | #endif 17 | unsigned long hde32_disasm(const void* code, struct hde32s* hs) { 18 | unsigned char x, c, *p = (unsigned char *) code, cflags, opcode, pref = 0; 19 | unsigned char *ht = hde32_table, m_mod, m_reg, m_rm, disp_size = 0; 20 | 21 | memset(hs, 0, sizeof (struct hde32s)); 22 | 23 | for (x = 16; x; x--) 24 | switch (c = *p++) { 25 | case 0xf3: 26 | hs->p_rep = c; 27 | pref |= PRE_F3; 28 | break; 29 | case 0xf2: 30 | hs->p_rep = c; 31 | pref |= PRE_F2; 32 | break; 33 | case 0xf0: 34 | hs->p_lock = c; 35 | pref |= PRE_LOCK; 36 | break; 37 | case 0x26: case 0x2e: case 0x36: 38 | case 0x3e: case 0x64: case 0x65: 39 | hs->p_seg = c; 40 | pref |= PRE_SEG; 41 | break; 42 | case 0x66: 43 | hs->p_66 = c; 44 | pref |= PRE_66; 45 | break; 46 | case 0x67: 47 | hs->p_67 = c; 48 | pref |= PRE_67; 49 | break; 50 | default: 51 | goto pref_done; 52 | } 53 | pref_done: 54 | 55 | hs->flags = (unsigned long) pref << 23; 56 | 57 | if (!pref) 58 | pref |= PRE_NONE; 59 | 60 | if ((hs->opcode = c) == 0x0f) { 61 | hs->opcode2 = c = *p++; 62 | ht += DELTA_OPCODES; 63 | } else if (c >= 0xa0 && c <= 0xa3) { 64 | if (pref & PRE_67) 65 | pref |= PRE_66; 66 | else 67 | pref &= ~PRE_66; 68 | } 69 | 70 | opcode = c; 71 | cflags = ht[ht[opcode / 4] + (opcode % 4)]; 72 | 73 | if (cflags == C_ERROR) { 74 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 75 | cflags = 0; 76 | if ((opcode & -3) == 0x24) 77 | cflags++; 78 | } 79 | 80 | x = 0; 81 | if (cflags & C_GROUP) { 82 | unsigned short t; 83 | t = *(unsigned short *) (ht + (cflags & 0x7f)); 84 | cflags = (unsigned char) t; 85 | x = (unsigned char) (t >> 8); 86 | } 87 | 88 | if (hs->opcode2) { 89 | ht = hde32_table + DELTA_PREFIXES; 90 | if (ht[ht[opcode / 4] + (opcode % 4)] & pref) 91 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 92 | } 93 | 94 | if (cflags & C_MODRM) { 95 | hs->flags |= F_MODRM; 96 | hs->modrm = c = *p++; 97 | hs->modrm_mod = m_mod = c >> 6; 98 | hs->modrm_rm = m_rm = c & 7; 99 | hs->modrm_reg = m_reg = (c & 0x3f) >> 3; 100 | 101 | if (x && ((x << m_reg) & 0x80)) 102 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 103 | 104 | if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { 105 | unsigned char t = opcode - 0xd9; 106 | if (m_mod == 3) { 107 | ht = hde32_table + DELTA_FPU_MODRM + t * 8; 108 | t = ht[m_reg] << m_rm; 109 | } else { 110 | ht = hde32_table + DELTA_FPU_REG; 111 | t = ht[t] << m_reg; 112 | } 113 | if (t & 0x80) 114 | hs->flags |= F_ERROR | F_ERROR_OPCODE; 115 | } 116 | 117 | if (pref & PRE_LOCK) { 118 | if (m_mod == 3) { 119 | hs->flags |= F_ERROR | F_ERROR_LOCK; 120 | } else { 121 | unsigned char *table_end, op = opcode; 122 | if (hs->opcode2) { 123 | ht = hde32_table + DELTA_OP2_LOCK_OK; 124 | table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; 125 | } else { 126 | ht = hde32_table + DELTA_OP_LOCK_OK; 127 | table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; 128 | op &= -2; 129 | } 130 | for (; ht != table_end; ht++) 131 | if (*ht++ == op) { 132 | if (!((*ht << m_reg) & 0x80)) 133 | goto no_lock_error; 134 | else 135 | break; 136 | } 137 | hs->flags |= F_ERROR | F_ERROR_LOCK; 138 | no_lock_error: 139 | ; 140 | } 141 | } 142 | 143 | if (hs->opcode2) { 144 | switch (opcode) { 145 | case 0x20: case 0x22: 146 | m_mod = 3; 147 | if (m_reg > 4 || m_reg == 1) 148 | goto error_operand; 149 | else 150 | goto no_error_operand; 151 | case 0x21: case 0x23: 152 | m_mod = 3; 153 | if (m_reg == 4 || m_reg == 5) 154 | goto error_operand; 155 | else 156 | goto no_error_operand; 157 | } 158 | } else { 159 | switch (opcode) { 160 | case 0x8c: 161 | if (m_reg > 5) 162 | goto error_operand; 163 | else 164 | goto no_error_operand; 165 | case 0x8e: 166 | if (m_reg == 1 || m_reg > 5) 167 | goto error_operand; 168 | else 169 | goto no_error_operand; 170 | } 171 | } 172 | 173 | if (m_mod == 3) { 174 | unsigned char *table_end; 175 | if (hs->opcode2) { 176 | ht = hde32_table + DELTA_OP2_ONLY_MEM; 177 | table_end = ht + sizeof (hde32_table) - DELTA_OP2_ONLY_MEM; 178 | } else { 179 | ht = hde32_table + DELTA_OP_ONLY_MEM; 180 | table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; 181 | } 182 | for (; ht != table_end; ht += 2) 183 | if (*ht++ == opcode) { 184 | if (*ht++ & pref && !((*ht << m_reg) & 0x80)) 185 | goto error_operand; 186 | else 187 | break; 188 | } 189 | goto no_error_operand; 190 | } else if (hs->opcode2) { 191 | switch (opcode) { 192 | case 0x50: case 0xd7: case 0xf7: 193 | if (pref & (PRE_NONE | PRE_66)) 194 | goto error_operand; 195 | break; 196 | case 0xd6: 197 | if (pref & (PRE_F2 | PRE_F3)) 198 | goto error_operand; 199 | break; 200 | case 0xc5: 201 | goto error_operand; 202 | } 203 | goto no_error_operand; 204 | } else 205 | goto no_error_operand; 206 | 207 | error_operand: 208 | hs->flags |= F_ERROR | F_ERROR_OPERAND; 209 | no_error_operand: 210 | 211 | c = *p++; 212 | if (m_reg <= 1) { 213 | if (opcode == 0xf6) 214 | cflags |= C_IMM8; 215 | else if (opcode == 0xf7) 216 | cflags |= C_IMM_P66; 217 | } 218 | 219 | switch (m_mod) { 220 | case 0: 221 | if (pref & PRE_67) { 222 | if (m_rm == 6) 223 | disp_size = 2; 224 | } else 225 | if (m_rm == 5) 226 | disp_size = 4; 227 | break; 228 | case 1: 229 | disp_size = 1; 230 | break; 231 | case 2: 232 | disp_size = 2; 233 | if (!(pref & PRE_67)) 234 | disp_size <<= 1; 235 | } 236 | 237 | if (m_mod != 3 && m_rm == 4 && !(pref & PRE_67)) { 238 | hs->flags |= F_SIB; 239 | p++; 240 | hs->sib = c; 241 | hs->sib_scale = c >> 6; 242 | hs->sib_index = (c & 0x3f) >> 3; 243 | if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) 244 | disp_size = 4; 245 | } 246 | 247 | p--; 248 | switch (disp_size) { 249 | case 1: 250 | hs->flags |= F_DISP8; 251 | hs->disp.disp8 = *(unsigned char *)p; 252 | break; 253 | case 2: 254 | hs->flags |= F_DISP16; 255 | hs->disp.disp16 = *(unsigned short *) p; 256 | break; 257 | case 4: 258 | hs->flags |= F_DISP32; 259 | hs->disp.disp32 = *(unsigned int *) p; 260 | } 261 | p += disp_size; 262 | } else if (pref & PRE_LOCK) 263 | hs->flags |= F_ERROR | F_ERROR_LOCK; 264 | 265 | if (cflags & C_IMM_P66) { 266 | if (cflags & C_REL32) { 267 | if (pref & PRE_66) { 268 | hs->flags |= F_IMM16 | F_RELATIVE; 269 | hs->imm.imm16 = *(unsigned short *) p; 270 | p += 2; 271 | goto disasm_done; 272 | } 273 | goto rel32_ok; 274 | } 275 | if (pref & PRE_66) { 276 | hs->flags |= F_IMM16; 277 | hs->imm.imm16 = *(unsigned short *) p; 278 | p += 2; 279 | } else { 280 | hs->flags |= F_IMM32; 281 | hs->imm.imm32 = *(unsigned long *) p; 282 | p += 4; 283 | } 284 | } 285 | 286 | if (cflags & C_IMM16) { 287 | if (hs->flags & F_IMM32) { 288 | hs->flags |= F_IMM16; 289 | hs->disp.disp16 = *(unsigned short *) p; 290 | } else if (hs->flags & F_IMM16) { 291 | hs->flags |= F_2IMM16; 292 | hs->disp.disp16 = *(unsigned short *) p; 293 | } else { 294 | hs->flags |= F_IMM16; 295 | hs->imm.imm16 = *(unsigned short *) p; 296 | } 297 | p += 2; 298 | } 299 | if (cflags & C_IMM8) { 300 | hs->flags |= F_IMM8; 301 | hs->imm.imm8 = *p++; 302 | } 303 | 304 | if (cflags & C_REL32) { 305 | rel32_ok: 306 | hs->flags |= F_IMM32 | F_RELATIVE; 307 | hs->imm.imm32 = *(unsigned long *) p; 308 | p += 4; 309 | } else if (cflags & C_REL8) { 310 | hs->flags |= F_IMM8 | F_RELATIVE; 311 | hs->imm.imm8 = *(unsigned char *)p++; 312 | } 313 | 314 | disasm_done: 315 | 316 | if ((hs->len = (unsigned char) (p - (unsigned char *) code)) > 15) { 317 | hs->flags |= F_ERROR | F_ERROR_LENGTH; 318 | hs->len = 15; 319 | } 320 | 321 | return (unsigned int) hs->len; 322 | } 323 | -------------------------------------------------------------------------------- /apis/apis.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | #include "../x86emu.h" 21 | 22 | int undefined_api(Thread * thread, DWORD * Args) { 23 | return 0; 24 | } 25 | 26 | int System::define_dll(char * name, char * path, DWORD vAddr) 27 | { 28 | if (name == NULL || path == NULL || vAddr == NULL)return 0; 29 | if (GetDllIndex(name)) 30 | { 31 | return GetDllIndex(name); 32 | } 33 | DLLs[dll_entries].name = name; 34 | DLLs[dll_entries].vAddr = vAddr; 35 | 36 | string s = ""; 37 | 38 | s.append(path); 39 | s.append(name); 40 | DLLs[dll_entries].imagebase = PELoader(s); 41 | // cout << (int*)DLLs[dll_entries].imagebase << "\n"; 42 | if (DLLs[dll_entries].imagebase == 0) 43 | { 44 | return 0; 45 | } 46 | DWORD FileHandler = DLLs[dll_entries].imagebase; 47 | image_header * PEHeader; 48 | PEHeader = (image_header *) (((dos_header *) FileHandler)->e_lfanew + FileHandler); 49 | DLLs[dll_entries].size = PEHeader->optional.size_of_image; 50 | dll_entries++; 51 | return dll_entries - 1; 52 | } 53 | 54 | int System::define_api(char * name, DLL * lib, DWORD args, int (* emu_func)(Thread *, DWORD *)) 55 | { 56 | if (name == NULL || lib == NULL || emu_func == NULL) return 0; 57 | for (int i = 0; i < api_entries; i++) 58 | { 59 | if (!strcmp(to_lower_case(APITable[i].name).c_str(), to_lower_case(name).c_str())) 60 | { 61 | APITable[i].lib = lib; 62 | APITable[i].emu_func = emu_func; 63 | return i; 64 | } 65 | } 66 | APITable[api_entries].name = name; 67 | APITable[api_entries].lib = lib; 68 | APITable[api_entries].args = args; 69 | APITable[api_entries].addr = GetAPI(APITable[api_entries].name, lib->imagebase); 70 | APITable[api_entries].emu_func = emu_func; 71 | api_entries++; 72 | return api_entries - 1; 73 | } 74 | 75 | // --------------------------------------------------------------------------------------------------- 76 | void System::init_apis(char * path) 77 | { 78 | // define the dlls 79 | define_dll("kernel32.dll", path, enVars.kernel32); 80 | define_dll("ntdll.dll", path, enVars.ntdll); 81 | define_dll("user32.dll", path, enVars.user32); 82 | 83 | // the defined apis 84 | define_api("GetProcAddress", &DLLs[0], 2, GetProcAddress_emu); 85 | define_api("GetModuleHandleA", &DLLs[0], 1, GetModuleHandleA_emu); 86 | define_api("LoadLibraryA", &DLLs[0], 1, LoadLibraryA_emu); 87 | define_api("VirtualAlloc", &DLLs[0], 4, VirtualAlloc_emu); 88 | define_api("VirtualFree", &DLLs[0], 3, VirtualFree_emu); 89 | define_api("VirtualProtect", &DLLs[0], 4, VirtualProtect_emu); 90 | define_api("SetUnhandledExceptionFilter", &DLLs[0], 1, SetUnhandledExceptionFilter_emu); 91 | 92 | // undefined apis 93 | ///* 94 | define_api("ExitProcess", &DLLs[0], 1, undefined_api); 95 | define_api("MessageBoxA", &DLLs[2], 4, undefined_api); 96 | define_api("GetCommandLineA", &DLLs[0], 0, undefined_api); 97 | define_api("CreateProcessA", &DLLs[0], 10, undefined_api); 98 | define_api("lstrlenA", &DLLs[0], 1, undefined_api); 99 | define_api("GetTickCount", &DLLs[0], 0, undefined_api); 100 | define_api("GetCurrentProcess", &DLLs[0], 0, undefined_api); 101 | define_api("GetCurrentProcessId", &DLLs[0], 0, undefined_api); 102 | define_api("GetCurrentThread", &DLLs[0], 0, undefined_api); 103 | define_api("GetStartupInfoA", &DLLs[0], 1, undefined_api); 104 | define_api("GetKeyboardType", &DLLs[2], 1, undefined_api); 105 | define_api("GetModuleFileNameA", &DLLs[0], 2, undefined_api); 106 | define_api("ReadFile", &DLLs[0], 5, undefined_api); 107 | define_api("WriteFile", &DLLs[0], 5, undefined_api); 108 | define_api("CreateFileA", &DLLs[0], 7, undefined_api); 109 | define_api("GetFileSize", &DLLs[0], 2, undefined_api); 110 | define_api("SetFilePointer", &DLLs[0], 4, undefined_api); 111 | define_api("SetEndOfFile", &DLLs[0], 2, undefined_api); 112 | define_api("GetLocaleInfoA", &DLLs[0], 4, undefined_api); 113 | define_api("IsCharUpper", &DLLs[0], 1, undefined_api); 114 | define_api("GetLastError", &DLLs[0], 0, undefined_api); 115 | define_api("GetKeyState", &DLLs[2], 1, undefined_api); 116 | define_api("GetFocus", &DLLs[2], 0, undefined_api); 117 | define_api("GetForegroundWindow", &DLLs[0], 0, undefined_api); 118 | define_api("GetDC", &DLLs[0], 1, undefined_api); 119 | define_api("GetCursorPos", &DLLs[0], 1, undefined_api); 120 | define_api("GetCursor", &DLLs[0], 0, undefined_api); 121 | define_api("lstrcmpA", &DLLs[0], 2, undefined_api); 122 | define_api("lstrcmpiA", &DLLs[0], 2, undefined_api); 123 | define_api("ZwSetInformationProcess", &DLLs[1], 4, undefined_api); 124 | define_api("ZwQueryInformationProcess", &DLLs[1], 5, undefined_api); 125 | //*/ 126 | // ZwSetInformationProcess 127 | 128 | // */ 129 | } 130 | 131 | int System::CallToAPI(Thread * thread, DISASM_INSTRUCTION * s) 132 | { 133 | DWORD retPtr = thread->stack->pop(); 134 | 135 | // cout << "\nCalling an API ......\n---------------------\n"; 136 | // if(s->other >0 )cout << APITable[s->other-1].name << "\n"; 137 | if (s->other > 0) 138 | { 139 | int n = s->other - 1; 140 | if (APITable[n].args > 0) 141 | { 142 | DWORD * args = (DWORD *) malloc(APITable[n].args * 4); 143 | memset(args, 0, APITable[n].args * 4); 144 | for (int i = 0; i < APITable[n].args; i++) 145 | { 146 | args[i] = thread->stack->pop(); 147 | // cout << i << " Argument : " << (int*)args[i] <<" "<< (int*)thread->Exx[4] << "\n"; 148 | } 149 | thread->Exx[0] = APITable[n].emu_func(thread, args); 150 | free(args); 151 | // cout << (int*)thread->Exx[0] << "\n"; 152 | } 153 | } 154 | thread->Eip = retPtr; 155 | return 0; 156 | } 157 | 158 | bool System::IsApiCall(Thread& thread, DISASM_INSTRUCTION * s) 159 | { 160 | if (s == NULL)return false; 161 | 162 | // first we will search for the pointer to find it's an API or not 163 | DWORD ptr = thread.Eip; 164 | int entry = 0; 165 | 166 | if ((ptr & 0xFFFF0000) == 0xBBBB0000) 167 | { 168 | return true; 169 | } 170 | for (int i = 0; i < thread.mem->vmem_length; i++) 171 | { 172 | if ((ptr >= thread.mem->vmem[i]->vmem) && (ptr <= (thread.mem->vmem[i]->vmem + thread.mem->vmem[i]->size))) { 173 | ptr -= thread.mem->vmem[i]->vmem; 174 | ptr += thread.mem->vmem[i]->rmem; 175 | entry = i; 176 | break; 177 | } 178 | } 179 | // it's an API let's get more information 180 | if (thread.mem->vmem[entry]->flags == MEM_DLLBASE) 181 | { 182 | s->flags |= API_CALL; 183 | // let's search for the api 184 | for (int i = 0; i < api_entries; i++) 185 | { 186 | if (APITable[i].addr == ptr) 187 | { 188 | s->other = i + 1; // because zero mean undefined :) 189 | break; 190 | } 191 | } 192 | return true; 193 | } 194 | else 195 | { 196 | return false; 197 | } 198 | } 199 | 200 | unsigned long System::GetAPI(char * func, unsigned long dll) 201 | { 202 | if (func == NULL || dll == NULL)return 0; 203 | 204 | DWORD hKernelModule; 205 | DWORD dwFuncOffset; 206 | DWORD dwNameOrdOffset; 207 | DWORD dwTemp, dwOffsetPE, dwOffsetExport; 208 | int i = 0; 209 | DWORD dwNumberOfNames, dwNamesOffset; 210 | DWORD * dwNameRVAs; 211 | DWORD * dwFuncRVAs; 212 | short * dwNameOrdRVAs; 213 | bool bApiFound; 214 | char lpszApiName[255]; 215 | 216 | // cout << func << "\n"; 217 | hKernelModule = dll; 218 | dwOffsetPE = *(DWORD *) ((DWORD) hKernelModule + 0x3C); 219 | dwOffsetExport = *(DWORD *) ((DWORD) hKernelModule + dwOffsetPE + 0x78); 220 | 221 | dwNumberOfNames = *(DWORD *) ((DWORD) hKernelModule + dwOffsetExport + 0x18); 222 | 223 | dwFuncOffset = *(DWORD *) (hKernelModule + dwOffsetExport + 0x1C); 224 | dwNamesOffset = *(DWORD *) ((DWORD) hKernelModule + dwOffsetExport + 0x20); 225 | dwNameOrdOffset = *(DWORD *) ((DWORD) hKernelModule + dwOffsetExport + 0x24); 226 | dwNameRVAs = (DWORD *) (hKernelModule + dwNamesOffset); 227 | dwFuncRVAs = (DWORD *) (hKernelModule + dwFuncOffset); 228 | dwNameOrdRVAs = (short *) (hKernelModule + dwNameOrdOffset); 229 | bApiFound = false; 230 | 231 | for (i = 0; i < dwNumberOfNames; i++) 232 | { 233 | if (!strcmp(((DWORD) hKernelModule + (char *) dwNameRVAs[i]), func)) { 234 | bApiFound = true; 235 | break; 236 | } 237 | } 238 | 239 | if (!bApiFound) 240 | { 241 | return 0; 242 | } 243 | i = dwNameOrdRVAs[i]; 244 | return dll + dwFuncRVAs[i]; 245 | } 246 | 247 | char * System::GetAPIbyAddress(unsigned long ptr, unsigned long dll) { 248 | DWORD hKernelModule; 249 | DWORD dwFuncOffset; 250 | DWORD dwNameOrdOffset; 251 | DWORD dwTemp, dwOffsetPE, dwOffsetExport; 252 | int i = 0; 253 | int l = 0; 254 | DWORD dwNumberOfNames, dwNamesOffset; 255 | DWORD * dwNameRVAs; 256 | DWORD * dwFuncRVAs; 257 | short * dwNameOrdRVAs; 258 | bool bApiFound; 259 | char lpszApiName[255]; 260 | 261 | hKernelModule = dll; 262 | if (dll == 0) { 263 | return 0; 264 | } 265 | // cout << (int*)dll << "\n"; 266 | dwOffsetPE = *(DWORD *) ((DWORD) hKernelModule + 0x3C); 267 | dwOffsetExport = *(DWORD *) ((DWORD) hKernelModule + dwOffsetPE + 0x78); 268 | 269 | dwNumberOfNames = *(DWORD *) ((DWORD) hKernelModule + dwOffsetExport + 0x18); 270 | 271 | dwFuncOffset = *(DWORD *) (hKernelModule + dwOffsetExport + 0x1C); 272 | dwNamesOffset = *(DWORD *) ((DWORD) hKernelModule + dwOffsetExport + 0x20); 273 | dwNameOrdOffset = *(DWORD *) ((DWORD) hKernelModule + dwOffsetExport + 0x24); 274 | dwNameRVAs = (DWORD *) (hKernelModule + dwNamesOffset); 275 | dwFuncRVAs = (DWORD *) (hKernelModule + dwFuncOffset); 276 | dwNameOrdRVAs = (short *) (hKernelModule + dwNameOrdOffset); 277 | 278 | bApiFound = false; 279 | 280 | for (i = 0; i < dwNumberOfNames; i++) { 281 | if ((dwFuncRVAs[i]) == (ptr - dll)) { 282 | bApiFound = true; 283 | break; 284 | } 285 | } 286 | if (!bApiFound) { 287 | return 0; 288 | } 289 | for (l = 0; l < dwNumberOfNames; l++) { 290 | if (i == dwNameOrdRVAs[l]) { 291 | i = l; 292 | break; 293 | } 294 | } 295 | return (char *) (dll + dwNameRVAs[i]); 296 | } 297 | 298 | char * System::GetTiggeredAPI(Thread &thread) 299 | { 300 | int entry = 0; 301 | DWORD ptr = thread.Eip; 302 | 303 | for (int i = 0; i < thread.mem->vmem_length; i++) 304 | { 305 | if ((ptr >= thread.mem->vmem[i]->vmem) && (ptr <= (thread.mem->vmem[i]->vmem + thread.mem->vmem[i]->size))) { 306 | ptr -= thread.mem->vmem[i]->vmem; 307 | ptr += thread.mem->vmem[i]->rmem; 308 | entry = i; 309 | break; 310 | } 311 | } 312 | DWORD dllbase = thread.mem->vmem[entry]->rmem; 313 | char * c = GetAPIbyAddress(ptr, dllbase); 314 | return c; 315 | } 316 | 317 | // ----------------------------------------------------------------------------------------------------------------------- 318 | unsigned long System::GetDllBase(char * s) 319 | { 320 | if (s == NULL)return 0; 321 | string str = to_lower_case((char *) s); 322 | 323 | str = str.substr(0, str.size() - 1); // sometimes converted wrong (from char* to string) 324 | for (int i = 0; i < dll_entries; i++) { 325 | string name = DLLs[i].name; 326 | if (!strcmp(str.c_str(), name.c_str())) { 327 | return DLLs[i].imagebase; 328 | } 329 | if (!strcmp(str.c_str(), name.substr(0, str.size()).c_str())) { 330 | return DLLs[i].imagebase; 331 | } 332 | } 333 | return 0; 334 | } 335 | 336 | unsigned long System::GetDllIndex(char * s) 337 | { 338 | if (s == NULL)return 0; 339 | string str = to_lower_case((char *) s); 340 | 341 | for (int i = 0; i < dll_entries; i++) { 342 | string name = DLLs[i].name; 343 | if (!strcmp(str.c_str(), name.c_str())) { 344 | return i; 345 | } 346 | if (!strcmp(str.c_str(), name.substr(0, str.size()).c_str())) { 347 | return i; 348 | } 349 | } 350 | return 0; 351 | } 352 | -------------------------------------------------------------------------------- /pe.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | 21 | #include "os/os.h" 22 | #include "x86emu.h" 23 | #ifdef WIN32 24 | #include 25 | #endif 26 | DWORD align(DWORD src, DWORD Alignment, bool lower) { 27 | DWORD aligned_ptr = src; 28 | 29 | if (src % Alignment != 0) { 30 | if (lower) { 31 | aligned_ptr -= src % Alignment; 32 | } else { 33 | aligned_ptr += Alignment - (src % Alignment); 34 | } 35 | } 36 | return aligned_ptr; 37 | } 38 | 39 | DWORD PELoader(char* buff) 40 | { 41 | long unsigned int size = 0; 42 | image_header * PEHeader; 43 | DWORD FileHandler, PEHeader_ptr; 44 | image_section_header * data; 45 | DWORD imagebase; 46 | FileHandler = (DWORD)buff; 47 | if (!(*((short *) FileHandler) == 0x5a4d)) { 48 | return 0; 49 | } 50 | PEHeader_ptr = ((dos_header *) FileHandler)->e_lfanew + FileHandler; 51 | if (!(*((short *) PEHeader_ptr) == 0x4550)) { 52 | return 0; 53 | } 54 | 55 | PEHeader = (image_header *) PEHeader_ptr; 56 | size = PEHeader->optional.size_of_image; 57 | // -------------------- 58 | // preparing the new place 59 | 60 | #ifdef WIN32 61 | imagebase = (DWORD) VirtualAlloc(NULL, size + 0x1000, MEM_COMMIT, PAGE_READWRITE); // the virtual place 62 | #else 63 | imagebase = (DWORD) malloc(size + 0x1000); // the virtual place 64 | #endif 65 | memset((char *) imagebase, 0, size + 0x1000); // for reconstructing the import table 66 | size = PEHeader->optional.size_of_headers; 67 | memcpy((char *) imagebase, (char *) FileHandler, size); 68 | // ---------------------- 69 | // copying the sections 70 | image_section_header * sections = (image_section_header *) (PEHeader->header.size_of_optional_header + (DWORD) & PEHeader->optional); 71 | for (int i = 0; i < PEHeader->header.number_of_sections; i++) { 72 | DWORD aligned_ptr = align(sections[i].pointer_to_raw_data, PEHeader->optional.file_alignment, true); 73 | DWORD src = aligned_ptr + FileHandler; 74 | DWORD dest = sections[i].virtual_address + imagebase; 75 | size = sections[i].size_of_raw_data; 76 | // cout << "src = "<<(int*)(src-FileHandler) << " dest = "<< (int*)(dest-imagebase+0x00400000)<< " size = "<< (int*)size<< "\n"; 77 | if (sections[i].pointer_to_raw_data != 0) { 78 | memcpy((char *) dest, (char *) src, size); 79 | } 80 | } 81 | return imagebase; 82 | } 83 | DWORD PELoader(string filename) 84 | { 85 | // First we will open the file and read it 86 | long unsigned int size = 0; 87 | FileMapping * rawdata = OpenFile(filename.c_str()); 88 | 89 | // ------------ 90 | // begin the PE parsing 91 | if (rawdata == 0) { 92 | return 0; 93 | } 94 | DWORD imagebase = PELoader((char*)rawdata->BaseAddress); 95 | CloseFile(rawdata); 96 | return imagebase; 97 | } 98 | 99 | DWORD FindAPI(Process * c, DWORD ApiName, DWORD DllHandle, DWORD napi, DWORD ndll, bool defined) { 100 | // getting the important variables from the virtual memory 101 | DWORD ptr = 0; 102 | DWORD dllhandle = 0; 103 | 104 | char * name = (char *) c->SharedMem->read_virtual_mem(ApiName); 105 | 106 | if (defined == true) { 107 | dllhandle = (DWORD) c->SharedMem->read_virtual_mem(DllHandle); 108 | } 109 | if (defined == true) { 110 | ptr = c->getsystem()->GetAPI(name, dllhandle); 111 | } 112 | ptr = c->SharedMem->get_virtual_pointer(ptr); 113 | // cout << "Ptr = "<<(int*)ptr << "\n"; 114 | 115 | if ((ptr == 0) && (defined == true)) { 116 | return 0; 117 | } 118 | // getting the image pointer and size to begin searching 119 | DWORD image = (DWORD) c->SharedMem->read_virtual_mem(c->GetImagebase()); 120 | DWORD PEHeader_ptr = ((dos_header *) image)->e_lfanew + image; 121 | image_header * PEHeader = (image_header *) PEHeader_ptr; 122 | DWORD size = PEHeader->optional.size_of_image; 123 | // create the virtual address that returned from getprocaddress as it's undefined dll 124 | if (defined == false) { 125 | ptr = 0xBBBB0000 + (napi << 8) + ndll; 126 | } 127 | // begin searching 128 | for (int i = 0; i < size - 4; i++) { 129 | DWORD * p = (DWORD *) (image + i); // the place we will test if it contains the address 130 | if (*p == ptr) { 131 | return c->SharedMem->get_virtual_pointer((DWORD) p); 132 | } 133 | } 134 | // we don't found so return zero 135 | return 0; 136 | } 137 | 138 | DWORD ReconstructImportTable(Process * c) { 139 | // creating a new section for the import table 140 | DWORD image = (DWORD) c->SharedMem->read_virtual_mem(c->GetImagebase()); 141 | DWORD PEHeader_ptr = ((dos_header *) image)->e_lfanew + image; 142 | image_header * PEHeader = (image_header *) PEHeader_ptr; 143 | DWORD size = PEHeader->optional.size_of_image; 144 | 145 | PEHeader->header.number_of_sections++; 146 | int i = PEHeader->header.number_of_sections - 1; 147 | image_section_header * sections = (image_section_header *) (PEHeader->header.size_of_optional_header + (DWORD) & PEHeader->optional); 148 | sections[i].name[0] = (char) 'i'; 149 | sections[i].name[1] = (char) 'd'; 150 | sections[i].name[2] = (char) 'a'; 151 | sections[i].name[3] = (char) 't'; 152 | sections[i].name[4] = (char) 'a'; 153 | sections[i].virtual_address = size; 154 | sections[i].pointer_to_raw_data = size; 155 | sections[i].virtual_size = 0x1000; 156 | sections[i].size_of_raw_data = 0x1000; 157 | sections[i].characteristics = 0xE0000040; 158 | PEHeader->optional.size_of_image += 0x1000; 159 | // getting the new section address 160 | image_import_descriptor * sec = (image_import_descriptor *) (sections[i].virtual_address + image); 161 | // parsing the new import table 162 | int nsec = 0; 163 | for (int i = 0; i < c->nimports; i++) { 164 | sec[nsec].name = c->imports[i]->name - c->GetImagebase(); 165 | DWORD x = FindAPI(c, c->imports[i]->apis[0], c->imports[i]->addr, 0, 0, c->imports[i]->defined); 166 | // cout << "1 "<< i << "\n"; 167 | if (x == 0) { 168 | x = FindAPI(c, c->imports[i]->apis[0], c->imports[i]->addr, 0, i, c->imports[i]->defined); 169 | if (x == 0) { 170 | // cout << "Error = "<< (int*)c->imports[i]->apis[0] << "\n"; 171 | continue; 172 | } 173 | } 174 | // cout << "nAPIs = "<imports[i]->napis << "\n"; 175 | DWORD maxAddr = 0, minAddr = 0xFFFFFFFF; 176 | for (int l = 0; l < c->imports[i]->napis; l++) { 177 | DWORD x = FindAPI(c, c->imports[i]->apis[l], c->imports[i]->addr, l, i, c->imports[i]->defined); 178 | // cout << "2 "<< (int*)x << "\n"; 179 | if (x == 0) { 180 | // cout << "Error = "<< (int*)c->imports[i]->apis[l] << "\n"; 181 | break; 182 | } 183 | // cout << "3 "<< l << "\n"; 184 | if (x < minAddr) { 185 | minAddr = x; 186 | } 187 | if (x > maxAddr) { 188 | maxAddr = x; 189 | } 190 | DWORD * thunk = c->SharedMem->read_virtual_mem(x); 191 | // cout << "4 "<< l << "\n"; 192 | *thunk = c->imports[i]->apis[l] - 2 - c->GetImagebase(); 193 | } 194 | DWORD * thunk = c->SharedMem->read_virtual_mem(maxAddr + 4); 195 | *thunk = 0; 196 | sec[nsec].original_first_thunk = minAddr - c->GetImagebase(); 197 | sec[nsec].first_thunk = minAddr - c->GetImagebase(); 198 | nsec++; 199 | } 200 | PEHeader->optional.data_directory[1].virtual_address = ((DWORD) sec) - image; 201 | PEHeader->optional.data_directory[1].size = 0x50; 202 | return 0; 203 | } 204 | 205 | DWORD PEDump(DWORD Eip, Process * c, char * filename) { 206 | // FileMapping* rawdata=OpenFile(filename); 207 | image_header * PEHeader; 208 | DWORD FileHandler, PEHeader_ptr; 209 | image_section_header * data; 210 | 211 | FileHandler = (DWORD) c->SharedMem->read_virtual_mem(c->GetImagebase()); 212 | if (!(*((short *) FileHandler) == 0x5a4d)) { 213 | return 0; 214 | } 215 | PEHeader_ptr = ((dos_header *) FileHandler)->e_lfanew + FileHandler; 216 | if (!(*((short *) PEHeader_ptr) == 0x4550)) { 217 | return 0; 218 | } 219 | PEHeader = (image_header *) PEHeader_ptr; 220 | DWORD size = align(PEHeader->optional.size_of_image, PEHeader->optional.section_alignment, false); 221 | image_section_header * sections = (image_section_header *) (PEHeader->header.size_of_optional_header + (DWORD) & PEHeader->optional); 222 | if (PEHeader->header.number_of_sections != 0) { 223 | for (int i = 0; i < PEHeader->header.number_of_sections - 1; i++) { 224 | sections[i].size_of_raw_data = sections[i + 1].virtual_address - sections[i].virtual_address; 225 | sections[i].pointer_to_raw_data = sections[i].virtual_address; 226 | sections[i].characteristics |= 0x80000000; 227 | //Set The Section that includes Eip to Executable Readonly 228 | if (Eip >= sections[i].virtual_address && Eip < (sections[i].virtual_address + sections[i].virtual_size)) 229 | sections[i].characteristics = 0x60000020; 230 | 231 | // cout << "Section = "<< i << "\n"; 232 | // cout << "Size = "<<(int*)PEHeader->sections[i].size_of_raw_data << "\n"; 233 | // cout << "Pointer = "<< (int*)PEHeader->sections[i].pointer_to_raw_data << "\n"; 234 | } 235 | DWORD index = PEHeader->header.number_of_sections - 1; 236 | if (sections[index].virtual_size != 0) { 237 | sections[index].size_of_raw_data = align(sections[index].virtual_size, PEHeader->optional.section_alignment, false); 238 | } 239 | sections[index].pointer_to_raw_data = sections[index].virtual_address; 240 | sections[index].characteristics |= 0x80000000; 241 | } 242 | // cout << "Section = "<< index << "\n"; 243 | // cout << "Size = "<<(int*)PEHeader->sections[index].size_of_raw_data << "\n"; 244 | // cout << "Pointer = "<< (int*)PEHeader->sections[index].pointer_to_raw_data << "\n"; 245 | 246 | PEHeader->optional.address_of_entry_point = Eip - c->GetImagebase(); 247 | // PEHeader->optional.data_directory[1].virtual_address=0; //delete the import table right now to be fixed by 248 | // PEHeader->optional.data_directory[1].size=0; //another program or manually 249 | FileMapping * rawdata = CreateNewFile((const char *) filename, (unsigned long) size + 0x1000); 250 | if (rawdata != 0) { 251 | if (rawdata->hMapping == 1) { // Linux Writing File 252 | rawdata->BaseAddress = FileHandler; 253 | } else { 254 | memcpy((char *) rawdata->BaseAddress, (char *) FileHandler, size); 255 | } 256 | CloseFile(rawdata); 257 | } 258 | } 259 | 260 | // ------------------------------------------------------------------------------------------------------------------------------- 261 | DWORD UnloadImportTable(Process * c) { 262 | DWORD FileHandler = (DWORD) c->SharedMem->read_virtual_mem(c->GetImagebase()); 263 | image_header * PEHeader = (image_header *) (((dos_header *) FileHandler)->e_lfanew + FileHandler); 264 | image_import_descriptor * Imports = (image_import_descriptor *) (PEHeader->optional.data_directory[1].virtual_address + FileHandler); 265 | 266 | while(1) 267 | { 268 | if ((Imports->original_first_thunk == 0) && (Imports->first_thunk == 0) && (Imports->name == 0)) 269 | { 270 | break; 271 | } 272 | image_import_by_name ** names; // pointer to the names that we will get's address 273 | DWORD * pointers; // pointer to the the place that we will put the addresses there 274 | if (Imports->original_first_thunk == 0) { 275 | return 0; 276 | } 277 | names = (image_import_by_name **) Imports->original_first_thunk; 278 | names = (image_import_by_name **) ((DWORD) names + FileHandler); 279 | pointers = (DWORD *) (Imports->first_thunk + FileHandler); 280 | if (Imports->first_thunk == 0) { 281 | return 0; 282 | } 283 | int i = 0; 284 | while(1) 285 | { 286 | if (names[i] == 0) { 287 | break; 288 | } 289 | memcpy(&pointers[i], &names[i], 4); 290 | i++; 291 | } 292 | Imports = (image_import_descriptor *)((DWORD)Imports + sizeof(image_import_descriptor)); 293 | } 294 | 295 | return 0; 296 | } 297 | DWORD ZeroImportTable(Process * c) 298 | { 299 | DWORD FileHandler = (DWORD) c->SharedMem->read_virtual_mem(c->GetImagebase()); 300 | image_header * PEHeader = (image_header *) (((dos_header *) FileHandler)->e_lfanew + FileHandler); 301 | PEHeader->optional.data_directory[1].virtual_address = 0; //delete the import table right now to be fixed by 302 | PEHeader->optional.data_directory[1].size = 0; 303 | return 0; 304 | } 305 | 306 | // ----------------------------------------------------------------------------------------------------------------------- 307 | -------------------------------------------------------------------------------- /pe.h: -------------------------------------------------------------------------------- 1 | // 2 | // PE Executable file format 3 | // 4 | // Copyright (C) 2002 Michael Ringgaard. All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without 7 | // modification, are permitted provided that the following conditions 8 | // are met: 9 | // 10 | // 1. Redistributions of source code must retain the above copyright 11 | // notice, this list of conditions and the following disclaimer. 12 | // 2. Redistributions in binary form must reproduce the above copyright 13 | // notice, this list of conditions and the following disclaimer in the 14 | // documentation and/or other materials provided with the distribution. 15 | // 3. Neither the name of the project nor the names of its contributors 16 | // may be used to endorse or promote products derived from this software 17 | // without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 23 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 | // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 | // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 | // SUCH DAMAGE. 30 | // 31 | #ifndef PE_H 32 | #define PE_H 33 | #define IMAGE_PE_SIGNATURE 0x00004550 // PE00 34 | // 35 | // DOS image header 36 | // 37 | //#pragma pack(push) 38 | //#pragma pack(1) 39 | struct dos_header 40 | { 41 | unsigned short e_magic; // Magic number 42 | unsigned short e_cblp; // Bytes on last page of file 43 | unsigned short e_cp; // Pages in file 44 | unsigned short e_crlc; // Relocations 45 | unsigned short e_cparhdr; // Size of header in paragraphs 46 | unsigned short e_minalloc; // Minimum extra paragraphs needed 47 | unsigned short e_maxalloc; // Maximum extra paragraphs needed 48 | unsigned short e_ss; // Initial (relative) SS value 49 | unsigned short e_sp; // Initial SP value 50 | unsigned short e_csum; // Checksum 51 | unsigned short e_ip; // Initial IP value 52 | unsigned short e_cs; // Initial (relative) CS value 53 | unsigned short e_lfarlc; // File address of relocation table 54 | unsigned short e_ovno; // Overlay number 55 | unsigned short e_res[4]; // Reserved words 56 | unsigned short e_oemid; // OEM identifier (for e_oeminfo) 57 | unsigned short e_oeminfo; // OEM information; e_oemid specific 58 | unsigned short e_res2[10]; // Reserved words 59 | unsigned long e_lfanew; // File address of new exe header 60 | }; 61 | //#pragma pack(pop) 62 | // 63 | // PE image file header 64 | // 65 | struct image_file_header 66 | { 67 | unsigned short machine; //+4 68 | unsigned short number_of_sections; //+6 69 | unsigned long timestamp; //+8 70 | unsigned long pointer_to_symboltable; //+C 71 | unsigned long number_of_symbols; //+10 72 | unsigned short size_of_optional_header; //+14 73 | unsigned short characteristics; //+16 74 | }; 75 | #define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file 76 | #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references) 77 | #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file 78 | #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file 79 | #define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 // Agressively trim working set 80 | #define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // App can handle >2gb addresses 81 | #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed 82 | #define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine 83 | #define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file 84 | #define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // If Image is on removable media, copy and run from the swap file 85 | #define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // If Image is on Net, copy and run from the swap file 86 | #define IMAGE_FILE_SYSTEM 0x1000 // System File 87 | #define IMAGE_FILE_DLL 0x2000 // File is a DLL 88 | #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // File should only be run on a UP machine 89 | #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed 90 | #define IMAGE_FILE_MACHINE_UNKNOWN 0 91 | #define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386. 92 | // 93 | // Image directory 94 | // 95 | struct image_directory 96 | { 97 | unsigned long virtual_address; 98 | unsigned long size; 99 | }; 100 | #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 101 | #define IMAGE_OPTIONAL_HDR32_MAGIC 0x10B 102 | // 103 | // Optional image header 104 | // 105 | struct image_optional_header 106 | { 107 | unsigned short magic; //+18 108 | unsigned char major_linker_version; //+1A 109 | unsigned char minor_linker_version; //+1B 110 | unsigned long size_of_code; //+1C 111 | unsigned long size_of_initialized_data; //+20 112 | unsigned long size_of_uninitialized_data; //+24 113 | unsigned long address_of_entry_point; //+28 114 | unsigned long base_of_code; //+2C 115 | unsigned long base_of_data; //+30 116 | unsigned long image_base; //+34 117 | unsigned long section_alignment; //+38 118 | unsigned long file_alignment; //+3C 119 | unsigned short major_operating_system_version; //+40 120 | unsigned short minor_operating_system_version; //+42 121 | unsigned short major_image_version; //+44 122 | unsigned short minor_image_version; //+46 123 | unsigned short major_subsystem_version; //+48 124 | unsigned short minor_subsystem_version; //+4A 125 | unsigned long win32_version_value; //+4C 126 | unsigned long size_of_image; //+50 127 | unsigned long size_of_headers; //+54 128 | unsigned long checksum; //+58 129 | unsigned short subsystem; //+5C 130 | unsigned short dll_characteristics; //+5E 131 | unsigned long size_of_stack_reserve; //+60 132 | unsigned long size_of_stack_commit; //+64 133 | unsigned long size_of_heap_reserve; //+68 134 | unsigned long size_of_heap_commit; //+6C 135 | unsigned long loader_flags; //+70 136 | unsigned long number_of_rva_and_sizes; //+74 137 | struct image_directory data_directory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; 138 | }; 139 | #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory //+78 140 | #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory //+80 141 | #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory //+88 142 | #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory 143 | #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory 144 | #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table 145 | #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory 146 | #define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage) 147 | #define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data 148 | #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP 149 | #define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory 150 | #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory 151 | #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers 152 | #define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table 153 | #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors 154 | #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor 155 | // 156 | // Image section header 157 | // 158 | #define IMAGE_SIZEOF_SHORT_NAME 8 159 | struct image_section_header 160 | { 161 | char name[IMAGE_SIZEOF_SHORT_NAME]; //+00 162 | unsigned long virtual_size; //+08 163 | unsigned long virtual_address; //+0C 164 | unsigned long size_of_raw_data; //+10 165 | unsigned long pointer_to_raw_data; //+14 166 | unsigned long pointer_to_relocations; //+18 167 | unsigned long pointer_to_linenumbers; //+1C 168 | unsigned short number_of_relocations; //+20 169 | unsigned short number_of_linenumbers; //+22 170 | unsigned long characteristics; //+24 171 | }; //Size=28 172 | // 173 | // Section characteristics 174 | // 175 | #define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. 176 | #define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. 177 | #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. 178 | #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data. 179 | #define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. 180 | #define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. 181 | #define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. 182 | #define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat. 183 | #define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 // Reset speculative exceptions handling bits in the TLB entries for this section. 184 | #define IMAGE_SCN_GPREL 0x00008000 // Section content can be accessed relative to GP 185 | #define IMAGE_SCN_MEM_FARDATA 0x00008000 186 | #define IMAGE_SCN_MEM_PURGEABLE 0x00020000 187 | #define IMAGE_SCN_MEM_16BIT 0x00020000 188 | #define IMAGE_SCN_MEM_LOCKED 0x00040000 189 | #define IMAGE_SCN_MEM_PRELOAD 0x00080000 190 | #define IMAGE_SCN_ALIGN_1BYTES 0x00100000 // 191 | #define IMAGE_SCN_ALIGN_2BYTES 0x00200000 // 192 | #define IMAGE_SCN_ALIGN_4BYTES 0x00300000 // 193 | #define IMAGE_SCN_ALIGN_8BYTES 0x00400000 // 194 | #define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified. 195 | #define IMAGE_SCN_ALIGN_32BYTES 0x00600000 // 196 | #define IMAGE_SCN_ALIGN_64BYTES 0x00700000 // 197 | #define IMAGE_SCN_ALIGN_128BYTES 0x00800000 // 198 | #define IMAGE_SCN_ALIGN_256BYTES 0x00900000 // 199 | #define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 // 200 | #define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 // 201 | #define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 // 202 | #define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 // 203 | #define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 // 204 | #define IMAGE_SCN_ALIGN_MASK 0x00F00000 205 | #define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 // Section contains extended relocations. 206 | #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded. 207 | #define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable. 208 | #define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable. 209 | #define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable. 210 | #define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable. 211 | #define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable. 212 | #define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable. 213 | // 214 | // 215 | // Combined image header 216 | // 217 | struct image_header 218 | { 219 | unsigned long signature; 220 | struct image_file_header header; 221 | struct image_optional_header optional; 222 | struct image_section_header sections[1]; 223 | }; 224 | 225 | // 226 | // Based relocation format 227 | // 228 | struct image_base_relocation 229 | { 230 | unsigned long virtual_address; 231 | unsigned long size_of_block; 232 | }; 233 | // 234 | // Based relocation types. 235 | // 236 | #define IMAGE_REL_BASED_ABSOLUTE 0 237 | #define IMAGE_REL_BASED_HIGH 1 238 | #define IMAGE_REL_BASED_LOW 2 239 | #define IMAGE_REL_BASED_HIGHLOW 3 240 | #define IMAGE_REL_BASED_HIGHADJ 4 241 | #define IMAGE_REL_BASED_MIPS_JMPADDR 5 242 | #define IMAGE_REL_BASED_SECTION 6 243 | #define IMAGE_REL_BASED_REL32 7 244 | // 245 | // Export Format 246 | // 247 | #define IMAGE_ORDINAL_FLAG 0x80000000 248 | struct image_export_directory 249 | { 250 | unsigned long characteristics; //+00 251 | unsigned long timestamp; //+04 252 | unsigned short major_version; //+08 253 | unsigned short minor_version; //+0A 254 | unsigned long name; //+0C 255 | unsigned long base; //+10 256 | unsigned long number_of_functions; //+14 257 | unsigned long number_of_names; //+18 258 | unsigned long address_of_functions; //+1C // RVA from base of image 259 | unsigned long address_of_names; //+20 // RVA from base of image 260 | unsigned long address_of_name_ordinals; //+24 // RVA from base of image 261 | }; 262 | // 263 | // Import Format 264 | // 265 | struct image_import_by_name 266 | { 267 | unsigned short hint; 268 | char name[1]; 269 | }; 270 | struct image_import_descriptor 271 | { 272 | union // +00 273 | { 274 | unsigned long characteristics; // 0 for terminating null import descriptor 275 | unsigned long original_first_thunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA) 276 | }; 277 | unsigned long timestamp; // +04 278 | unsigned long forwarder_chain; // -1 if no forwarders +08 279 | unsigned long name; // +0C 280 | unsigned long first_thunk; // RVA to IAT (if bound this IAT has actual addresses) +10 281 | }; 282 | struct image_bound_import_descriptor 283 | { 284 | unsigned long timestamp; 285 | unsigned short offset_module_name; 286 | unsigned short number_of_module_forwarder_refs; 287 | // array of zero or more struct image_bound_forwarder_ref follows 288 | }; 289 | struct image_bound_forwarder_ref 290 | { 291 | unsigned long timestamp; 292 | unsigned short offset_module_name; 293 | unsigned short reserved; 294 | }; 295 | // 296 | // Resource Format 297 | // 298 | struct image_resource_directory 299 | { 300 | unsigned long characteristics; 301 | unsigned long timestamp; 302 | unsigned short major_version; 303 | unsigned short minor_version; 304 | unsigned short number_of_named_entries; 305 | unsigned short number_of_id_entries; 306 | // struct image_resource_directory_entry directoryentries[]; 307 | }; 308 | #define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000 309 | #define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000 310 | struct image_resource_directory_entry 311 | { 312 | union 313 | { 314 | struct 315 | { 316 | unsigned long name_offset : 31; 317 | unsigned long name_is_string : 1; 318 | }; 319 | unsigned long name; 320 | unsigned short id; 321 | }; 322 | union 323 | { 324 | unsigned long offset_to_data; 325 | struct 326 | { 327 | unsigned long offset_to_directory : 31; 328 | unsigned long data_is_directory : 1; 329 | }; 330 | }; 331 | }; 332 | struct image_resource_directory_string 333 | { 334 | unsigned short length; 335 | char name_string[1]; 336 | }; 337 | struct image_resource_data_entry 338 | { 339 | unsigned long offset_to_data; 340 | unsigned long size; 341 | unsigned long codepage; 342 | unsigned long reserved; 343 | }; 344 | #define TLS_MAGIC 0xABABABAB 345 | struct _IMAGE_TLS_DIRECTORY { 346 | unsigned long StartAddressOfRawData; 347 | unsigned long EndAddressOfRawData; 348 | unsigned long* AddressOfIndex; 349 | unsigned long* AddressOfCallBacks; 350 | unsigned long SizeOfZeroFill; 351 | unsigned long Characteristics; 352 | }; 353 | //typedef void (MODENTRY *PIMAGE_TLS_CALLBACK) ( PTR DllHandle, UINT32 Reason, PTR Reserved ); 354 | #endif 355 | -------------------------------------------------------------------------------- /emu/jmps.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (C) 2010-2011 Amr Thabet 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to Amr Thabet 17 | * amr.thabet@student.alx.edu.eg 18 | * 19 | */ 20 | #include "../x86emu.h" 21 | 22 | // this file for emulating the jmps and push &pop to stack 23 | 24 | // PUSH & POP 25 | int op_push(Thread & thread, DISASM_INSTRUCTION * s) { 26 | int dest = 0; 27 | 28 | if (s->flags & DEST_IMM) { 29 | if (s->hde.flags & F_IMM8 && (s->ndest & 0x80)) { 30 | s->ndest += 0xFFFFFF00; 31 | } 32 | dest = s->ndest; 33 | } else if (s->flags & DEST_REG) { 34 | int dest2 = thread.Exx[s->ndest]; 35 | if (s->flags & DEST_BITS32) { 36 | memcpy(&dest, &dest2, 4); 37 | } 38 | if (s->flags & DEST_BITS16) { 39 | memcpy(&dest, &dest2, 2); 40 | } 41 | if (s->flags & DEST_BITS8) { 42 | memcpy(&dest, &dest2, 1); 43 | } 44 | } else if (s->flags & DEST_RM) { 45 | DWORD * ptr; 46 | EMU_READ_MEM(ptr, (DWORD) modrm_calc(thread, s)); 47 | if (s->flags & DEST_BITS32) { 48 | memcpy(&dest, ptr, 4); 49 | } 50 | if (s->flags & DEST_BITS16) { 51 | memcpy(&dest, ptr, 2); 52 | } 53 | if (s->flags & DEST_BITS8) { 54 | memcpy(&dest, ptr, 1); 55 | } 56 | } 57 | if (s->hde.flags & F_PREFIX_66) { 58 | EMU_WRITE_MEM(thread.Exx[4] - 2, (DWORD) 2, (unsigned char *) &dest); 59 | thread.Exx[4] -= 2; 60 | } else { 61 | thread.stack->push(dest); 62 | } 63 | // cout << "src = " << dest << "\n"; 64 | return 0; 65 | } 66 | 67 | // --------------- 68 | int op_pop(Thread & thread, DISASM_INSTRUCTION * s) { 69 | DWORD src; 70 | 71 | if (s->hde.flags & F_PREFIX_66) { 72 | DWORD * src2; 73 | EMU_READ_MEM(src2, thread.Exx[4]); 74 | src = (DWORD) src2; 75 | thread.Exx[4] += 2; 76 | } else { 77 | src = (DWORD) thread.stack->pop(); 78 | } 79 | DWORD dest, result; 80 | if (s->flags & DEST_REG) { 81 | dest = thread.Exx[s->ndest]; 82 | // thread.Exx[s->ndest]=src; 83 | if (s->flags & DEST_BITS32) { 84 | memcpy(&thread.Exx[s->ndest], &src, 4); 85 | } 86 | if (s->flags & DEST_BITS16) { 87 | memcpy(&thread.Exx[s->ndest], &src, 2); 88 | } 89 | if (s->flags & DEST_BITS8) { 90 | memcpy(&thread.Exx[s->ndest], &src, 1); 91 | } 92 | result = thread.Exx[s->ndest]; 93 | } else if (s->flags & DEST_RM) { 94 | DWORD * ptr; 95 | EMU_READ_MEM(ptr, (DWORD) modrm_calc(thread, s)); 96 | dest = *ptr; 97 | if (s->flags & DEST_BITS32) { 98 | DWORD n = src; 99 | EMU_WRITE_MEM((DWORD) modrm_calc(thread, s), (DWORD) 4, (unsigned char *) &n); 100 | } 101 | if (s->flags & DEST_BITS16) { 102 | unsigned short n = src; 103 | EMU_WRITE_MEM((DWORD) modrm_calc(thread, s), (DWORD) 2, (unsigned char *) &n); 104 | } 105 | if (s->flags & DEST_BITS8) { 106 | unsigned char n = src; 107 | EMU_WRITE_MEM((DWORD) modrm_calc(thread, s), (DWORD) 1, (unsigned char *) &n); 108 | } 109 | result = *ptr; 110 | } 111 | return 0; 112 | } 113 | 114 | // ---------------------------------------------------------------------------------------- 115 | // PUSHAD & POPAD 116 | int op_pushad(Thread & thread, DISASM_INSTRUCTION * s) { 117 | for (int i = 0; i < 8; i++) { 118 | thread.stack->push(thread.Exx[i]); 119 | } 120 | return 0; 121 | } 122 | 123 | int op_popad(Thread & thread, DISASM_INSTRUCTION * s) { 124 | for (int i = 7; i >= 0; i--) { 125 | if (i != 4) { 126 | thread.Exx[i] = thread.stack->pop(); 127 | } else { 128 | thread.stack->pop(); 129 | } 130 | } 131 | return 0; 132 | } 133 | 134 | // ---------------------------------------------------------------------------------------- 135 | // PUSHFD & POPFD 136 | int op_pushfd(Thread & thread, DISASM_INSTRUCTION * s) { 137 | thread.stack->push(thread.EFlags); 138 | return 0; 139 | } 140 | 141 | int op_popfd(Thread & thread, DISASM_INSTRUCTION * s) { 142 | thread.EFlags = thread.stack->pop(); 143 | return 0; 144 | } 145 | 146 | // ---------------------------------------------------------------------------------------- 147 | int op_enter(Thread & thread, DISASM_INSTRUCTION * s) { 148 | thread.stack->push(thread.Exx[5]); 149 | thread.Exx[5] = thread.Exx[4]; 150 | for (int i = 0; i < s->nsrc; i++) { 151 | thread.stack->push(thread.Exx[5]); 152 | thread.Exx[5] = thread.Exx[4]; 153 | } 154 | thread.Exx[4] -= s->ndest; 155 | // thread.Eip=thread.stack->pop(); 156 | return 0; 157 | } 158 | 159 | // ---------------------------------------------------------------------------------------- 160 | int op_leave(Thread & thread, DISASM_INSTRUCTION * s) { 161 | thread.Exx[4] = thread.Exx[5]; 162 | DWORD src = (DWORD) thread.stack->pop(); 163 | memcpy(&thread.Exx[5], &src, 4); 164 | // thread.Eip=thread.stack->pop(); 165 | return 0; 166 | } 167 | 168 | // ============================================================================================================= 169 | // JCC 170 | int op_jcc(Thread & thread, DISASM_INSTRUCTION * s) { 171 | int dest = 0; 172 | bool rel = false; 173 | 174 | if (s->flags & DEST_IMM) { 175 | dest = s->ndest; 176 | // converting the negative imm8 to negative imm32 177 | if ((s->flags & DEST_BITS8) && ((dest >> 7) == 1)) { 178 | dest += 0xFFFFFF00; 179 | } 180 | rel = true; // that's mean that the dest will be added to or subtracted from the eip of the thread 181 | } else if (s->flags & DEST_REG) { 182 | dest = thread.Exx[s->ndest]; 183 | } else if (s->flags & DEST_RM) { 184 | DWORD * ptr; 185 | EMU_READ_MEM(ptr, (DWORD) modrm_calc(thread, s)); 186 | memcpy(&dest, ptr, 4); 187 | } 188 | // now we have the offset and now we need to chack if we will jump to it or not 189 | // cout <opcode->substr(0,s->opcode->size()) <<"\n"; 190 | if (s->opcode->substr(0, s->opcode->size()).compare("jmp") == 0) { 191 | goto Yes_JmptoIt; 192 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("ja") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("jnbe") == 0)) { 193 | if (!(thread.EFlags & EFLG_CF) && !(thread.EFlags & EFLG_ZF)) { 194 | goto Yes_JmptoIt; 195 | } 196 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("jae") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("jnb") == 0)) { 197 | if (!(thread.EFlags & EFLG_CF)) { 198 | goto Yes_JmptoIt; 199 | } 200 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("jnae") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("jb") == 0)) { 201 | if (thread.EFlags & EFLG_CF) { 202 | goto Yes_JmptoIt; 203 | } 204 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("jbe") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("jna") == 0)) { 205 | if ((thread.EFlags & EFLG_CF) || (thread.EFlags & EFLG_ZF)) { 206 | goto Yes_JmptoIt; 207 | } 208 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("je") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("jz") == 0)) { 209 | if (thread.EFlags & EFLG_ZF) { 210 | goto Yes_JmptoIt; 211 | } 212 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("jne") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("jnz") == 0)) { 213 | if (!(thread.EFlags & EFLG_ZF)) { 214 | goto Yes_JmptoIt; 215 | } 216 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("jnp") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("jpo") == 0)) { 217 | if (!(thread.EFlags & EFLG_PF)) { 218 | goto Yes_JmptoIt; 219 | } 220 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("jp") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("jpe") == 0)) { 221 | if (thread.EFlags & EFLG_PF) { 222 | goto Yes_JmptoIt; 223 | } 224 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("jg") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("jnle") == 0)) { 225 | if (!(thread.EFlags & EFLG_SF) ^ (thread.EFlags & EFLG_OF) && !(thread.EFlags & EFLG_ZF)) { 226 | goto Yes_JmptoIt; 227 | } 228 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("jnge") == 0) || (s->opcode->substr(0, s->opcode->size()) .compare("jl") == 0)) { 229 | if ((thread.EFlags & EFLG_SF) ^ (thread.EFlags & EFLG_OF)) { 230 | goto Yes_JmptoIt; 231 | } 232 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("jge") == 0) || (s->opcode->substr(0, s->opcode->size()) .compare("jnl") == 0)) { 233 | if (!((thread.EFlags & EFLG_SF) ^ (thread.EFlags & EFLG_OF))) { 234 | goto Yes_JmptoIt; // not SF xor OF as 1 xor 1 == jump 235 | } 236 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("jle") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("jng") == 0)) { 237 | if ((thread.EFlags & EFLG_SF) ^ (thread.EFlags & EFLG_OF) || (thread.EFlags & EFLG_ZF)) { 238 | goto Yes_JmptoIt; 239 | } 240 | } else if (s->opcode->substr(0, s->opcode->size()).compare("jns") == 0) { 241 | if (!(thread.EFlags & EFLG_SF)) { 242 | goto Yes_JmptoIt; 243 | } 244 | } else if (s->opcode->substr(0, s->opcode->size()).compare("js") == 0) { 245 | if (thread.EFlags & EFLG_SF) { 246 | goto Yes_JmptoIt; 247 | } 248 | } else if (s->opcode->substr(0, s->opcode->size()).compare("jno") == 0) { 249 | if (!(thread.EFlags & EFLG_OF)) { 250 | goto Yes_JmptoIt; 251 | } 252 | } else if (s->opcode->substr(0, s->opcode->size()).compare("jo") == 0) { 253 | if (thread.EFlags & EFLG_OF) { 254 | goto Yes_JmptoIt; 255 | } 256 | } else if ((s->hde.opcode == 0xE3) && !(s->hde.flags & F_PREFIX_67)) { 257 | if (thread.Exx[1] == 0) { 258 | goto Yes_JmptoIt; 259 | } 260 | } else if ((s->hde.opcode == 0xE3) && (s->hde.flags & F_PREFIX_67)) { 261 | if ((thread.Exx[1] & 0xffff) == 0) { 262 | goto Yes_JmptoIt; 263 | } 264 | } else if (s->opcode->substr(0, s->opcode->size()).compare("loop") == 0) { 265 | thread.Exx[1]--; 266 | if (thread.Exx[1] != 0) { 267 | goto Yes_JmptoIt; 268 | } 269 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("loope") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("loopz") == 0)) { 270 | thread.Exx[1]--; 271 | if (thread.EFlags & EFLG_ZF && (thread.Exx[1] != 0)) { 272 | goto Yes_JmptoIt; 273 | } 274 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("loopne") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("loopnz") == 0)) { 275 | thread.Exx[1]--; 276 | if (!(thread.EFlags & EFLG_ZF) && (thread.Exx[1] != 0)) { 277 | goto Yes_JmptoIt; 278 | } 279 | } 280 | 281 | return 0; 282 | Yes_JmptoIt: 283 | if (rel) { 284 | thread.Eip = (DWORD) ((signed int) thread.Eip + (signed int) dest); 285 | } else { 286 | thread.Eip = dest; // - s->hde.len; 287 | } 288 | 289 | return 0; 290 | } 291 | 292 | // ============================================================================================================= 293 | // SETCC 294 | int op_setcc(Thread & thread, DISASM_INSTRUCTION * s) { 295 | unsigned char * ptr = 0; 296 | bool rel = false; 297 | 298 | if (s->flags & DEST_REG) { 299 | if (s->ndest < 3) { 300 | ptr = (unsigned char *) &thread.Exx[s->ndest]; 301 | } else { 302 | ptr = (unsigned char *) &thread.Exx[s->ndest - 4]; 303 | ptr++; 304 | } 305 | } else if (s->flags & DEST_RM) { 306 | DWORD * ptr2; 307 | EMU_READ_MEM(ptr2, (DWORD) modrm_calc(thread, s)); 308 | ptr = (unsigned char *) ptr2; 309 | } 310 | // now we have the offset and now we need to chack if we will jump to it or not 311 | // cout <opcode->substr(0,s->opcode->size()) <<"\n"; 312 | if ((s->opcode->substr(0, s->opcode->size()).compare("seta") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("setnbe") == 0)) { 313 | if (!(thread.EFlags & EFLG_CF) && !(thread.EFlags & EFLG_ZF)) { 314 | goto Yes_JmptoIt; 315 | } 316 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("setae") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("setnb") == 0)) { 317 | if (!(thread.EFlags & EFLG_CF)) { 318 | goto Yes_JmptoIt; 319 | } 320 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("setnae") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("setb") == 0)) { 321 | if (thread.EFlags & EFLG_CF) { 322 | goto Yes_JmptoIt; 323 | } 324 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("setbe") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("setna") == 0)) { 325 | if ((thread.EFlags & EFLG_CF) || (thread.EFlags & EFLG_ZF)) { 326 | goto Yes_JmptoIt; 327 | } 328 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("sete") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("setz") == 0)) { 329 | if (thread.EFlags & EFLG_ZF) { 330 | goto Yes_JmptoIt; 331 | } 332 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("setne") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("setnz") == 0)) { 333 | if (!(thread.EFlags & EFLG_ZF)) { 334 | goto Yes_JmptoIt; 335 | } 336 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("setnp") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("setpo") == 0)) { 337 | if (!(thread.EFlags & EFLG_PF)) { 338 | goto Yes_JmptoIt; 339 | } 340 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("setp") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("setpe") == 0)) { 341 | if (thread.EFlags & EFLG_PF) { 342 | goto Yes_JmptoIt; 343 | } 344 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("setg") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("setnle") == 0)) { 345 | if (!(thread.EFlags & EFLG_SF) ^ (thread.EFlags & EFLG_OF) && !(thread.EFlags & EFLG_ZF)) { 346 | goto Yes_JmptoIt; 347 | } 348 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("setnge") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("setl") == 0)) { 349 | if ((thread.EFlags & EFLG_SF) ^ (thread.EFlags & EFLG_OF)) { 350 | goto Yes_JmptoIt; 351 | } 352 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("setge") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("setnl") == 0)) { 353 | if (!((thread.EFlags & EFLG_SF) ^ (thread.EFlags & EFLG_OF))) { 354 | goto Yes_JmptoIt; // not SF xor OF as 1 xor 1 == set 355 | } 356 | } else if ((s->opcode->substr(0, s->opcode->size()).compare("setle") == 0) || (s->opcode->substr(0, s->opcode->size()).compare("setng") == 0)) { 357 | if ((thread.EFlags & EFLG_SF) ^ (thread.EFlags & EFLG_OF) || (thread.EFlags & EFLG_ZF)) { 358 | goto Yes_JmptoIt; 359 | } 360 | } else if (s->opcode->substr(0, s->opcode->size()).compare("setns") == 0) { 361 | if (!(thread.EFlags & EFLG_SF)) { 362 | goto Yes_JmptoIt; 363 | } 364 | } else if (s->opcode->substr(0, s->opcode->size()).compare("sets") == 0) { 365 | if (thread.EFlags & EFLG_SF) { 366 | goto Yes_JmptoIt; 367 | } 368 | } else if (s->opcode->substr(0, s->opcode->size()).compare("setno") == 0) { 369 | if (!(thread.EFlags & EFLG_OF)) { 370 | goto Yes_JmptoIt; 371 | } 372 | } else if (s->opcode->substr(0, s->opcode->size()).compare("seto") == 0) { 373 | if (thread.EFlags & EFLG_OF) { 374 | goto Yes_JmptoIt; 375 | } 376 | } else if ((s->hde.opcode == 0xE3) && !(s->hde.flags & F_PREFIX_67)) { 377 | if (thread.Exx[1] == 0) { 378 | goto Yes_JmptoIt; 379 | } 380 | } else if ((s->hde.opcode == 0xE3) && (s->hde.flags & F_PREFIX_67)) { 381 | if ((thread.Exx[1] & 0xffff) == 0) { 382 | goto Yes_JmptoIt; 383 | } 384 | } 385 | 386 | return 0; 387 | Yes_JmptoIt: 388 | cout << (int *) ptr << "\n"; 389 | cout << (int *) *ptr << "\n"; 390 | *ptr = 1; 391 | 392 | return 0; 393 | } 394 | 395 | // ============================================================================================================= 396 | // CALL 397 | int op_call(Thread & thread, DISASM_INSTRUCTION * s) { 398 | int dest = 0; 399 | bool rel = false; 400 | 401 | if (s->flags & DEST_IMM) { 402 | dest = s->ndest; 403 | rel = true; // that's mean that the dest will be added to or subtracted from the eip of the thread 404 | } else if (s->flags & DEST_REG) { 405 | dest = thread.Exx[s->ndest]; 406 | } else if (s->flags & DEST_RM) { 407 | DWORD * ptr; 408 | EMU_READ_MEM(ptr, (DWORD) modrm_calc(thread, s)); 409 | memcpy(&dest, ptr, 4); 410 | } 411 | // push the pointer to the next instruction 412 | // we work here as the process increase the eip before emulating the instruction so the eip now pointing to the next instruction 413 | thread.stack->push(thread.Eip); 414 | if (rel) { 415 | thread.Eip = (DWORD) ((signed int) thread.Eip + (signed int) dest); // - s->hde.len+1; 416 | } else { 417 | thread.Eip = dest; // we subtract it because the process::emulate will add it again 418 | } 419 | return 0; 420 | } 421 | 422 | // ============================================================================================================= 423 | // RET 424 | int op_ret(Thread & thread, DISASM_INSTRUCTION * s) { 425 | int bf = 0; 426 | int dest = 0; 427 | 428 | // this for the parameters of the function 429 | thread.Eip = thread.stack->pop(); 430 | if (s->flags & DEST_IMM) { 431 | thread.Exx[4] += s->ndest; 432 | } 433 | if ((thread.Eip == TLS_MAGIC) && thread.still_tls) { 434 | thread.TLSContinue(); 435 | } 436 | if (thread.Eip == SEH_MAGIC) { 437 | thread.sehReturn(); 438 | } 439 | return 0; 440 | } 441 | --------------------------------------------------------------------------------