├── 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 |
--------------------------------------------------------------------------------