添加项目文件。
This commit is contained in:
60
.vscode/settings.json
vendored
Normal file
60
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"iostream": "cpp",
|
||||
"xstring": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"exception": "cpp",
|
||||
"fstream": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"ios": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"istream": "cpp",
|
||||
"iterator": "cpp",
|
||||
"limits": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"memory": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"set": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"string": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"utility": "cpp",
|
||||
"vector": "cpp",
|
||||
"xfacet": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xiosbase": "cpp",
|
||||
"xlocale": "cpp",
|
||||
"xlocinfo": "cpp",
|
||||
"xlocmon": "cpp",
|
||||
"xlocnum": "cpp",
|
||||
"xloctime": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xstddef": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xtree": "cpp",
|
||||
"xutility": "cpp"
|
||||
}
|
||||
}
|
||||
31
ai_anti_malware.sln
Normal file
31
ai_anti_malware.sln
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.35731.53
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ai_anti_malware", "ai_anti_malware\ai_anti_malware.vcxproj", "{E12C93D6-6150-484D-85E1-7A644E393D5A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E12C93D6-6150-484D-85E1-7A644E393D5A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E12C93D6-6150-484D-85E1-7A644E393D5A}.Debug|x64.Build.0 = Debug|x64
|
||||
{E12C93D6-6150-484D-85E1-7A644E393D5A}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{E12C93D6-6150-484D-85E1-7A644E393D5A}.Debug|x86.Build.0 = Debug|Win32
|
||||
{E12C93D6-6150-484D-85E1-7A644E393D5A}.Release|x64.ActiveCfg = Release|x64
|
||||
{E12C93D6-6150-484D-85E1-7A644E393D5A}.Release|x64.Build.0 = Release|x64
|
||||
{E12C93D6-6150-484D-85E1-7A644E393D5A}.Release|x86.ActiveCfg = Release|Win32
|
||||
{E12C93D6-6150-484D-85E1-7A644E393D5A}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {4B304E25-0491-4346-8FCB-7E30DDEB2E43}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
48
ai_anti_malware/ai_anti_malware.cpp
Normal file
48
ai_anti_malware/ai_anti_malware.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
// ai_anti_malware.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
|
||||
//
|
||||
|
||||
#include "head.h"
|
||||
|
||||
auto getPeInfo(std::string inputFilePath) -> std::shared_ptr<BasicPeInfo> {
|
||||
auto sampleInfo = std::make_shared<BasicPeInfo>();
|
||||
sampleInfo->inputFilePath =
|
||||
"E:\\对战平台\\CrowAntiCheat\\CrowAntiCheat\\client\\Console_"
|
||||
"Test\\Release\\Console_Test.exe";
|
||||
|
||||
sampleInfo->peBuffer =
|
||||
peconv::load_pe_module((const char*)sampleInfo->inputFilePath.c_str(),
|
||||
sampleInfo->peSize, false, false);
|
||||
sampleInfo->ntHead64 = peconv::get_nt_hdrs64((BYTE*)sampleInfo->peBuffer);
|
||||
sampleInfo->ntHead32 = peconv::get_nt_hdrs32((BYTE*)sampleInfo->peBuffer);
|
||||
sampleInfo->isX64 = peconv::is64bit((BYTE*)sampleInfo->peBuffer);
|
||||
sampleInfo->RecImageBase =
|
||||
sampleInfo->isX64
|
||||
? (DWORD64)sampleInfo->ntHead64->OptionalHeader.ImageBase
|
||||
: (DWORD)sampleInfo->ntHead32->OptionalHeader.ImageBase;
|
||||
sampleInfo->isRelocated = peconv::relocate_module(
|
||||
(BYTE*)sampleInfo->peBuffer, sampleInfo->peSize, sampleInfo->RecImageBase);
|
||||
|
||||
sampleInfo->entryPoint =
|
||||
sampleInfo->isX64
|
||||
? sampleInfo->ntHead64->OptionalHeader.AddressOfEntryPoint
|
||||
: sampleInfo->ntHead32->OptionalHeader.AddressOfEntryPoint;
|
||||
sampleInfo->imageEnd =
|
||||
sampleInfo->RecImageBase +
|
||||
(sampleInfo->isX64 ? sampleInfo->ntHead64->OptionalHeader.SizeOfImage
|
||||
: sampleInfo->ntHead32->OptionalHeader.SizeOfImage);
|
||||
return sampleInfo;
|
||||
}
|
||||
int main() {
|
||||
auto sampleInfo = getPeInfo(
|
||||
"E:\\对战平台\\CrowAntiCheat\\CrowAntiCheat\\client\\Console_"
|
||||
"Test\\Release\\Console_Test.exe");
|
||||
printf("input new file %s \n", sampleInfo->inputFilePath);
|
||||
printf("is x64: %d\n", sampleInfo->isX64);
|
||||
printf("is relocated: %d\n", sampleInfo->isRelocated);
|
||||
printf("RecImageBase: %llx\n", sampleInfo->RecImageBase);
|
||||
auto sandbox = std::make_shared<Sandbox>();
|
||||
sandbox->InitEnv(sampleInfo);
|
||||
sandbox->Run();
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
187
ai_anti_malware/ai_anti_malware.vcxproj
Normal file
187
ai_anti_malware/ai_anti_malware.vcxproj
Normal file
@@ -0,0 +1,187 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{e12c93d6-6150-484d-85e1-7a644e393d5a}</ProjectGuid>
|
||||
<RootNamespace>aiantimalware</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(SolutionDir)ai_anti_malware\libpeconv\libpeconv\;$(SolutionDir)ai_anti_malware\libpeconv\libpeconv\include;$(SolutionDir)ai_anti_malware\libpeconv\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ai_anti_malware.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\buffer_util.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\caves.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\delayed_imports_loader.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\exported_func.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\exports_lookup.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\exports_mapper.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\file_util.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\find_base.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\fix_dot_net_ep.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\fix_imports.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\function_resolver.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\hooks.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\imports_loader.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\imports_uneraser.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\load_config_util.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\peb_lookup.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\pe_dumper.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\pe_hdrs_helper.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\pe_loader.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\pe_mode_detector.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\pe_raw_to_virtual.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\pe_virtual_to_raw.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\relocate.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\remote_pe_reader.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\resource_parser.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\resource_util.cpp" />
|
||||
<ClCompile Include="libpeconv\libpeconv\src\util.cpp" />
|
||||
<ClCompile Include="sandbox.cpp" />
|
||||
<ClCompile Include="sandbox_callbacks.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="head.h" />
|
||||
<ClInclude Include="libpeconv\libpeconv\src\fix_dot_net_ep.h" />
|
||||
<ClInclude Include="libpeconv\libpeconv\src\ntddk.h" />
|
||||
<ClInclude Include="native_struct.h" />
|
||||
<ClInclude Include="sandbox.h" />
|
||||
<ClInclude Include="sandbox_callbacks.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
138
ai_anti_malware/ai_anti_malware.vcxproj.filters
Normal file
138
ai_anti_malware/ai_anti_malware.vcxproj.filters
Normal file
@@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="源文件\sandbox">
|
||||
<UniqueIdentifier>{9204f3c4-f3df-47b3-9cfc-42fcc5dd6ca9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="头文件\sandbox">
|
||||
<UniqueIdentifier>{41d9dd76-a1a6-4627-b982-cbdb41cf0f7b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="头文件\libpe">
|
||||
<UniqueIdentifier>{38ea362d-55dc-410e-92f1-3a44ced4dc2d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ai_anti_malware.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sandbox.cpp">
|
||||
<Filter>源文件\sandbox</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\buffer_util.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\caves.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\delayed_imports_loader.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\exported_func.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\exports_lookup.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\exports_mapper.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\file_util.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\find_base.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\fix_dot_net_ep.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\fix_imports.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\function_resolver.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\hooks.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\imports_loader.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\imports_uneraser.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\load_config_util.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\pe_dumper.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\pe_hdrs_helper.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\pe_loader.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\pe_mode_detector.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\pe_raw_to_virtual.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\pe_virtual_to_raw.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\peb_lookup.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\relocate.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\remote_pe_reader.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\resource_parser.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\resource_util.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libpeconv\libpeconv\src\util.cpp">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sandbox_callbacks.cpp">
|
||||
<Filter>源文件\sandbox</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="head.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sandbox.h">
|
||||
<Filter>头文件\sandbox</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="libpeconv\libpeconv\src\fix_dot_net_ep.h">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="libpeconv\libpeconv\src\ntddk.h">
|
||||
<Filter>头文件\libpe</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="native_struct.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sandbox_callbacks.h">
|
||||
<Filter>头文件\sandbox</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
BIN
ai_anti_malware/capstone/capstone.lib
Normal file
BIN
ai_anti_malware/capstone/capstone.lib
Normal file
Binary file not shown.
937
ai_anti_malware/capstone/include/capstone/arm.h
Normal file
937
ai_anti_malware/capstone/include/capstone/arm.h
Normal file
@@ -0,0 +1,937 @@
|
||||
#ifndef CAPSTONE_ARM_H
|
||||
#define CAPSTONE_ARM_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// ARM shift type
|
||||
typedef enum arm_shifter {
|
||||
ARM_SFT_INVALID = 0,
|
||||
ARM_SFT_ASR, ///< shift with immediate const
|
||||
ARM_SFT_LSL, ///< shift with immediate const
|
||||
ARM_SFT_LSR, ///< shift with immediate const
|
||||
ARM_SFT_ROR, ///< shift with immediate const
|
||||
ARM_SFT_RRX, ///< shift with immediate const
|
||||
ARM_SFT_ASR_REG, ///< shift with register
|
||||
ARM_SFT_LSL_REG, ///< shift with register
|
||||
ARM_SFT_LSR_REG, ///< shift with register
|
||||
ARM_SFT_ROR_REG, ///< shift with register
|
||||
ARM_SFT_RRX_REG, ///< shift with register
|
||||
} arm_shifter;
|
||||
|
||||
/// ARM condition code
|
||||
typedef enum arm_cc {
|
||||
ARM_CC_INVALID = 0,
|
||||
ARM_CC_EQ, ///< Equal Equal
|
||||
ARM_CC_NE, ///< Not equal Not equal, or unordered
|
||||
ARM_CC_HS, ///< Carry set >, ==, or unordered
|
||||
ARM_CC_LO, ///< Carry clear Less than
|
||||
ARM_CC_MI, ///< Minus, negative Less than
|
||||
ARM_CC_PL, ///< Plus, positive or zero >, ==, or unordered
|
||||
ARM_CC_VS, ///< Overflow Unordered
|
||||
ARM_CC_VC, ///< No overflow Not unordered
|
||||
ARM_CC_HI, ///< Unsigned higher Greater than, or unordered
|
||||
ARM_CC_LS, ///< Unsigned lower or same Less than or equal
|
||||
ARM_CC_GE, ///< Greater than or equal Greater than or equal
|
||||
ARM_CC_LT, ///< Less than Less than, or unordered
|
||||
ARM_CC_GT, ///< Greater than Greater than
|
||||
ARM_CC_LE, ///< Less than or equal <, ==, or unordered
|
||||
ARM_CC_AL ///< Always (unconditional) Always (unconditional)
|
||||
} arm_cc;
|
||||
|
||||
typedef enum arm_sysreg {
|
||||
/// Special registers for MSR
|
||||
ARM_SYSREG_INVALID = 0,
|
||||
|
||||
// SPSR* registers can be OR combined
|
||||
ARM_SYSREG_SPSR_C = 1,
|
||||
ARM_SYSREG_SPSR_X = 2,
|
||||
ARM_SYSREG_SPSR_S = 4,
|
||||
ARM_SYSREG_SPSR_F = 8,
|
||||
|
||||
// CPSR* registers can be OR combined
|
||||
ARM_SYSREG_CPSR_C = 16,
|
||||
ARM_SYSREG_CPSR_X = 32,
|
||||
ARM_SYSREG_CPSR_S = 64,
|
||||
ARM_SYSREG_CPSR_F = 128,
|
||||
|
||||
// independent registers
|
||||
ARM_SYSREG_APSR = 256,
|
||||
ARM_SYSREG_APSR_G,
|
||||
ARM_SYSREG_APSR_NZCVQ,
|
||||
ARM_SYSREG_APSR_NZCVQG,
|
||||
|
||||
ARM_SYSREG_IAPSR,
|
||||
ARM_SYSREG_IAPSR_G,
|
||||
ARM_SYSREG_IAPSR_NZCVQG,
|
||||
ARM_SYSREG_IAPSR_NZCVQ,
|
||||
|
||||
ARM_SYSREG_EAPSR,
|
||||
ARM_SYSREG_EAPSR_G,
|
||||
ARM_SYSREG_EAPSR_NZCVQG,
|
||||
ARM_SYSREG_EAPSR_NZCVQ,
|
||||
|
||||
ARM_SYSREG_XPSR,
|
||||
ARM_SYSREG_XPSR_G,
|
||||
ARM_SYSREG_XPSR_NZCVQG,
|
||||
ARM_SYSREG_XPSR_NZCVQ,
|
||||
|
||||
ARM_SYSREG_IPSR,
|
||||
ARM_SYSREG_EPSR,
|
||||
ARM_SYSREG_IEPSR,
|
||||
|
||||
ARM_SYSREG_MSP,
|
||||
ARM_SYSREG_PSP,
|
||||
ARM_SYSREG_PRIMASK,
|
||||
ARM_SYSREG_BASEPRI,
|
||||
ARM_SYSREG_BASEPRI_MAX,
|
||||
ARM_SYSREG_FAULTMASK,
|
||||
ARM_SYSREG_CONTROL,
|
||||
|
||||
// Banked Registers
|
||||
ARM_SYSREG_R8_USR,
|
||||
ARM_SYSREG_R9_USR,
|
||||
ARM_SYSREG_R10_USR,
|
||||
ARM_SYSREG_R11_USR,
|
||||
ARM_SYSREG_R12_USR,
|
||||
ARM_SYSREG_SP_USR,
|
||||
ARM_SYSREG_LR_USR,
|
||||
ARM_SYSREG_R8_FIQ,
|
||||
ARM_SYSREG_R9_FIQ,
|
||||
ARM_SYSREG_R10_FIQ,
|
||||
ARM_SYSREG_R11_FIQ,
|
||||
ARM_SYSREG_R12_FIQ,
|
||||
ARM_SYSREG_SP_FIQ,
|
||||
ARM_SYSREG_LR_FIQ,
|
||||
ARM_SYSREG_LR_IRQ,
|
||||
ARM_SYSREG_SP_IRQ,
|
||||
ARM_SYSREG_LR_SVC,
|
||||
ARM_SYSREG_SP_SVC,
|
||||
ARM_SYSREG_LR_ABT,
|
||||
ARM_SYSREG_SP_ABT,
|
||||
ARM_SYSREG_LR_UND,
|
||||
ARM_SYSREG_SP_UND,
|
||||
ARM_SYSREG_LR_MON,
|
||||
ARM_SYSREG_SP_MON,
|
||||
ARM_SYSREG_ELR_HYP,
|
||||
ARM_SYSREG_SP_HYP,
|
||||
|
||||
ARM_SYSREG_SPSR_FIQ,
|
||||
ARM_SYSREG_SPSR_IRQ,
|
||||
ARM_SYSREG_SPSR_SVC,
|
||||
ARM_SYSREG_SPSR_ABT,
|
||||
ARM_SYSREG_SPSR_UND,
|
||||
ARM_SYSREG_SPSR_MON,
|
||||
ARM_SYSREG_SPSR_HYP,
|
||||
} arm_sysreg;
|
||||
|
||||
/// The memory barrier constants map directly to the 4-bit encoding of
|
||||
/// the option field for Memory Barrier operations.
|
||||
typedef enum arm_mem_barrier {
|
||||
ARM_MB_INVALID = 0,
|
||||
ARM_MB_RESERVED_0,
|
||||
ARM_MB_OSHLD,
|
||||
ARM_MB_OSHST,
|
||||
ARM_MB_OSH,
|
||||
ARM_MB_RESERVED_4,
|
||||
ARM_MB_NSHLD,
|
||||
ARM_MB_NSHST,
|
||||
ARM_MB_NSH,
|
||||
ARM_MB_RESERVED_8,
|
||||
ARM_MB_ISHLD,
|
||||
ARM_MB_ISHST,
|
||||
ARM_MB_ISH,
|
||||
ARM_MB_RESERVED_12,
|
||||
ARM_MB_LD,
|
||||
ARM_MB_ST,
|
||||
ARM_MB_SY,
|
||||
} arm_mem_barrier;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum arm_op_type {
|
||||
ARM_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
ARM_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
ARM_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
ARM_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
ARM_OP_FP, ///< = CS_OP_FP (Floating-Point operand).
|
||||
ARM_OP_CIMM = 64, ///< C-Immediate (coprocessor registers)
|
||||
ARM_OP_PIMM, ///< P-Immediate (coprocessor registers)
|
||||
ARM_OP_SETEND, ///< operand for SETEND instruction
|
||||
ARM_OP_SYSREG, ///< MSR/MRS special register operand
|
||||
} arm_op_type;
|
||||
|
||||
/// Operand type for SETEND instruction
|
||||
typedef enum arm_setend_type {
|
||||
ARM_SETEND_INVALID = 0, ///< Uninitialized.
|
||||
ARM_SETEND_BE, ///< BE operand.
|
||||
ARM_SETEND_LE, ///< LE operand
|
||||
} arm_setend_type;
|
||||
|
||||
typedef enum arm_cpsmode_type {
|
||||
ARM_CPSMODE_INVALID = 0,
|
||||
ARM_CPSMODE_IE = 2,
|
||||
ARM_CPSMODE_ID = 3
|
||||
} arm_cpsmode_type;
|
||||
|
||||
/// Operand type for SETEND instruction
|
||||
typedef enum arm_cpsflag_type {
|
||||
ARM_CPSFLAG_INVALID = 0,
|
||||
ARM_CPSFLAG_F = 1,
|
||||
ARM_CPSFLAG_I = 2,
|
||||
ARM_CPSFLAG_A = 4,
|
||||
ARM_CPSFLAG_NONE = 16, ///< no flag
|
||||
} arm_cpsflag_type;
|
||||
|
||||
/// Data type for elements of vector instructions.
|
||||
typedef enum arm_vectordata_type {
|
||||
ARM_VECTORDATA_INVALID = 0,
|
||||
|
||||
// Integer type
|
||||
ARM_VECTORDATA_I8,
|
||||
ARM_VECTORDATA_I16,
|
||||
ARM_VECTORDATA_I32,
|
||||
ARM_VECTORDATA_I64,
|
||||
|
||||
// Signed integer type
|
||||
ARM_VECTORDATA_S8,
|
||||
ARM_VECTORDATA_S16,
|
||||
ARM_VECTORDATA_S32,
|
||||
ARM_VECTORDATA_S64,
|
||||
|
||||
// Unsigned integer type
|
||||
ARM_VECTORDATA_U8,
|
||||
ARM_VECTORDATA_U16,
|
||||
ARM_VECTORDATA_U32,
|
||||
ARM_VECTORDATA_U64,
|
||||
|
||||
// Data type for VMUL/VMULL
|
||||
ARM_VECTORDATA_P8,
|
||||
|
||||
// Floating type
|
||||
ARM_VECTORDATA_F32,
|
||||
ARM_VECTORDATA_F64,
|
||||
|
||||
// Convert float <-> float
|
||||
ARM_VECTORDATA_F16F64, // f16.f64
|
||||
ARM_VECTORDATA_F64F16, // f64.f16
|
||||
ARM_VECTORDATA_F32F16, // f32.f16
|
||||
ARM_VECTORDATA_F16F32, // f32.f16
|
||||
ARM_VECTORDATA_F64F32, // f64.f32
|
||||
ARM_VECTORDATA_F32F64, // f32.f64
|
||||
|
||||
// Convert integer <-> float
|
||||
ARM_VECTORDATA_S32F32, // s32.f32
|
||||
ARM_VECTORDATA_U32F32, // u32.f32
|
||||
ARM_VECTORDATA_F32S32, // f32.s32
|
||||
ARM_VECTORDATA_F32U32, // f32.u32
|
||||
ARM_VECTORDATA_F64S16, // f64.s16
|
||||
ARM_VECTORDATA_F32S16, // f32.s16
|
||||
ARM_VECTORDATA_F64S32, // f64.s32
|
||||
ARM_VECTORDATA_S16F64, // s16.f64
|
||||
ARM_VECTORDATA_S16F32, // s16.f64
|
||||
ARM_VECTORDATA_S32F64, // s32.f64
|
||||
ARM_VECTORDATA_U16F64, // u16.f64
|
||||
ARM_VECTORDATA_U16F32, // u16.f32
|
||||
ARM_VECTORDATA_U32F64, // u32.f64
|
||||
ARM_VECTORDATA_F64U16, // f64.u16
|
||||
ARM_VECTORDATA_F32U16, // f32.u16
|
||||
ARM_VECTORDATA_F64U32, // f64.u32
|
||||
} arm_vectordata_type;
|
||||
|
||||
/// ARM registers
|
||||
typedef enum arm_reg {
|
||||
ARM_REG_INVALID = 0,
|
||||
ARM_REG_APSR,
|
||||
ARM_REG_APSR_NZCV,
|
||||
ARM_REG_CPSR,
|
||||
ARM_REG_FPEXC,
|
||||
ARM_REG_FPINST,
|
||||
ARM_REG_FPSCR,
|
||||
ARM_REG_FPSCR_NZCV,
|
||||
ARM_REG_FPSID,
|
||||
ARM_REG_ITSTATE,
|
||||
ARM_REG_LR,
|
||||
ARM_REG_PC,
|
||||
ARM_REG_SP,
|
||||
ARM_REG_SPSR,
|
||||
ARM_REG_D0,
|
||||
ARM_REG_D1,
|
||||
ARM_REG_D2,
|
||||
ARM_REG_D3,
|
||||
ARM_REG_D4,
|
||||
ARM_REG_D5,
|
||||
ARM_REG_D6,
|
||||
ARM_REG_D7,
|
||||
ARM_REG_D8,
|
||||
ARM_REG_D9,
|
||||
ARM_REG_D10,
|
||||
ARM_REG_D11,
|
||||
ARM_REG_D12,
|
||||
ARM_REG_D13,
|
||||
ARM_REG_D14,
|
||||
ARM_REG_D15,
|
||||
ARM_REG_D16,
|
||||
ARM_REG_D17,
|
||||
ARM_REG_D18,
|
||||
ARM_REG_D19,
|
||||
ARM_REG_D20,
|
||||
ARM_REG_D21,
|
||||
ARM_REG_D22,
|
||||
ARM_REG_D23,
|
||||
ARM_REG_D24,
|
||||
ARM_REG_D25,
|
||||
ARM_REG_D26,
|
||||
ARM_REG_D27,
|
||||
ARM_REG_D28,
|
||||
ARM_REG_D29,
|
||||
ARM_REG_D30,
|
||||
ARM_REG_D31,
|
||||
ARM_REG_FPINST2,
|
||||
ARM_REG_MVFR0,
|
||||
ARM_REG_MVFR1,
|
||||
ARM_REG_MVFR2,
|
||||
ARM_REG_Q0,
|
||||
ARM_REG_Q1,
|
||||
ARM_REG_Q2,
|
||||
ARM_REG_Q3,
|
||||
ARM_REG_Q4,
|
||||
ARM_REG_Q5,
|
||||
ARM_REG_Q6,
|
||||
ARM_REG_Q7,
|
||||
ARM_REG_Q8,
|
||||
ARM_REG_Q9,
|
||||
ARM_REG_Q10,
|
||||
ARM_REG_Q11,
|
||||
ARM_REG_Q12,
|
||||
ARM_REG_Q13,
|
||||
ARM_REG_Q14,
|
||||
ARM_REG_Q15,
|
||||
ARM_REG_R0,
|
||||
ARM_REG_R1,
|
||||
ARM_REG_R2,
|
||||
ARM_REG_R3,
|
||||
ARM_REG_R4,
|
||||
ARM_REG_R5,
|
||||
ARM_REG_R6,
|
||||
ARM_REG_R7,
|
||||
ARM_REG_R8,
|
||||
ARM_REG_R9,
|
||||
ARM_REG_R10,
|
||||
ARM_REG_R11,
|
||||
ARM_REG_R12,
|
||||
ARM_REG_S0,
|
||||
ARM_REG_S1,
|
||||
ARM_REG_S2,
|
||||
ARM_REG_S3,
|
||||
ARM_REG_S4,
|
||||
ARM_REG_S5,
|
||||
ARM_REG_S6,
|
||||
ARM_REG_S7,
|
||||
ARM_REG_S8,
|
||||
ARM_REG_S9,
|
||||
ARM_REG_S10,
|
||||
ARM_REG_S11,
|
||||
ARM_REG_S12,
|
||||
ARM_REG_S13,
|
||||
ARM_REG_S14,
|
||||
ARM_REG_S15,
|
||||
ARM_REG_S16,
|
||||
ARM_REG_S17,
|
||||
ARM_REG_S18,
|
||||
ARM_REG_S19,
|
||||
ARM_REG_S20,
|
||||
ARM_REG_S21,
|
||||
ARM_REG_S22,
|
||||
ARM_REG_S23,
|
||||
ARM_REG_S24,
|
||||
ARM_REG_S25,
|
||||
ARM_REG_S26,
|
||||
ARM_REG_S27,
|
||||
ARM_REG_S28,
|
||||
ARM_REG_S29,
|
||||
ARM_REG_S30,
|
||||
ARM_REG_S31,
|
||||
|
||||
ARM_REG_ENDING, // <-- mark the end of the list or registers
|
||||
|
||||
// alias registers
|
||||
ARM_REG_R13 = ARM_REG_SP,
|
||||
ARM_REG_R14 = ARM_REG_LR,
|
||||
ARM_REG_R15 = ARM_REG_PC,
|
||||
|
||||
ARM_REG_SB = ARM_REG_R9,
|
||||
ARM_REG_SL = ARM_REG_R10,
|
||||
ARM_REG_FP = ARM_REG_R11,
|
||||
ARM_REG_IP = ARM_REG_R12,
|
||||
} arm_reg;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with ARM_OP_MEM operand type above
|
||||
typedef struct arm_op_mem {
|
||||
arm_reg base; ///< base register
|
||||
arm_reg index; ///< index register
|
||||
int scale; ///< scale for index register (can be 1, or -1)
|
||||
int disp; ///< displacement/offset value
|
||||
/// left-shift on index register, or 0 if irrelevant
|
||||
/// NOTE: this value can also be fetched via operand.shift.value
|
||||
int lshift;
|
||||
} arm_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_arm_op {
|
||||
int vector_index; ///< Vector Index for some vector operands (or -1 if irrelevant)
|
||||
|
||||
struct {
|
||||
arm_shifter type;
|
||||
unsigned int value;
|
||||
} shift;
|
||||
|
||||
arm_op_type type; ///< operand type
|
||||
|
||||
union {
|
||||
int reg; ///< register value for REG/SYSREG operand
|
||||
int32_t imm; ///< immediate value for C-IMM, P-IMM or IMM operand
|
||||
double fp; ///< floating point value for FP operand
|
||||
arm_op_mem mem; ///< base/index/scale/disp value for MEM operand
|
||||
arm_setend_type setend; ///< SETEND instruction's operand type
|
||||
};
|
||||
|
||||
/// in some instructions, an operand can be subtracted or added to
|
||||
/// the base register,
|
||||
/// if TRUE, this operand is subtracted. otherwise, it is added.
|
||||
bool subtracted;
|
||||
|
||||
/// How is this operand accessed? (READ, WRITE or READ|WRITE)
|
||||
/// This field is combined of cs_ac_type.
|
||||
/// NOTE: this field is irrelevant if engine is compiled in DIET mode.
|
||||
uint8_t access;
|
||||
|
||||
/// Neon lane index for NEON instructions (or -1 if irrelevant)
|
||||
int8_t neon_lane;
|
||||
} cs_arm_op;
|
||||
|
||||
/// Instruction structure
|
||||
typedef struct cs_arm {
|
||||
bool usermode; ///< User-mode registers to be loaded (for LDM/STM instructions)
|
||||
int vector_size; ///< Scalar size for vector instructions
|
||||
arm_vectordata_type vector_data; ///< Data type for elements of vector instructions
|
||||
arm_cpsmode_type cps_mode; ///< CPS mode for CPS instruction
|
||||
arm_cpsflag_type cps_flag; ///< CPS mode for CPS instruction
|
||||
arm_cc cc; ///< conditional code for this insn
|
||||
bool update_flags; ///< does this insn update flags?
|
||||
bool writeback; ///< does this insn write-back?
|
||||
arm_mem_barrier mem_barrier; ///< Option for some memory barrier instructions
|
||||
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
|
||||
cs_arm_op operands[36]; ///< operands for this instruction.
|
||||
} cs_arm;
|
||||
|
||||
/// ARM instruction
|
||||
typedef enum arm_insn {
|
||||
ARM_INS_INVALID = 0,
|
||||
|
||||
ARM_INS_ADC,
|
||||
ARM_INS_ADD,
|
||||
ARM_INS_ADR,
|
||||
ARM_INS_AESD,
|
||||
ARM_INS_AESE,
|
||||
ARM_INS_AESIMC,
|
||||
ARM_INS_AESMC,
|
||||
ARM_INS_AND,
|
||||
ARM_INS_BFC,
|
||||
ARM_INS_BFI,
|
||||
ARM_INS_BIC,
|
||||
ARM_INS_BKPT,
|
||||
ARM_INS_BL,
|
||||
ARM_INS_BLX,
|
||||
ARM_INS_BX,
|
||||
ARM_INS_BXJ,
|
||||
ARM_INS_B,
|
||||
ARM_INS_CDP,
|
||||
ARM_INS_CDP2,
|
||||
ARM_INS_CLREX,
|
||||
ARM_INS_CLZ,
|
||||
ARM_INS_CMN,
|
||||
ARM_INS_CMP,
|
||||
ARM_INS_CPS,
|
||||
ARM_INS_CRC32B,
|
||||
ARM_INS_CRC32CB,
|
||||
ARM_INS_CRC32CH,
|
||||
ARM_INS_CRC32CW,
|
||||
ARM_INS_CRC32H,
|
||||
ARM_INS_CRC32W,
|
||||
ARM_INS_DBG,
|
||||
ARM_INS_DMB,
|
||||
ARM_INS_DSB,
|
||||
ARM_INS_EOR,
|
||||
ARM_INS_ERET,
|
||||
ARM_INS_VMOV,
|
||||
ARM_INS_FLDMDBX,
|
||||
ARM_INS_FLDMIAX,
|
||||
ARM_INS_VMRS,
|
||||
ARM_INS_FSTMDBX,
|
||||
ARM_INS_FSTMIAX,
|
||||
ARM_INS_HINT,
|
||||
ARM_INS_HLT,
|
||||
ARM_INS_HVC,
|
||||
ARM_INS_ISB,
|
||||
ARM_INS_LDA,
|
||||
ARM_INS_LDAB,
|
||||
ARM_INS_LDAEX,
|
||||
ARM_INS_LDAEXB,
|
||||
ARM_INS_LDAEXD,
|
||||
ARM_INS_LDAEXH,
|
||||
ARM_INS_LDAH,
|
||||
ARM_INS_LDC2L,
|
||||
ARM_INS_LDC2,
|
||||
ARM_INS_LDCL,
|
||||
ARM_INS_LDC,
|
||||
ARM_INS_LDMDA,
|
||||
ARM_INS_LDMDB,
|
||||
ARM_INS_LDM,
|
||||
ARM_INS_LDMIB,
|
||||
ARM_INS_LDRBT,
|
||||
ARM_INS_LDRB,
|
||||
ARM_INS_LDRD,
|
||||
ARM_INS_LDREX,
|
||||
ARM_INS_LDREXB,
|
||||
ARM_INS_LDREXD,
|
||||
ARM_INS_LDREXH,
|
||||
ARM_INS_LDRH,
|
||||
ARM_INS_LDRHT,
|
||||
ARM_INS_LDRSB,
|
||||
ARM_INS_LDRSBT,
|
||||
ARM_INS_LDRSH,
|
||||
ARM_INS_LDRSHT,
|
||||
ARM_INS_LDRT,
|
||||
ARM_INS_LDR,
|
||||
ARM_INS_MCR,
|
||||
ARM_INS_MCR2,
|
||||
ARM_INS_MCRR,
|
||||
ARM_INS_MCRR2,
|
||||
ARM_INS_MLA,
|
||||
ARM_INS_MLS,
|
||||
ARM_INS_MOV,
|
||||
ARM_INS_MOVT,
|
||||
ARM_INS_MOVW,
|
||||
ARM_INS_MRC,
|
||||
ARM_INS_MRC2,
|
||||
ARM_INS_MRRC,
|
||||
ARM_INS_MRRC2,
|
||||
ARM_INS_MRS,
|
||||
ARM_INS_MSR,
|
||||
ARM_INS_MUL,
|
||||
ARM_INS_MVN,
|
||||
ARM_INS_ORR,
|
||||
ARM_INS_PKHBT,
|
||||
ARM_INS_PKHTB,
|
||||
ARM_INS_PLDW,
|
||||
ARM_INS_PLD,
|
||||
ARM_INS_PLI,
|
||||
ARM_INS_QADD,
|
||||
ARM_INS_QADD16,
|
||||
ARM_INS_QADD8,
|
||||
ARM_INS_QASX,
|
||||
ARM_INS_QDADD,
|
||||
ARM_INS_QDSUB,
|
||||
ARM_INS_QSAX,
|
||||
ARM_INS_QSUB,
|
||||
ARM_INS_QSUB16,
|
||||
ARM_INS_QSUB8,
|
||||
ARM_INS_RBIT,
|
||||
ARM_INS_REV,
|
||||
ARM_INS_REV16,
|
||||
ARM_INS_REVSH,
|
||||
ARM_INS_RFEDA,
|
||||
ARM_INS_RFEDB,
|
||||
ARM_INS_RFEIA,
|
||||
ARM_INS_RFEIB,
|
||||
ARM_INS_RSB,
|
||||
ARM_INS_RSC,
|
||||
ARM_INS_SADD16,
|
||||
ARM_INS_SADD8,
|
||||
ARM_INS_SASX,
|
||||
ARM_INS_SBC,
|
||||
ARM_INS_SBFX,
|
||||
ARM_INS_SDIV,
|
||||
ARM_INS_SEL,
|
||||
ARM_INS_SETEND,
|
||||
ARM_INS_SHA1C,
|
||||
ARM_INS_SHA1H,
|
||||
ARM_INS_SHA1M,
|
||||
ARM_INS_SHA1P,
|
||||
ARM_INS_SHA1SU0,
|
||||
ARM_INS_SHA1SU1,
|
||||
ARM_INS_SHA256H,
|
||||
ARM_INS_SHA256H2,
|
||||
ARM_INS_SHA256SU0,
|
||||
ARM_INS_SHA256SU1,
|
||||
ARM_INS_SHADD16,
|
||||
ARM_INS_SHADD8,
|
||||
ARM_INS_SHASX,
|
||||
ARM_INS_SHSAX,
|
||||
ARM_INS_SHSUB16,
|
||||
ARM_INS_SHSUB8,
|
||||
ARM_INS_SMC,
|
||||
ARM_INS_SMLABB,
|
||||
ARM_INS_SMLABT,
|
||||
ARM_INS_SMLAD,
|
||||
ARM_INS_SMLADX,
|
||||
ARM_INS_SMLAL,
|
||||
ARM_INS_SMLALBB,
|
||||
ARM_INS_SMLALBT,
|
||||
ARM_INS_SMLALD,
|
||||
ARM_INS_SMLALDX,
|
||||
ARM_INS_SMLALTB,
|
||||
ARM_INS_SMLALTT,
|
||||
ARM_INS_SMLATB,
|
||||
ARM_INS_SMLATT,
|
||||
ARM_INS_SMLAWB,
|
||||
ARM_INS_SMLAWT,
|
||||
ARM_INS_SMLSD,
|
||||
ARM_INS_SMLSDX,
|
||||
ARM_INS_SMLSLD,
|
||||
ARM_INS_SMLSLDX,
|
||||
ARM_INS_SMMLA,
|
||||
ARM_INS_SMMLAR,
|
||||
ARM_INS_SMMLS,
|
||||
ARM_INS_SMMLSR,
|
||||
ARM_INS_SMMUL,
|
||||
ARM_INS_SMMULR,
|
||||
ARM_INS_SMUAD,
|
||||
ARM_INS_SMUADX,
|
||||
ARM_INS_SMULBB,
|
||||
ARM_INS_SMULBT,
|
||||
ARM_INS_SMULL,
|
||||
ARM_INS_SMULTB,
|
||||
ARM_INS_SMULTT,
|
||||
ARM_INS_SMULWB,
|
||||
ARM_INS_SMULWT,
|
||||
ARM_INS_SMUSD,
|
||||
ARM_INS_SMUSDX,
|
||||
ARM_INS_SRSDA,
|
||||
ARM_INS_SRSDB,
|
||||
ARM_INS_SRSIA,
|
||||
ARM_INS_SRSIB,
|
||||
ARM_INS_SSAT,
|
||||
ARM_INS_SSAT16,
|
||||
ARM_INS_SSAX,
|
||||
ARM_INS_SSUB16,
|
||||
ARM_INS_SSUB8,
|
||||
ARM_INS_STC2L,
|
||||
ARM_INS_STC2,
|
||||
ARM_INS_STCL,
|
||||
ARM_INS_STC,
|
||||
ARM_INS_STL,
|
||||
ARM_INS_STLB,
|
||||
ARM_INS_STLEX,
|
||||
ARM_INS_STLEXB,
|
||||
ARM_INS_STLEXD,
|
||||
ARM_INS_STLEXH,
|
||||
ARM_INS_STLH,
|
||||
ARM_INS_STMDA,
|
||||
ARM_INS_STMDB,
|
||||
ARM_INS_STM,
|
||||
ARM_INS_STMIB,
|
||||
ARM_INS_STRBT,
|
||||
ARM_INS_STRB,
|
||||
ARM_INS_STRD,
|
||||
ARM_INS_STREX,
|
||||
ARM_INS_STREXB,
|
||||
ARM_INS_STREXD,
|
||||
ARM_INS_STREXH,
|
||||
ARM_INS_STRH,
|
||||
ARM_INS_STRHT,
|
||||
ARM_INS_STRT,
|
||||
ARM_INS_STR,
|
||||
ARM_INS_SUB,
|
||||
ARM_INS_SVC,
|
||||
ARM_INS_SWP,
|
||||
ARM_INS_SWPB,
|
||||
ARM_INS_SXTAB,
|
||||
ARM_INS_SXTAB16,
|
||||
ARM_INS_SXTAH,
|
||||
ARM_INS_SXTB,
|
||||
ARM_INS_SXTB16,
|
||||
ARM_INS_SXTH,
|
||||
ARM_INS_TEQ,
|
||||
ARM_INS_TRAP,
|
||||
ARM_INS_TST,
|
||||
ARM_INS_UADD16,
|
||||
ARM_INS_UADD8,
|
||||
ARM_INS_UASX,
|
||||
ARM_INS_UBFX,
|
||||
ARM_INS_UDF,
|
||||
ARM_INS_UDIV,
|
||||
ARM_INS_UHADD16,
|
||||
ARM_INS_UHADD8,
|
||||
ARM_INS_UHASX,
|
||||
ARM_INS_UHSAX,
|
||||
ARM_INS_UHSUB16,
|
||||
ARM_INS_UHSUB8,
|
||||
ARM_INS_UMAAL,
|
||||
ARM_INS_UMLAL,
|
||||
ARM_INS_UMULL,
|
||||
ARM_INS_UQADD16,
|
||||
ARM_INS_UQADD8,
|
||||
ARM_INS_UQASX,
|
||||
ARM_INS_UQSAX,
|
||||
ARM_INS_UQSUB16,
|
||||
ARM_INS_UQSUB8,
|
||||
ARM_INS_USAD8,
|
||||
ARM_INS_USADA8,
|
||||
ARM_INS_USAT,
|
||||
ARM_INS_USAT16,
|
||||
ARM_INS_USAX,
|
||||
ARM_INS_USUB16,
|
||||
ARM_INS_USUB8,
|
||||
ARM_INS_UXTAB,
|
||||
ARM_INS_UXTAB16,
|
||||
ARM_INS_UXTAH,
|
||||
ARM_INS_UXTB,
|
||||
ARM_INS_UXTB16,
|
||||
ARM_INS_UXTH,
|
||||
ARM_INS_VABAL,
|
||||
ARM_INS_VABA,
|
||||
ARM_INS_VABDL,
|
||||
ARM_INS_VABD,
|
||||
ARM_INS_VABS,
|
||||
ARM_INS_VACGE,
|
||||
ARM_INS_VACGT,
|
||||
ARM_INS_VADD,
|
||||
ARM_INS_VADDHN,
|
||||
ARM_INS_VADDL,
|
||||
ARM_INS_VADDW,
|
||||
ARM_INS_VAND,
|
||||
ARM_INS_VBIC,
|
||||
ARM_INS_VBIF,
|
||||
ARM_INS_VBIT,
|
||||
ARM_INS_VBSL,
|
||||
ARM_INS_VCEQ,
|
||||
ARM_INS_VCGE,
|
||||
ARM_INS_VCGT,
|
||||
ARM_INS_VCLE,
|
||||
ARM_INS_VCLS,
|
||||
ARM_INS_VCLT,
|
||||
ARM_INS_VCLZ,
|
||||
ARM_INS_VCMP,
|
||||
ARM_INS_VCMPE,
|
||||
ARM_INS_VCNT,
|
||||
ARM_INS_VCVTA,
|
||||
ARM_INS_VCVTB,
|
||||
ARM_INS_VCVT,
|
||||
ARM_INS_VCVTM,
|
||||
ARM_INS_VCVTN,
|
||||
ARM_INS_VCVTP,
|
||||
ARM_INS_VCVTT,
|
||||
ARM_INS_VDIV,
|
||||
ARM_INS_VDUP,
|
||||
ARM_INS_VEOR,
|
||||
ARM_INS_VEXT,
|
||||
ARM_INS_VFMA,
|
||||
ARM_INS_VFMS,
|
||||
ARM_INS_VFNMA,
|
||||
ARM_INS_VFNMS,
|
||||
ARM_INS_VHADD,
|
||||
ARM_INS_VHSUB,
|
||||
ARM_INS_VLD1,
|
||||
ARM_INS_VLD2,
|
||||
ARM_INS_VLD3,
|
||||
ARM_INS_VLD4,
|
||||
ARM_INS_VLDMDB,
|
||||
ARM_INS_VLDMIA,
|
||||
ARM_INS_VLDR,
|
||||
ARM_INS_VMAXNM,
|
||||
ARM_INS_VMAX,
|
||||
ARM_INS_VMINNM,
|
||||
ARM_INS_VMIN,
|
||||
ARM_INS_VMLA,
|
||||
ARM_INS_VMLAL,
|
||||
ARM_INS_VMLS,
|
||||
ARM_INS_VMLSL,
|
||||
ARM_INS_VMOVL,
|
||||
ARM_INS_VMOVN,
|
||||
ARM_INS_VMSR,
|
||||
ARM_INS_VMUL,
|
||||
ARM_INS_VMULL,
|
||||
ARM_INS_VMVN,
|
||||
ARM_INS_VNEG,
|
||||
ARM_INS_VNMLA,
|
||||
ARM_INS_VNMLS,
|
||||
ARM_INS_VNMUL,
|
||||
ARM_INS_VORN,
|
||||
ARM_INS_VORR,
|
||||
ARM_INS_VPADAL,
|
||||
ARM_INS_VPADDL,
|
||||
ARM_INS_VPADD,
|
||||
ARM_INS_VPMAX,
|
||||
ARM_INS_VPMIN,
|
||||
ARM_INS_VQABS,
|
||||
ARM_INS_VQADD,
|
||||
ARM_INS_VQDMLAL,
|
||||
ARM_INS_VQDMLSL,
|
||||
ARM_INS_VQDMULH,
|
||||
ARM_INS_VQDMULL,
|
||||
ARM_INS_VQMOVUN,
|
||||
ARM_INS_VQMOVN,
|
||||
ARM_INS_VQNEG,
|
||||
ARM_INS_VQRDMULH,
|
||||
ARM_INS_VQRSHL,
|
||||
ARM_INS_VQRSHRN,
|
||||
ARM_INS_VQRSHRUN,
|
||||
ARM_INS_VQSHL,
|
||||
ARM_INS_VQSHLU,
|
||||
ARM_INS_VQSHRN,
|
||||
ARM_INS_VQSHRUN,
|
||||
ARM_INS_VQSUB,
|
||||
ARM_INS_VRADDHN,
|
||||
ARM_INS_VRECPE,
|
||||
ARM_INS_VRECPS,
|
||||
ARM_INS_VREV16,
|
||||
ARM_INS_VREV32,
|
||||
ARM_INS_VREV64,
|
||||
ARM_INS_VRHADD,
|
||||
ARM_INS_VRINTA,
|
||||
ARM_INS_VRINTM,
|
||||
ARM_INS_VRINTN,
|
||||
ARM_INS_VRINTP,
|
||||
ARM_INS_VRINTR,
|
||||
ARM_INS_VRINTX,
|
||||
ARM_INS_VRINTZ,
|
||||
ARM_INS_VRSHL,
|
||||
ARM_INS_VRSHRN,
|
||||
ARM_INS_VRSHR,
|
||||
ARM_INS_VRSQRTE,
|
||||
ARM_INS_VRSQRTS,
|
||||
ARM_INS_VRSRA,
|
||||
ARM_INS_VRSUBHN,
|
||||
ARM_INS_VSELEQ,
|
||||
ARM_INS_VSELGE,
|
||||
ARM_INS_VSELGT,
|
||||
ARM_INS_VSELVS,
|
||||
ARM_INS_VSHLL,
|
||||
ARM_INS_VSHL,
|
||||
ARM_INS_VSHRN,
|
||||
ARM_INS_VSHR,
|
||||
ARM_INS_VSLI,
|
||||
ARM_INS_VSQRT,
|
||||
ARM_INS_VSRA,
|
||||
ARM_INS_VSRI,
|
||||
ARM_INS_VST1,
|
||||
ARM_INS_VST2,
|
||||
ARM_INS_VST3,
|
||||
ARM_INS_VST4,
|
||||
ARM_INS_VSTMDB,
|
||||
ARM_INS_VSTMIA,
|
||||
ARM_INS_VSTR,
|
||||
ARM_INS_VSUB,
|
||||
ARM_INS_VSUBHN,
|
||||
ARM_INS_VSUBL,
|
||||
ARM_INS_VSUBW,
|
||||
ARM_INS_VSWP,
|
||||
ARM_INS_VTBL,
|
||||
ARM_INS_VTBX,
|
||||
ARM_INS_VCVTR,
|
||||
ARM_INS_VTRN,
|
||||
ARM_INS_VTST,
|
||||
ARM_INS_VUZP,
|
||||
ARM_INS_VZIP,
|
||||
ARM_INS_ADDW,
|
||||
ARM_INS_ASR,
|
||||
ARM_INS_DCPS1,
|
||||
ARM_INS_DCPS2,
|
||||
ARM_INS_DCPS3,
|
||||
ARM_INS_IT,
|
||||
ARM_INS_LSL,
|
||||
ARM_INS_LSR,
|
||||
ARM_INS_ORN,
|
||||
ARM_INS_ROR,
|
||||
ARM_INS_RRX,
|
||||
ARM_INS_SUBW,
|
||||
ARM_INS_TBB,
|
||||
ARM_INS_TBH,
|
||||
ARM_INS_CBNZ,
|
||||
ARM_INS_CBZ,
|
||||
ARM_INS_POP,
|
||||
ARM_INS_PUSH,
|
||||
|
||||
// special instructions
|
||||
ARM_INS_NOP,
|
||||
ARM_INS_YIELD,
|
||||
ARM_INS_WFE,
|
||||
ARM_INS_WFI,
|
||||
ARM_INS_SEV,
|
||||
ARM_INS_SEVL,
|
||||
ARM_INS_VPUSH,
|
||||
ARM_INS_VPOP,
|
||||
|
||||
ARM_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} arm_insn;
|
||||
|
||||
/// Group of ARM instructions
|
||||
typedef enum arm_insn_group {
|
||||
ARM_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
ARM_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
ARM_GRP_CALL, ///< = CS_GRP_CALL
|
||||
ARM_GRP_INT = 4, ///< = CS_GRP_INT
|
||||
ARM_GRP_PRIVILEGE = 6, ///< = CS_GRP_PRIVILEGE
|
||||
ARM_GRP_BRANCH_RELATIVE, ///< = CS_GRP_BRANCH_RELATIVE
|
||||
|
||||
// Architecture-specific groups
|
||||
ARM_GRP_CRYPTO = 128,
|
||||
ARM_GRP_DATABARRIER,
|
||||
ARM_GRP_DIVIDE,
|
||||
ARM_GRP_FPARMV8,
|
||||
ARM_GRP_MULTPRO,
|
||||
ARM_GRP_NEON,
|
||||
ARM_GRP_T2EXTRACTPACK,
|
||||
ARM_GRP_THUMB2DSP,
|
||||
ARM_GRP_TRUSTZONE,
|
||||
ARM_GRP_V4T,
|
||||
ARM_GRP_V5T,
|
||||
ARM_GRP_V5TE,
|
||||
ARM_GRP_V6,
|
||||
ARM_GRP_V6T2,
|
||||
ARM_GRP_V7,
|
||||
ARM_GRP_V8,
|
||||
ARM_GRP_VFP2,
|
||||
ARM_GRP_VFP3,
|
||||
ARM_GRP_VFP4,
|
||||
ARM_GRP_ARM,
|
||||
ARM_GRP_MCLASS,
|
||||
ARM_GRP_NOTMCLASS,
|
||||
ARM_GRP_THUMB,
|
||||
ARM_GRP_THUMB1ONLY,
|
||||
ARM_GRP_THUMB2,
|
||||
ARM_GRP_PREV8,
|
||||
ARM_GRP_FPVMLX,
|
||||
ARM_GRP_MULOPS,
|
||||
ARM_GRP_CRC,
|
||||
ARM_GRP_DPVFP,
|
||||
ARM_GRP_V6M,
|
||||
ARM_GRP_VIRTUALIZATION,
|
||||
|
||||
ARM_GRP_ENDING,
|
||||
} arm_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1164
ai_anti_malware/capstone/include/capstone/arm64.h
Normal file
1164
ai_anti_malware/capstone/include/capstone/arm64.h
Normal file
File diff suppressed because it is too large
Load Diff
766
ai_anti_malware/capstone/include/capstone/capstone.h
Normal file
766
ai_anti_malware/capstone/include/capstone/capstone.h
Normal file
@@ -0,0 +1,766 @@
|
||||
#ifndef CAPSTONE_ENGINE_H
|
||||
#define CAPSTONE_ENGINE_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2016 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#if defined(CAPSTONE_HAS_OSXKERNEL)
|
||||
#include <libkern/libkern.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#pragma warning(disable:4100)
|
||||
#define CAPSTONE_API __cdecl
|
||||
#ifdef CAPSTONE_SHARED
|
||||
#define CAPSTONE_EXPORT __declspec(dllexport)
|
||||
#else // defined(CAPSTONE_STATIC)
|
||||
#define CAPSTONE_EXPORT
|
||||
#endif
|
||||
#else
|
||||
#define CAPSTONE_API
|
||||
#if defined(__GNUC__) && !defined(CAPSTONE_STATIC)
|
||||
#define CAPSTONE_EXPORT __attribute__((visibility("default")))
|
||||
#else // defined(CAPSTONE_STATIC)
|
||||
#define CAPSTONE_EXPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define CAPSTONE_DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
#define CAPSTONE_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
#pragma message("WARNING: You need to implement CAPSTONE_DEPRECATED for this compiler")
|
||||
#define CAPSTONE_DEPRECATED
|
||||
#endif
|
||||
|
||||
// Capstone API version
|
||||
#define CS_API_MAJOR 4
|
||||
#define CS_API_MINOR 0
|
||||
|
||||
// Version for bleeding edge code of the Github's "next" branch.
|
||||
// Use this if you want the absolutely latest development code.
|
||||
// This version number will be bumped up whenever we have a new major change.
|
||||
#define CS_NEXT_VERSION 5
|
||||
|
||||
// Capstone package version
|
||||
#define CS_VERSION_MAJOR CS_API_MAJOR
|
||||
#define CS_VERSION_MINOR CS_API_MINOR
|
||||
#define CS_VERSION_EXTRA 2
|
||||
|
||||
/// Macro to create combined version which can be compared to
|
||||
/// result of cs_version() API.
|
||||
#define CS_MAKE_VERSION(major, minor) ((major << 8) + minor)
|
||||
|
||||
/// Maximum size of an instruction mnemonic string.
|
||||
#define CS_MNEMONIC_SIZE 32
|
||||
|
||||
// Handle using with all API
|
||||
typedef size_t csh;
|
||||
|
||||
/// Architecture type
|
||||
typedef enum cs_arch {
|
||||
CS_ARCH_ARM = 0, ///< ARM architecture (including Thumb, Thumb-2)
|
||||
CS_ARCH_ARM64, ///< ARM-64, also called AArch64
|
||||
CS_ARCH_MIPS, ///< Mips architecture
|
||||
CS_ARCH_X86, ///< X86 architecture (including x86 & x86-64)
|
||||
CS_ARCH_PPC, ///< PowerPC architecture
|
||||
CS_ARCH_SPARC, ///< Sparc architecture
|
||||
CS_ARCH_SYSZ, ///< SystemZ architecture
|
||||
CS_ARCH_XCORE, ///< XCore architecture
|
||||
CS_ARCH_M68K, ///< 68K architecture
|
||||
CS_ARCH_TMS320C64X, ///< TMS320C64x architecture
|
||||
CS_ARCH_M680X, ///< 680X architecture
|
||||
CS_ARCH_EVM, ///< Ethereum architecture
|
||||
CS_ARCH_MAX,
|
||||
CS_ARCH_ALL = 0xFFFF, // All architectures - for cs_support()
|
||||
} cs_arch;
|
||||
|
||||
// Support value to verify diet mode of the engine.
|
||||
// If cs_support(CS_SUPPORT_DIET) return True, the engine was compiled
|
||||
// in diet mode.
|
||||
#define CS_SUPPORT_DIET (CS_ARCH_ALL + 1)
|
||||
|
||||
// Support value to verify X86 reduce mode of the engine.
|
||||
// If cs_support(CS_SUPPORT_X86_REDUCE) return True, the engine was compiled
|
||||
// in X86 reduce mode.
|
||||
#define CS_SUPPORT_X86_REDUCE (CS_ARCH_ALL + 2)
|
||||
|
||||
/// Mode type
|
||||
typedef enum cs_mode {
|
||||
CS_MODE_LITTLE_ENDIAN = 0, ///< little-endian mode (default mode)
|
||||
CS_MODE_ARM = 0, ///< 32-bit ARM
|
||||
CS_MODE_16 = 1 << 1, ///< 16-bit mode (X86)
|
||||
CS_MODE_32 = 1 << 2, ///< 32-bit mode (X86)
|
||||
CS_MODE_64 = 1 << 3, ///< 64-bit mode (X86, PPC)
|
||||
CS_MODE_THUMB = 1 << 4, ///< ARM's Thumb mode, including Thumb-2
|
||||
CS_MODE_MCLASS = 1 << 5, ///< ARM's Cortex-M series
|
||||
CS_MODE_V8 = 1 << 6, ///< ARMv8 A32 encodings for ARM
|
||||
CS_MODE_MICRO = 1 << 4, ///< MicroMips mode (MIPS)
|
||||
CS_MODE_MIPS3 = 1 << 5, ///< Mips III ISA
|
||||
CS_MODE_MIPS32R6 = 1 << 6, ///< Mips32r6 ISA
|
||||
CS_MODE_MIPS2 = 1 << 7, ///< Mips II ISA
|
||||
CS_MODE_V9 = 1 << 4, ///< SparcV9 mode (Sparc)
|
||||
CS_MODE_QPX = 1 << 4, ///< Quad Processing eXtensions mode (PPC)
|
||||
CS_MODE_M68K_000 = 1 << 1, ///< M68K 68000 mode
|
||||
CS_MODE_M68K_010 = 1 << 2, ///< M68K 68010 mode
|
||||
CS_MODE_M68K_020 = 1 << 3, ///< M68K 68020 mode
|
||||
CS_MODE_M68K_030 = 1 << 4, ///< M68K 68030 mode
|
||||
CS_MODE_M68K_040 = 1 << 5, ///< M68K 68040 mode
|
||||
CS_MODE_M68K_060 = 1 << 6, ///< M68K 68060 mode
|
||||
CS_MODE_BIG_ENDIAN = 1 << 31, ///< big-endian mode
|
||||
CS_MODE_MIPS32 = CS_MODE_32, ///< Mips32 ISA (Mips)
|
||||
CS_MODE_MIPS64 = CS_MODE_64, ///< Mips64 ISA (Mips)
|
||||
CS_MODE_M680X_6301 = 1 << 1, ///< M680X Hitachi 6301,6303 mode
|
||||
CS_MODE_M680X_6309 = 1 << 2, ///< M680X Hitachi 6309 mode
|
||||
CS_MODE_M680X_6800 = 1 << 3, ///< M680X Motorola 6800,6802 mode
|
||||
CS_MODE_M680X_6801 = 1 << 4, ///< M680X Motorola 6801,6803 mode
|
||||
CS_MODE_M680X_6805 = 1 << 5, ///< M680X Motorola/Freescale 6805 mode
|
||||
CS_MODE_M680X_6808 = 1 << 6, ///< M680X Motorola/Freescale/NXP 68HC08 mode
|
||||
CS_MODE_M680X_6809 = 1 << 7, ///< M680X Motorola 6809 mode
|
||||
CS_MODE_M680X_6811 = 1 << 8, ///< M680X Motorola/Freescale/NXP 68HC11 mode
|
||||
CS_MODE_M680X_CPU12 = 1 << 9, ///< M680X Motorola/Freescale/NXP CPU12
|
||||
///< used on M68HC12/HCS12
|
||||
CS_MODE_M680X_HCS08 = 1 << 10, ///< M680X Freescale/NXP HCS08 mode
|
||||
} cs_mode;
|
||||
|
||||
typedef void* (CAPSTONE_API *cs_malloc_t)(size_t size);
|
||||
typedef void* (CAPSTONE_API *cs_calloc_t)(size_t nmemb, size_t size);
|
||||
typedef void* (CAPSTONE_API *cs_realloc_t)(void *ptr, size_t size);
|
||||
typedef void (CAPSTONE_API *cs_free_t)(void *ptr);
|
||||
typedef int (CAPSTONE_API *cs_vsnprintf_t)(char *str, size_t size, const char *format, va_list ap);
|
||||
|
||||
|
||||
/// User-defined dynamic memory related functions: malloc/calloc/realloc/free/vsnprintf()
|
||||
/// By default, Capstone uses system's malloc(), calloc(), realloc(), free() & vsnprintf().
|
||||
typedef struct cs_opt_mem {
|
||||
cs_malloc_t malloc;
|
||||
cs_calloc_t calloc;
|
||||
cs_realloc_t realloc;
|
||||
cs_free_t free;
|
||||
cs_vsnprintf_t vsnprintf;
|
||||
} cs_opt_mem;
|
||||
|
||||
/// Customize mnemonic for instructions with alternative name.
|
||||
/// To reset existing customized instruction to its default mnemonic,
|
||||
/// call cs_option(CS_OPT_MNEMONIC) again with the same @id and NULL value
|
||||
/// for @mnemonic.
|
||||
typedef struct cs_opt_mnem {
|
||||
/// ID of instruction to be customized.
|
||||
unsigned int id;
|
||||
/// Customized instruction mnemonic.
|
||||
const char *mnemonic;
|
||||
} cs_opt_mnem;
|
||||
|
||||
/// Runtime option for the disassembled engine
|
||||
typedef enum cs_opt_type {
|
||||
CS_OPT_INVALID = 0, ///< No option specified
|
||||
CS_OPT_SYNTAX, ///< Assembly output syntax
|
||||
CS_OPT_DETAIL, ///< Break down instruction structure into details
|
||||
CS_OPT_MODE, ///< Change engine's mode at run-time
|
||||
CS_OPT_MEM, ///< User-defined dynamic memory related functions
|
||||
CS_OPT_SKIPDATA, ///< Skip data when disassembling. Then engine is in SKIPDATA mode.
|
||||
CS_OPT_SKIPDATA_SETUP, ///< Setup user-defined function for SKIPDATA option
|
||||
CS_OPT_MNEMONIC, ///< Customize instruction mnemonic
|
||||
CS_OPT_UNSIGNED, ///< print immediate operands in unsigned form
|
||||
} cs_opt_type;
|
||||
|
||||
/// Runtime option value (associated with option type above)
|
||||
typedef enum cs_opt_value {
|
||||
CS_OPT_OFF = 0, ///< Turn OFF an option - default for CS_OPT_DETAIL, CS_OPT_SKIPDATA, CS_OPT_UNSIGNED.
|
||||
CS_OPT_ON = 3, ///< Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
|
||||
CS_OPT_SYNTAX_DEFAULT = 0, ///< Default asm syntax (CS_OPT_SYNTAX).
|
||||
CS_OPT_SYNTAX_INTEL, ///< X86 Intel asm syntax - default on X86 (CS_OPT_SYNTAX).
|
||||
CS_OPT_SYNTAX_ATT, ///< X86 ATT asm syntax (CS_OPT_SYNTAX).
|
||||
CS_OPT_SYNTAX_NOREGNAME, ///< Prints register name with only number (CS_OPT_SYNTAX)
|
||||
CS_OPT_SYNTAX_MASM, ///< X86 Intel Masm syntax (CS_OPT_SYNTAX).
|
||||
} cs_opt_value;
|
||||
|
||||
/// Common instruction operand types - to be consistent across all architectures.
|
||||
typedef enum cs_op_type {
|
||||
CS_OP_INVALID = 0, ///< uninitialized/invalid operand.
|
||||
CS_OP_REG, ///< Register operand.
|
||||
CS_OP_IMM, ///< Immediate operand.
|
||||
CS_OP_MEM, ///< Memory operand.
|
||||
CS_OP_FP, ///< Floating-Point operand.
|
||||
} cs_op_type;
|
||||
|
||||
/// Common instruction operand access types - to be consistent across all architectures.
|
||||
/// It is possible to combine access types, for example: CS_AC_READ | CS_AC_WRITE
|
||||
typedef enum cs_ac_type {
|
||||
CS_AC_INVALID = 0, ///< Uninitialized/invalid access type.
|
||||
CS_AC_READ = 1 << 0, ///< Operand read from memory or register.
|
||||
CS_AC_WRITE = 1 << 1, ///< Operand write to memory or register.
|
||||
} cs_ac_type;
|
||||
|
||||
/// Common instruction groups - to be consistent across all architectures.
|
||||
typedef enum cs_group_type {
|
||||
CS_GRP_INVALID = 0, ///< uninitialized/invalid group.
|
||||
CS_GRP_JUMP, ///< all jump instructions (conditional+direct+indirect jumps)
|
||||
CS_GRP_CALL, ///< all call instructions
|
||||
CS_GRP_RET, ///< all return instructions
|
||||
CS_GRP_INT, ///< all interrupt instructions (int+syscall)
|
||||
CS_GRP_IRET, ///< all interrupt return instructions
|
||||
CS_GRP_PRIVILEGE, ///< all privileged instructions
|
||||
CS_GRP_BRANCH_RELATIVE, ///< all relative branching instructions
|
||||
} cs_group_type;
|
||||
|
||||
/**
|
||||
User-defined callback function for SKIPDATA option.
|
||||
See tests/test_skipdata.c for sample code demonstrating this API.
|
||||
|
||||
@code: the input buffer containing code to be disassembled.
|
||||
This is the same buffer passed to cs_disasm().
|
||||
@code_size: size (in bytes) of the above @code buffer.
|
||||
@offset: the position of the currently-examining byte in the input
|
||||
buffer @code mentioned above.
|
||||
@user_data: user-data passed to cs_option() via @user_data field in
|
||||
cs_opt_skipdata struct below.
|
||||
|
||||
@return: return number of bytes to skip, or 0 to immediately stop disassembling.
|
||||
*/
|
||||
typedef size_t (CAPSTONE_API *cs_skipdata_cb_t)(const uint8_t *code, size_t code_size, size_t offset, void *user_data);
|
||||
|
||||
/// User-customized setup for SKIPDATA option
|
||||
typedef struct cs_opt_skipdata {
|
||||
/// Capstone considers data to skip as special "instructions".
|
||||
/// User can specify the string for this instruction's "mnemonic" here.
|
||||
/// By default (if @mnemonic is NULL), Capstone use ".byte".
|
||||
const char *mnemonic;
|
||||
|
||||
/// User-defined callback function to be called when Capstone hits data.
|
||||
/// If the returned value from this callback is positive (>0), Capstone
|
||||
/// will skip exactly that number of bytes & continue. Otherwise, if
|
||||
/// the callback returns 0, Capstone stops disassembling and returns
|
||||
/// immediately from cs_disasm()
|
||||
/// NOTE: if this callback pointer is NULL, Capstone would skip a number
|
||||
/// of bytes depending on architectures, as following:
|
||||
/// Arm: 2 bytes (Thumb mode) or 4 bytes.
|
||||
/// Arm64: 4 bytes.
|
||||
/// Mips: 4 bytes.
|
||||
/// M680x: 1 byte.
|
||||
/// PowerPC: 4 bytes.
|
||||
/// Sparc: 4 bytes.
|
||||
/// SystemZ: 2 bytes.
|
||||
/// X86: 1 bytes.
|
||||
/// XCore: 2 bytes.
|
||||
/// EVM: 1 bytes.
|
||||
cs_skipdata_cb_t callback; // default value is NULL
|
||||
|
||||
/// User-defined data to be passed to @callback function pointer.
|
||||
void *user_data;
|
||||
} cs_opt_skipdata;
|
||||
|
||||
|
||||
#include "arm.h"
|
||||
#include "arm64.h"
|
||||
#include "m68k.h"
|
||||
#include "mips.h"
|
||||
#include "ppc.h"
|
||||
#include "sparc.h"
|
||||
#include "systemz.h"
|
||||
#include "x86.h"
|
||||
#include "xcore.h"
|
||||
#include "tms320c64x.h"
|
||||
#include "m680x.h"
|
||||
#include "evm.h"
|
||||
|
||||
/// NOTE: All information in cs_detail is only available when CS_OPT_DETAIL = CS_OPT_ON
|
||||
/// Initialized as memset(., 0, offsetof(cs_detail, ARCH)+sizeof(cs_ARCH))
|
||||
/// by ARCH_getInstruction in arch/ARCH/ARCHDisassembler.c
|
||||
/// if cs_detail changes, in particular if a field is added after the union,
|
||||
/// then update arch/ARCH/ARCHDisassembler.c accordingly
|
||||
typedef struct cs_detail {
|
||||
uint16_t regs_read[12]; ///< list of implicit registers read by this insn
|
||||
uint8_t regs_read_count; ///< number of implicit registers read by this insn
|
||||
|
||||
uint16_t regs_write[20]; ///< list of implicit registers modified by this insn
|
||||
uint8_t regs_write_count; ///< number of implicit registers modified by this insn
|
||||
|
||||
uint8_t groups[8]; ///< list of group this instruction belong to
|
||||
uint8_t groups_count; ///< number of groups this insn belongs to
|
||||
|
||||
/// Architecture-specific instruction info
|
||||
union {
|
||||
cs_x86 x86; ///< X86 architecture, including 16-bit, 32-bit & 64-bit mode
|
||||
cs_arm64 arm64; ///< ARM64 architecture (aka AArch64)
|
||||
cs_arm arm; ///< ARM architecture (including Thumb/Thumb2)
|
||||
cs_m68k m68k; ///< M68K architecture
|
||||
cs_mips mips; ///< MIPS architecture
|
||||
cs_ppc ppc; ///< PowerPC architecture
|
||||
cs_sparc sparc; ///< Sparc architecture
|
||||
cs_sysz sysz; ///< SystemZ architecture
|
||||
cs_xcore xcore; ///< XCore architecture
|
||||
cs_tms320c64x tms320c64x; ///< TMS320C64x architecture
|
||||
cs_m680x m680x; ///< M680X architecture
|
||||
cs_evm evm; ///< Ethereum architecture
|
||||
};
|
||||
} cs_detail;
|
||||
|
||||
/// Detail information of disassembled instruction
|
||||
typedef struct cs_insn {
|
||||
/// Instruction ID (basically a numeric ID for the instruction mnemonic)
|
||||
/// Find the instruction id in the '[ARCH]_insn' enum in the header file
|
||||
/// of corresponding architecture, such as 'arm_insn' in arm.h for ARM,
|
||||
/// 'x86_insn' in x86.h for X86, etc...
|
||||
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
|
||||
/// NOTE: in Skipdata mode, "data" instruction has 0 for this id field.
|
||||
unsigned int id;
|
||||
|
||||
/// Address (EIP) of this instruction
|
||||
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
|
||||
uint64_t address;
|
||||
|
||||
/// Size of this instruction
|
||||
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
|
||||
uint16_t size;
|
||||
|
||||
/// Machine bytes of this instruction, with number of bytes indicated by @size above
|
||||
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
|
||||
uint8_t bytes[16];
|
||||
|
||||
/// Ascii text of instruction mnemonic
|
||||
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
|
||||
char mnemonic[CS_MNEMONIC_SIZE];
|
||||
|
||||
/// Ascii text of instruction operands
|
||||
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
|
||||
char op_str[160];
|
||||
|
||||
/// Pointer to cs_detail.
|
||||
/// NOTE: detail pointer is only valid when both requirements below are met:
|
||||
/// (1) CS_OP_DETAIL = CS_OPT_ON
|
||||
/// (2) Engine is not in Skipdata mode (CS_OP_SKIPDATA option set to CS_OPT_ON)
|
||||
///
|
||||
/// NOTE 2: when in Skipdata mode, or when detail mode is OFF, even if this pointer
|
||||
/// is not NULL, its content is still irrelevant.
|
||||
cs_detail *detail;
|
||||
} cs_insn;
|
||||
|
||||
|
||||
/// Calculate the offset of a disassembled instruction in its buffer, given its position
|
||||
/// in its array of disassembled insn
|
||||
/// NOTE: this macro works with position (>=1), not index
|
||||
#define CS_INSN_OFFSET(insns, post) (insns[post - 1].address - insns[0].address)
|
||||
|
||||
|
||||
/// All type of errors encountered by Capstone API.
|
||||
/// These are values returned by cs_errno()
|
||||
typedef enum cs_err {
|
||||
CS_ERR_OK = 0, ///< No error: everything was fine
|
||||
CS_ERR_MEM, ///< Out-Of-Memory error: cs_open(), cs_disasm(), cs_disasm_iter()
|
||||
CS_ERR_ARCH, ///< Unsupported architecture: cs_open()
|
||||
CS_ERR_HANDLE, ///< Invalid handle: cs_op_count(), cs_op_index()
|
||||
CS_ERR_CSH, ///< Invalid csh argument: cs_close(), cs_errno(), cs_option()
|
||||
CS_ERR_MODE, ///< Invalid/unsupported mode: cs_open()
|
||||
CS_ERR_OPTION, ///< Invalid/unsupported option: cs_option()
|
||||
CS_ERR_DETAIL, ///< Information is unavailable because detail option is OFF
|
||||
CS_ERR_MEMSETUP, ///< Dynamic memory management uninitialized (see CS_OPT_MEM)
|
||||
CS_ERR_VERSION, ///< Unsupported version (bindings)
|
||||
CS_ERR_DIET, ///< Access irrelevant data in "diet" engine
|
||||
CS_ERR_SKIPDATA, ///< Access irrelevant data for "data" instruction in SKIPDATA mode
|
||||
CS_ERR_X86_ATT, ///< X86 AT&T syntax is unsupported (opt-out at compile time)
|
||||
CS_ERR_X86_INTEL, ///< X86 Intel syntax is unsupported (opt-out at compile time)
|
||||
CS_ERR_X86_MASM, ///< X86 Masm syntax is unsupported (opt-out at compile time)
|
||||
} cs_err;
|
||||
|
||||
/**
|
||||
Return combined API version & major and minor version numbers.
|
||||
|
||||
@major: major number of API version
|
||||
@minor: minor number of API version
|
||||
|
||||
@return hexical number as (major << 8 | minor), which encodes both
|
||||
major & minor versions.
|
||||
NOTE: This returned value can be compared with version number made
|
||||
with macro CS_MAKE_VERSION
|
||||
|
||||
For example, second API version would return 1 in @major, and 1 in @minor
|
||||
The return value would be 0x0101
|
||||
|
||||
NOTE: if you only care about returned value, but not major and minor values,
|
||||
set both @major & @minor arguments to NULL.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
unsigned int CAPSTONE_API cs_version(int *major, int *minor);
|
||||
|
||||
|
||||
/**
|
||||
This API can be used to either ask for archs supported by this library,
|
||||
or check to see if the library was compile with 'diet' option (or called
|
||||
in 'diet' mode).
|
||||
|
||||
To check if a particular arch is supported by this library, set @query to
|
||||
arch mode (CS_ARCH_* value).
|
||||
To verify if this library supports all the archs, use CS_ARCH_ALL.
|
||||
|
||||
To check if this library is in 'diet' mode, set @query to CS_SUPPORT_DIET.
|
||||
|
||||
@return True if this library supports the given arch, or in 'diet' mode.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
bool CAPSTONE_API cs_support(int query);
|
||||
|
||||
/**
|
||||
Initialize CS handle: this must be done before any usage of CS.
|
||||
|
||||
@arch: architecture type (CS_ARCH_*)
|
||||
@mode: hardware mode. This is combined of CS_MODE_*
|
||||
@handle: pointer to handle, which will be updated at return time
|
||||
|
||||
@return CS_ERR_OK on success, or other value on failure (refer to cs_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle);
|
||||
|
||||
/**
|
||||
Close CS handle: MUST do to release the handle when it is not used anymore.
|
||||
NOTE: this must be only called when there is no longer usage of Capstone,
|
||||
not even access to cs_insn array. The reason is the this API releases some
|
||||
cached memory, thus access to any Capstone API after cs_close() might crash
|
||||
your application.
|
||||
|
||||
In fact,this API invalidate @handle by ZERO out its value (i.e *handle = 0).
|
||||
|
||||
@handle: pointer to a handle returned by cs_open()
|
||||
|
||||
@return CS_ERR_OK on success, or other value on failure (refer to cs_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_close(csh *handle);
|
||||
|
||||
/**
|
||||
Set option for disassembling engine at runtime
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@type: type of option to be set
|
||||
@value: option value corresponding with @type
|
||||
|
||||
@return: CS_ERR_OK on success, or other value on failure.
|
||||
Refer to cs_err enum for detailed error.
|
||||
|
||||
NOTE: in the case of CS_OPT_MEM, handle's value can be anything,
|
||||
so that cs_option(handle, CS_OPT_MEM, value) can (i.e must) be called
|
||||
even before cs_open()
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_option(csh handle, cs_opt_type type, size_t value);
|
||||
|
||||
/**
|
||||
Report the last error number when some API function fail.
|
||||
Like glibc's errno, cs_errno might not retain its old value once accessed.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
|
||||
@return: error code of cs_err enum type (CS_ERR_*, see above)
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_errno(csh handle);
|
||||
|
||||
|
||||
/**
|
||||
Return a string describing given error code.
|
||||
|
||||
@code: error code (see CS_ERR_* above)
|
||||
|
||||
@return: returns a pointer to a string that describes the error code
|
||||
passed in the argument @code
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
const char * CAPSTONE_API cs_strerror(cs_err code);
|
||||
|
||||
/**
|
||||
Disassemble binary code, given the code buffer, size, address and number
|
||||
of instructions to be decoded.
|
||||
This API dynamically allocate memory to contain disassembled instruction.
|
||||
Resulting instructions will be put into @*insn
|
||||
|
||||
NOTE 1: this API will automatically determine memory needed to contain
|
||||
output disassembled instructions in @insn.
|
||||
|
||||
NOTE 2: caller must free the allocated memory itself to avoid memory leaking.
|
||||
|
||||
NOTE 3: for system with scarce memory to be dynamically allocated such as
|
||||
OS kernel or firmware, the API cs_disasm_iter() might be a better choice than
|
||||
cs_disasm(). The reason is that with cs_disasm(), based on limited available
|
||||
memory, we have to calculate in advance how many instructions to be disassembled,
|
||||
which complicates things. This is especially troublesome for the case @count=0,
|
||||
when cs_disasm() runs uncontrollably (until either end of input buffer, or
|
||||
when it encounters an invalid instruction).
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@code: buffer containing raw binary code to be disassembled.
|
||||
@code_size: size of the above code buffer.
|
||||
@address: address of the first instruction in given raw code buffer.
|
||||
@insn: array of instructions filled in by this API.
|
||||
NOTE: @insn will be allocated by this function, and should be freed
|
||||
with cs_free() API.
|
||||
@count: number of instructions to be disassembled, or 0 to get all of them
|
||||
|
||||
@return: the number of successfully disassembled instructions,
|
||||
or 0 if this function failed to disassemble the given code
|
||||
|
||||
On failure, call cs_errno() for error code.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
size_t CAPSTONE_API cs_disasm(csh handle,
|
||||
const uint8_t *code, size_t code_size,
|
||||
uint64_t address,
|
||||
size_t count,
|
||||
cs_insn **insn);
|
||||
|
||||
/**
|
||||
Deprecated function - to be retired in the next version!
|
||||
Use cs_disasm() instead of cs_disasm_ex()
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
CAPSTONE_DEPRECATED
|
||||
size_t CAPSTONE_API cs_disasm_ex(csh handle,
|
||||
const uint8_t *code, size_t code_size,
|
||||
uint64_t address,
|
||||
size_t count,
|
||||
cs_insn **insn);
|
||||
|
||||
/**
|
||||
Free memory allocated by cs_malloc() or cs_disasm() (argument @insn)
|
||||
|
||||
@insn: pointer returned by @insn argument in cs_disasm() or cs_malloc()
|
||||
@count: number of cs_insn structures returned by cs_disasm(), or 1
|
||||
to free memory allocated by cs_malloc().
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
void CAPSTONE_API cs_free(cs_insn *insn, size_t count);
|
||||
|
||||
|
||||
/**
|
||||
Allocate memory for 1 instruction to be used by cs_disasm_iter().
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
|
||||
NOTE: when no longer in use, you can reclaim the memory allocated for
|
||||
this instruction with cs_free(insn, 1)
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_insn * CAPSTONE_API cs_malloc(csh handle);
|
||||
|
||||
/**
|
||||
Fast API to disassemble binary code, given the code buffer, size, address
|
||||
and number of instructions to be decoded.
|
||||
This API puts the resulting instruction into a given cache in @insn.
|
||||
See tests/test_iter.c for sample code demonstrating this API.
|
||||
|
||||
NOTE 1: this API will update @code, @size & @address to point to the next
|
||||
instruction in the input buffer. Therefore, it is convenient to use
|
||||
cs_disasm_iter() inside a loop to quickly iterate all the instructions.
|
||||
While decoding one instruction at a time can also be achieved with
|
||||
cs_disasm(count=1), some benchmarks shown that cs_disasm_iter() can be 30%
|
||||
faster on random input.
|
||||
|
||||
NOTE 2: the cache in @insn can be created with cs_malloc() API.
|
||||
|
||||
NOTE 3: for system with scarce memory to be dynamically allocated such as
|
||||
OS kernel or firmware, this API is recommended over cs_disasm(), which
|
||||
allocates memory based on the number of instructions to be disassembled.
|
||||
The reason is that with cs_disasm(), based on limited available memory,
|
||||
we have to calculate in advance how many instructions to be disassembled,
|
||||
which complicates things. This is especially troublesome for the case
|
||||
@count=0, when cs_disasm() runs uncontrollably (until either end of input
|
||||
buffer, or when it encounters an invalid instruction).
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@code: buffer containing raw binary code to be disassembled
|
||||
@size: size of above code
|
||||
@address: address of the first insn in given raw code buffer
|
||||
@insn: pointer to instruction to be filled in by this API.
|
||||
|
||||
@return: true if this API successfully decode 1 instruction,
|
||||
or false otherwise.
|
||||
|
||||
On failure, call cs_errno() for error code.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
bool CAPSTONE_API cs_disasm_iter(csh handle,
|
||||
const uint8_t **code, size_t *size,
|
||||
uint64_t *address, cs_insn *insn);
|
||||
|
||||
/**
|
||||
Return friendly name of register in a string.
|
||||
Find the instruction id from header file of corresponding architecture (arm.h for ARM,
|
||||
x86.h for X86, ...)
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because engine does not
|
||||
store register name.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@reg_id: register id
|
||||
|
||||
@return: string name of the register, or NULL if @reg_id is invalid.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
const char * CAPSTONE_API cs_reg_name(csh handle, unsigned int reg_id);
|
||||
|
||||
/**
|
||||
Return friendly name of an instruction in a string.
|
||||
Find the instruction id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because the engine does not
|
||||
store instruction name.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@insn_id: instruction id
|
||||
|
||||
@return: string name of the instruction, or NULL if @insn_id is invalid.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
const char * CAPSTONE_API cs_insn_name(csh handle, unsigned int insn_id);
|
||||
|
||||
/**
|
||||
Return friendly name of a group id (that an instruction can belong to)
|
||||
Find the group id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because the engine does not
|
||||
store group name.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@group_id: group id
|
||||
|
||||
@return: string name of the group, or NULL if @group_id is invalid.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
const char * CAPSTONE_API cs_group_name(csh handle, unsigned int group_id);
|
||||
|
||||
/**
|
||||
Check if a disassembled instruction belong to a particular group.
|
||||
Find the group id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
Internally, this simply verifies if @group_id matches any member of insn->groups array.
|
||||
|
||||
NOTE: this API is only valid when detail option is ON (which is OFF by default).
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because the engine does not
|
||||
update @groups array.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter()
|
||||
@group_id: group that you want to check if this instruction belong to.
|
||||
|
||||
@return: true if this instruction indeed belongs to the given group, or false otherwise.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
bool CAPSTONE_API cs_insn_group(csh handle, const cs_insn *insn, unsigned int group_id);
|
||||
|
||||
/**
|
||||
Check if a disassembled instruction IMPLICITLY used a particular register.
|
||||
Find the register id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
Internally, this simply verifies if @reg_id matches any member of insn->regs_read array.
|
||||
|
||||
NOTE: this API is only valid when detail option is ON (which is OFF by default)
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because the engine does not
|
||||
update @regs_read array.
|
||||
|
||||
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter()
|
||||
@reg_id: register that you want to check if this instruction used it.
|
||||
|
||||
@return: true if this instruction indeed implicitly used the given register, or false otherwise.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
bool CAPSTONE_API cs_reg_read(csh handle, const cs_insn *insn, unsigned int reg_id);
|
||||
|
||||
/**
|
||||
Check if a disassembled instruction IMPLICITLY modified a particular register.
|
||||
Find the register id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
Internally, this simply verifies if @reg_id matches any member of insn->regs_write array.
|
||||
|
||||
NOTE: this API is only valid when detail option is ON (which is OFF by default)
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because the engine does not
|
||||
update @regs_write array.
|
||||
|
||||
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter()
|
||||
@reg_id: register that you want to check if this instruction modified it.
|
||||
|
||||
@return: true if this instruction indeed implicitly modified the given register, or false otherwise.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
bool CAPSTONE_API cs_reg_write(csh handle, const cs_insn *insn, unsigned int reg_id);
|
||||
|
||||
/**
|
||||
Count the number of operands of a given type.
|
||||
Find the operand type in header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
|
||||
NOTE: this API is only valid when detail option is ON (which is OFF by default)
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter()
|
||||
@op_type: Operand type to be found.
|
||||
|
||||
@return: number of operands of given type @op_type in instruction @insn,
|
||||
or -1 on failure.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
int CAPSTONE_API cs_op_count(csh handle, const cs_insn *insn, unsigned int op_type);
|
||||
|
||||
/**
|
||||
Retrieve the position of operand of given type in <arch>.operands[] array.
|
||||
Later, the operand can be accessed using the returned position.
|
||||
Find the operand type in header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
|
||||
NOTE: this API is only valid when detail option is ON (which is OFF by default)
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter()
|
||||
@op_type: Operand type to be found.
|
||||
@position: position of the operand to be found. This must be in the range
|
||||
[1, cs_op_count(handle, insn, op_type)]
|
||||
|
||||
@return: index of operand of given type @op_type in <arch>.operands[] array
|
||||
in instruction @insn, or -1 on failure.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
int CAPSTONE_API cs_op_index(csh handle, const cs_insn *insn, unsigned int op_type,
|
||||
unsigned int position);
|
||||
|
||||
/// Type of array to keep the list of registers
|
||||
typedef uint16_t cs_regs[64];
|
||||
|
||||
/**
|
||||
Retrieve all the registers accessed by an instruction, either explicitly or
|
||||
implicitly.
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because engine does not
|
||||
store registers.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@insn: disassembled instruction structure returned from cs_disasm() or cs_disasm_iter()
|
||||
@regs_read: on return, this array contains all registers read by instruction.
|
||||
@regs_read_count: number of registers kept inside @regs_read array.
|
||||
@regs_write: on return, this array contains all registers written by instruction.
|
||||
@regs_write_count: number of registers kept inside @regs_write array.
|
||||
|
||||
@return CS_ERR_OK on success, or other value on failure (refer to cs_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_regs_access(csh handle, const cs_insn *insn,
|
||||
cs_regs regs_read, uint8_t *regs_read_count,
|
||||
cs_regs regs_write, uint8_t *regs_write_count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
188
ai_anti_malware/capstone/include/capstone/evm.h
Normal file
188
ai_anti_malware/capstone/include/capstone/evm.h
Normal file
@@ -0,0 +1,188 @@
|
||||
#ifndef CAPSTONE_EVM_H
|
||||
#define CAPSTONE_EVM_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2018 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// Instruction structure
|
||||
typedef struct cs_evm {
|
||||
unsigned char pop; ///< number of items popped from the stack
|
||||
unsigned char push; ///< number of items pushed into the stack
|
||||
unsigned int fee; ///< gas fee for the instruction
|
||||
} cs_evm;
|
||||
|
||||
/// EVM instruction
|
||||
typedef enum evm_insn {
|
||||
EVM_INS_STOP = 0,
|
||||
EVM_INS_ADD = 1,
|
||||
EVM_INS_MUL = 2,
|
||||
EVM_INS_SUB = 3,
|
||||
EVM_INS_DIV = 4,
|
||||
EVM_INS_SDIV = 5,
|
||||
EVM_INS_MOD = 6,
|
||||
EVM_INS_SMOD = 7,
|
||||
EVM_INS_ADDMOD = 8,
|
||||
EVM_INS_MULMOD = 9,
|
||||
EVM_INS_EXP = 10,
|
||||
EVM_INS_SIGNEXTEND = 11,
|
||||
EVM_INS_LT = 16,
|
||||
EVM_INS_GT = 17,
|
||||
EVM_INS_SLT = 18,
|
||||
EVM_INS_SGT = 19,
|
||||
EVM_INS_EQ = 20,
|
||||
EVM_INS_ISZERO = 21,
|
||||
EVM_INS_AND = 22,
|
||||
EVM_INS_OR = 23,
|
||||
EVM_INS_XOR = 24,
|
||||
EVM_INS_NOT = 25,
|
||||
EVM_INS_BYTE = 26,
|
||||
EVM_INS_SHA3 = 32,
|
||||
EVM_INS_ADDRESS = 48,
|
||||
EVM_INS_BALANCE = 49,
|
||||
EVM_INS_ORIGIN = 50,
|
||||
EVM_INS_CALLER = 51,
|
||||
EVM_INS_CALLVALUE = 52,
|
||||
EVM_INS_CALLDATALOAD = 53,
|
||||
EVM_INS_CALLDATASIZE = 54,
|
||||
EVM_INS_CALLDATACOPY = 55,
|
||||
EVM_INS_CODESIZE = 56,
|
||||
EVM_INS_CODECOPY = 57,
|
||||
EVM_INS_GASPRICE = 58,
|
||||
EVM_INS_EXTCODESIZE = 59,
|
||||
EVM_INS_EXTCODECOPY = 60,
|
||||
EVM_INS_RETURNDATASIZE = 61,
|
||||
EVM_INS_RETURNDATACOPY = 62,
|
||||
EVM_INS_BLOCKHASH = 64,
|
||||
EVM_INS_COINBASE = 65,
|
||||
EVM_INS_TIMESTAMP = 66,
|
||||
EVM_INS_NUMBER = 67,
|
||||
EVM_INS_DIFFICULTY = 68,
|
||||
EVM_INS_GASLIMIT = 69,
|
||||
EVM_INS_POP = 80,
|
||||
EVM_INS_MLOAD = 81,
|
||||
EVM_INS_MSTORE = 82,
|
||||
EVM_INS_MSTORE8 = 83,
|
||||
EVM_INS_SLOAD = 84,
|
||||
EVM_INS_SSTORE = 85,
|
||||
EVM_INS_JUMP = 86,
|
||||
EVM_INS_JUMPI = 87,
|
||||
EVM_INS_PC = 88,
|
||||
EVM_INS_MSIZE = 89,
|
||||
EVM_INS_GAS = 90,
|
||||
EVM_INS_JUMPDEST = 91,
|
||||
EVM_INS_PUSH1 = 96,
|
||||
EVM_INS_PUSH2 = 97,
|
||||
EVM_INS_PUSH3 = 98,
|
||||
EVM_INS_PUSH4 = 99,
|
||||
EVM_INS_PUSH5 = 100,
|
||||
EVM_INS_PUSH6 = 101,
|
||||
EVM_INS_PUSH7 = 102,
|
||||
EVM_INS_PUSH8 = 103,
|
||||
EVM_INS_PUSH9 = 104,
|
||||
EVM_INS_PUSH10 = 105,
|
||||
EVM_INS_PUSH11 = 106,
|
||||
EVM_INS_PUSH12 = 107,
|
||||
EVM_INS_PUSH13 = 108,
|
||||
EVM_INS_PUSH14 = 109,
|
||||
EVM_INS_PUSH15 = 110,
|
||||
EVM_INS_PUSH16 = 111,
|
||||
EVM_INS_PUSH17 = 112,
|
||||
EVM_INS_PUSH18 = 113,
|
||||
EVM_INS_PUSH19 = 114,
|
||||
EVM_INS_PUSH20 = 115,
|
||||
EVM_INS_PUSH21 = 116,
|
||||
EVM_INS_PUSH22 = 117,
|
||||
EVM_INS_PUSH23 = 118,
|
||||
EVM_INS_PUSH24 = 119,
|
||||
EVM_INS_PUSH25 = 120,
|
||||
EVM_INS_PUSH26 = 121,
|
||||
EVM_INS_PUSH27 = 122,
|
||||
EVM_INS_PUSH28 = 123,
|
||||
EVM_INS_PUSH29 = 124,
|
||||
EVM_INS_PUSH30 = 125,
|
||||
EVM_INS_PUSH31 = 126,
|
||||
EVM_INS_PUSH32 = 127,
|
||||
EVM_INS_DUP1 = 128,
|
||||
EVM_INS_DUP2 = 129,
|
||||
EVM_INS_DUP3 = 130,
|
||||
EVM_INS_DUP4 = 131,
|
||||
EVM_INS_DUP5 = 132,
|
||||
EVM_INS_DUP6 = 133,
|
||||
EVM_INS_DUP7 = 134,
|
||||
EVM_INS_DUP8 = 135,
|
||||
EVM_INS_DUP9 = 136,
|
||||
EVM_INS_DUP10 = 137,
|
||||
EVM_INS_DUP11 = 138,
|
||||
EVM_INS_DUP12 = 139,
|
||||
EVM_INS_DUP13 = 140,
|
||||
EVM_INS_DUP14 = 141,
|
||||
EVM_INS_DUP15 = 142,
|
||||
EVM_INS_DUP16 = 143,
|
||||
EVM_INS_SWAP1 = 144,
|
||||
EVM_INS_SWAP2 = 145,
|
||||
EVM_INS_SWAP3 = 146,
|
||||
EVM_INS_SWAP4 = 147,
|
||||
EVM_INS_SWAP5 = 148,
|
||||
EVM_INS_SWAP6 = 149,
|
||||
EVM_INS_SWAP7 = 150,
|
||||
EVM_INS_SWAP8 = 151,
|
||||
EVM_INS_SWAP9 = 152,
|
||||
EVM_INS_SWAP10 = 153,
|
||||
EVM_INS_SWAP11 = 154,
|
||||
EVM_INS_SWAP12 = 155,
|
||||
EVM_INS_SWAP13 = 156,
|
||||
EVM_INS_SWAP14 = 157,
|
||||
EVM_INS_SWAP15 = 158,
|
||||
EVM_INS_SWAP16 = 159,
|
||||
EVM_INS_LOG0 = 160,
|
||||
EVM_INS_LOG1 = 161,
|
||||
EVM_INS_LOG2 = 162,
|
||||
EVM_INS_LOG3 = 163,
|
||||
EVM_INS_LOG4 = 164,
|
||||
EVM_INS_CREATE = 240,
|
||||
EVM_INS_CALL = 241,
|
||||
EVM_INS_CALLCODE = 242,
|
||||
EVM_INS_RETURN = 243,
|
||||
EVM_INS_DELEGATECALL = 244,
|
||||
EVM_INS_CALLBLACKBOX = 245,
|
||||
EVM_INS_STATICCALL = 250,
|
||||
EVM_INS_REVERT = 253,
|
||||
EVM_INS_SUICIDE = 255,
|
||||
|
||||
EVM_INS_INVALID = 512,
|
||||
EVM_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} evm_insn;
|
||||
|
||||
/// Group of EVM instructions
|
||||
typedef enum evm_insn_group {
|
||||
EVM_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
EVM_GRP_JUMP, ///< all jump instructions
|
||||
|
||||
EVM_GRP_MATH = 8, ///< math instructions
|
||||
EVM_GRP_STACK_WRITE, ///< instructions write to stack
|
||||
EVM_GRP_STACK_READ, ///< instructions read from stack
|
||||
EVM_GRP_MEM_WRITE, ///< instructions write to memory
|
||||
EVM_GRP_MEM_READ, ///< instructions read from memory
|
||||
EVM_GRP_STORE_WRITE, ///< instructions write to storage
|
||||
EVM_GRP_STORE_READ, ///< instructions read from storage
|
||||
EVM_GRP_HALT, ///< instructions halt execution
|
||||
|
||||
EVM_GRP_ENDING, ///< <-- mark the end of the list of groups
|
||||
} evm_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
537
ai_anti_malware/capstone/include/capstone/m680x.h
Normal file
537
ai_anti_malware/capstone/include/capstone/m680x.h
Normal file
@@ -0,0 +1,537 @@
|
||||
#ifndef CAPSTONE_M680X_H
|
||||
#define CAPSTONE_M680X_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
#define M680X_OPERAND_COUNT 9
|
||||
|
||||
/// M680X registers and special registers
|
||||
typedef enum m680x_reg {
|
||||
M680X_REG_INVALID = 0,
|
||||
|
||||
M680X_REG_A, ///< M6800/1/2/3/9, HD6301/9
|
||||
M680X_REG_B, ///< M6800/1/2/3/9, HD6301/9
|
||||
M680X_REG_E, ///< HD6309
|
||||
M680X_REG_F, ///< HD6309
|
||||
M680X_REG_0, ///< HD6309
|
||||
|
||||
M680X_REG_D, ///< M6801/3/9, HD6301/9
|
||||
M680X_REG_W, ///< HD6309
|
||||
|
||||
M680X_REG_CC, ///< M6800/1/2/3/9, M6301/9
|
||||
M680X_REG_DP, ///< M6809/M6309
|
||||
M680X_REG_MD, ///< M6309
|
||||
|
||||
M680X_REG_HX, ///< M6808
|
||||
M680X_REG_H, ///< M6808
|
||||
M680X_REG_X, ///< M6800/1/2/3/9, M6301/9
|
||||
M680X_REG_Y, ///< M6809/M6309
|
||||
M680X_REG_S, ///< M6809/M6309
|
||||
M680X_REG_U, ///< M6809/M6309
|
||||
M680X_REG_V, ///< M6309
|
||||
|
||||
M680X_REG_Q, ///< M6309
|
||||
|
||||
M680X_REG_PC, ///< M6800/1/2/3/9, M6301/9
|
||||
|
||||
M680X_REG_TMP2, ///< CPU12
|
||||
M680X_REG_TMP3, ///< CPU12
|
||||
|
||||
M680X_REG_ENDING, ///< <-- mark the end of the list of registers
|
||||
} m680x_reg;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum m680x_op_type {
|
||||
M680X_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
M680X_OP_REGISTER, ///< = Register operand.
|
||||
M680X_OP_IMMEDIATE, ///< = Immediate operand.
|
||||
M680X_OP_INDEXED, ///< = Indexed addressing operand.
|
||||
M680X_OP_EXTENDED, ///< = Extended addressing operand.
|
||||
M680X_OP_DIRECT, ///< = Direct addressing operand.
|
||||
M680X_OP_RELATIVE, ///< = Relative addressing operand.
|
||||
M680X_OP_CONSTANT, ///< = constant operand (Displayed as number only).
|
||||
///< Used e.g. for a bit index or page number.
|
||||
} m680x_op_type;
|
||||
|
||||
// Supported bit values for mem.idx.offset_bits
|
||||
#define M680X_OFFSET_NONE 0
|
||||
#define M680X_OFFSET_BITS_5 5
|
||||
#define M680X_OFFSET_BITS_8 8
|
||||
#define M680X_OFFSET_BITS_9 9
|
||||
#define M680X_OFFSET_BITS_16 16
|
||||
|
||||
// Supported bit flags for mem.idx.flags
|
||||
// These flags can be combined
|
||||
#define M680X_IDX_INDIRECT 1
|
||||
#define M680X_IDX_NO_COMMA 2
|
||||
#define M680X_IDX_POST_INC_DEC 4
|
||||
|
||||
/// Instruction's operand referring to indexed addressing
|
||||
typedef struct m680x_op_idx {
|
||||
m680x_reg base_reg; ///< base register (or M680X_REG_INVALID if
|
||||
///< irrelevant)
|
||||
m680x_reg offset_reg; ///< offset register (or M680X_REG_INVALID if
|
||||
///< irrelevant)
|
||||
int16_t offset; ///< 5-,8- or 16-bit offset. See also offset_bits.
|
||||
uint16_t offset_addr; ///< = offset addr. if base_reg == M680X_REG_PC.
|
||||
///< calculated as offset + PC
|
||||
uint8_t offset_bits; ///< offset width in bits for indexed addressing
|
||||
int8_t inc_dec; ///< inc. or dec. value:
|
||||
///< 0: no inc-/decrement
|
||||
///< 1 .. 8: increment by 1 .. 8
|
||||
///< -1 .. -8: decrement by 1 .. 8
|
||||
///< if flag M680X_IDX_POST_INC_DEC set it is post
|
||||
///< inc-/decrement otherwise pre inc-/decrement
|
||||
uint8_t flags; ///< 8-bit flags (see above)
|
||||
} m680x_op_idx;
|
||||
|
||||
/// Instruction's memory operand referring to relative addressing (Bcc/LBcc)
|
||||
typedef struct m680x_op_rel {
|
||||
uint16_t address; ///< The absolute address.
|
||||
///< calculated as PC + offset. PC is the first
|
||||
///< address after the instruction.
|
||||
int16_t offset; ///< the offset/displacement value
|
||||
} m680x_op_rel;
|
||||
|
||||
/// Instruction's operand referring to extended addressing
|
||||
typedef struct m680x_op_ext {
|
||||
uint16_t address; ///< The absolute address
|
||||
bool indirect; ///< true if extended indirect addressing
|
||||
} m680x_op_ext;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_m680x_op {
|
||||
m680x_op_type type;
|
||||
union {
|
||||
int32_t imm; ///< immediate value for IMM operand
|
||||
m680x_reg reg; ///< register value for REG operand
|
||||
m680x_op_idx idx; ///< Indexed addressing operand
|
||||
m680x_op_rel rel; ///< Relative address. operand (Bcc/LBcc)
|
||||
m680x_op_ext ext; ///< Extended address
|
||||
uint8_t direct_addr; ///<</ Direct address (lower 8-bit)
|
||||
uint8_t const_val; ///< constant value (bit index, page nr.)
|
||||
};
|
||||
uint8_t size; ///< size of this operand (in bytes)
|
||||
/// How is this operand accessed? (READ, WRITE or READ|WRITE)
|
||||
/// This field is combined of cs_ac_type.
|
||||
/// NOTE: this field is irrelevant if engine is compiled in DIET
|
||||
uint8_t access;
|
||||
} cs_m680x_op;
|
||||
|
||||
/// Group of M680X instructions
|
||||
typedef enum m680x_group_type {
|
||||
M680X_GRP_INVALID = 0, /// = CS_GRP_INVALID
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
M680X_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
// all call instructions
|
||||
M680X_GRP_CALL, ///< = CS_GRP_CALL
|
||||
// all return instructions
|
||||
M680X_GRP_RET, ///< = CS_GRP_RET
|
||||
// all interrupt instructions (int+syscall)
|
||||
M680X_GRP_INT, ///< = CS_GRP_INT
|
||||
// all interrupt return instructions
|
||||
M680X_GRP_IRET, ///< = CS_GRP_IRET
|
||||
// all privileged instructions
|
||||
M680X_GRP_PRIV, ///< = CS_GRP_PRIVILEDGE; not used
|
||||
// all relative branching instructions
|
||||
M680X_GRP_BRAREL, ///< = CS_GRP_BRANCH_RELATIVE
|
||||
|
||||
// Architecture-specific groups
|
||||
M680X_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} m680x_group_type;
|
||||
|
||||
// M680X instruction flags:
|
||||
|
||||
/// The first (register) operand is part of the
|
||||
/// instruction mnemonic
|
||||
#define M680X_FIRST_OP_IN_MNEM 1
|
||||
/// The second (register) operand is part of the
|
||||
/// instruction mnemonic
|
||||
#define M680X_SECOND_OP_IN_MNEM 2
|
||||
|
||||
/// The M680X instruction and it's operands
|
||||
typedef struct cs_m680x {
|
||||
uint8_t flags; ///< See: M680X instruction flags
|
||||
uint8_t op_count; ///< number of operands for the instruction or 0
|
||||
cs_m680x_op operands[M680X_OPERAND_COUNT]; ///< operands for this insn.
|
||||
} cs_m680x;
|
||||
|
||||
/// M680X instruction IDs
|
||||
typedef enum m680x_insn {
|
||||
M680X_INS_INVLD = 0,
|
||||
M680X_INS_ABA, ///< M6800/1/2/3
|
||||
M680X_INS_ABX,
|
||||
M680X_INS_ABY,
|
||||
M680X_INS_ADC,
|
||||
M680X_INS_ADCA,
|
||||
M680X_INS_ADCB,
|
||||
M680X_INS_ADCD,
|
||||
M680X_INS_ADCR,
|
||||
M680X_INS_ADD,
|
||||
M680X_INS_ADDA,
|
||||
M680X_INS_ADDB,
|
||||
M680X_INS_ADDD,
|
||||
M680X_INS_ADDE,
|
||||
M680X_INS_ADDF,
|
||||
M680X_INS_ADDR,
|
||||
M680X_INS_ADDW,
|
||||
M680X_INS_AIM,
|
||||
M680X_INS_AIS,
|
||||
M680X_INS_AIX,
|
||||
M680X_INS_AND,
|
||||
M680X_INS_ANDA,
|
||||
M680X_INS_ANDB,
|
||||
M680X_INS_ANDCC,
|
||||
M680X_INS_ANDD,
|
||||
M680X_INS_ANDR,
|
||||
M680X_INS_ASL,
|
||||
M680X_INS_ASLA,
|
||||
M680X_INS_ASLB,
|
||||
M680X_INS_ASLD, ///< or LSLD
|
||||
M680X_INS_ASR,
|
||||
M680X_INS_ASRA,
|
||||
M680X_INS_ASRB,
|
||||
M680X_INS_ASRD,
|
||||
M680X_INS_ASRX,
|
||||
M680X_INS_BAND,
|
||||
M680X_INS_BCC, ///< or BHS
|
||||
M680X_INS_BCLR,
|
||||
M680X_INS_BCS, ///< or BLO
|
||||
M680X_INS_BEOR,
|
||||
M680X_INS_BEQ,
|
||||
M680X_INS_BGE,
|
||||
M680X_INS_BGND,
|
||||
M680X_INS_BGT,
|
||||
M680X_INS_BHCC,
|
||||
M680X_INS_BHCS,
|
||||
M680X_INS_BHI,
|
||||
M680X_INS_BIAND,
|
||||
M680X_INS_BIEOR,
|
||||
M680X_INS_BIH,
|
||||
M680X_INS_BIL,
|
||||
M680X_INS_BIOR,
|
||||
M680X_INS_BIT,
|
||||
M680X_INS_BITA,
|
||||
M680X_INS_BITB,
|
||||
M680X_INS_BITD,
|
||||
M680X_INS_BITMD,
|
||||
M680X_INS_BLE,
|
||||
M680X_INS_BLS,
|
||||
M680X_INS_BLT,
|
||||
M680X_INS_BMC,
|
||||
M680X_INS_BMI,
|
||||
M680X_INS_BMS,
|
||||
M680X_INS_BNE,
|
||||
M680X_INS_BOR,
|
||||
M680X_INS_BPL,
|
||||
M680X_INS_BRCLR,
|
||||
M680X_INS_BRSET,
|
||||
M680X_INS_BRA,
|
||||
M680X_INS_BRN,
|
||||
M680X_INS_BSET,
|
||||
M680X_INS_BSR,
|
||||
M680X_INS_BVC,
|
||||
M680X_INS_BVS,
|
||||
M680X_INS_CALL,
|
||||
M680X_INS_CBA, ///< M6800/1/2/3
|
||||
M680X_INS_CBEQ,
|
||||
M680X_INS_CBEQA,
|
||||
M680X_INS_CBEQX,
|
||||
M680X_INS_CLC, ///< M6800/1/2/3
|
||||
M680X_INS_CLI, ///< M6800/1/2/3
|
||||
M680X_INS_CLR,
|
||||
M680X_INS_CLRA,
|
||||
M680X_INS_CLRB,
|
||||
M680X_INS_CLRD,
|
||||
M680X_INS_CLRE,
|
||||
M680X_INS_CLRF,
|
||||
M680X_INS_CLRH,
|
||||
M680X_INS_CLRW,
|
||||
M680X_INS_CLRX,
|
||||
M680X_INS_CLV, ///< M6800/1/2/3
|
||||
M680X_INS_CMP,
|
||||
M680X_INS_CMPA,
|
||||
M680X_INS_CMPB,
|
||||
M680X_INS_CMPD,
|
||||
M680X_INS_CMPE,
|
||||
M680X_INS_CMPF,
|
||||
M680X_INS_CMPR,
|
||||
M680X_INS_CMPS,
|
||||
M680X_INS_CMPU,
|
||||
M680X_INS_CMPW,
|
||||
M680X_INS_CMPX,
|
||||
M680X_INS_CMPY,
|
||||
M680X_INS_COM,
|
||||
M680X_INS_COMA,
|
||||
M680X_INS_COMB,
|
||||
M680X_INS_COMD,
|
||||
M680X_INS_COME,
|
||||
M680X_INS_COMF,
|
||||
M680X_INS_COMW,
|
||||
M680X_INS_COMX,
|
||||
M680X_INS_CPD,
|
||||
M680X_INS_CPHX,
|
||||
M680X_INS_CPS,
|
||||
M680X_INS_CPX, ///< M6800/1/2/3
|
||||
M680X_INS_CPY,
|
||||
M680X_INS_CWAI,
|
||||
M680X_INS_DAA,
|
||||
M680X_INS_DBEQ,
|
||||
M680X_INS_DBNE,
|
||||
M680X_INS_DBNZ,
|
||||
M680X_INS_DBNZA,
|
||||
M680X_INS_DBNZX,
|
||||
M680X_INS_DEC,
|
||||
M680X_INS_DECA,
|
||||
M680X_INS_DECB,
|
||||
M680X_INS_DECD,
|
||||
M680X_INS_DECE,
|
||||
M680X_INS_DECF,
|
||||
M680X_INS_DECW,
|
||||
M680X_INS_DECX,
|
||||
M680X_INS_DES, ///< M6800/1/2/3
|
||||
M680X_INS_DEX, ///< M6800/1/2/3
|
||||
M680X_INS_DEY,
|
||||
M680X_INS_DIV,
|
||||
M680X_INS_DIVD,
|
||||
M680X_INS_DIVQ,
|
||||
M680X_INS_EDIV,
|
||||
M680X_INS_EDIVS,
|
||||
M680X_INS_EIM,
|
||||
M680X_INS_EMACS,
|
||||
M680X_INS_EMAXD,
|
||||
M680X_INS_EMAXM,
|
||||
M680X_INS_EMIND,
|
||||
M680X_INS_EMINM,
|
||||
M680X_INS_EMUL,
|
||||
M680X_INS_EMULS,
|
||||
M680X_INS_EOR,
|
||||
M680X_INS_EORA,
|
||||
M680X_INS_EORB,
|
||||
M680X_INS_EORD,
|
||||
M680X_INS_EORR,
|
||||
M680X_INS_ETBL,
|
||||
M680X_INS_EXG,
|
||||
M680X_INS_FDIV,
|
||||
M680X_INS_IBEQ,
|
||||
M680X_INS_IBNE,
|
||||
M680X_INS_IDIV,
|
||||
M680X_INS_IDIVS,
|
||||
M680X_INS_ILLGL,
|
||||
M680X_INS_INC,
|
||||
M680X_INS_INCA,
|
||||
M680X_INS_INCB,
|
||||
M680X_INS_INCD,
|
||||
M680X_INS_INCE,
|
||||
M680X_INS_INCF,
|
||||
M680X_INS_INCW,
|
||||
M680X_INS_INCX,
|
||||
M680X_INS_INS, ///< M6800/1/2/3
|
||||
M680X_INS_INX, ///< M6800/1/2/3
|
||||
M680X_INS_INY,
|
||||
M680X_INS_JMP,
|
||||
M680X_INS_JSR,
|
||||
M680X_INS_LBCC, ///< or LBHS
|
||||
M680X_INS_LBCS, ///< or LBLO
|
||||
M680X_INS_LBEQ,
|
||||
M680X_INS_LBGE,
|
||||
M680X_INS_LBGT,
|
||||
M680X_INS_LBHI,
|
||||
M680X_INS_LBLE,
|
||||
M680X_INS_LBLS,
|
||||
M680X_INS_LBLT,
|
||||
M680X_INS_LBMI,
|
||||
M680X_INS_LBNE,
|
||||
M680X_INS_LBPL,
|
||||
M680X_INS_LBRA,
|
||||
M680X_INS_LBRN,
|
||||
M680X_INS_LBSR,
|
||||
M680X_INS_LBVC,
|
||||
M680X_INS_LBVS,
|
||||
M680X_INS_LDA,
|
||||
M680X_INS_LDAA, ///< M6800/1/2/3
|
||||
M680X_INS_LDAB, ///< M6800/1/2/3
|
||||
M680X_INS_LDB,
|
||||
M680X_INS_LDBT,
|
||||
M680X_INS_LDD,
|
||||
M680X_INS_LDE,
|
||||
M680X_INS_LDF,
|
||||
M680X_INS_LDHX,
|
||||
M680X_INS_LDMD,
|
||||
M680X_INS_LDQ,
|
||||
M680X_INS_LDS,
|
||||
M680X_INS_LDU,
|
||||
M680X_INS_LDW,
|
||||
M680X_INS_LDX,
|
||||
M680X_INS_LDY,
|
||||
M680X_INS_LEAS,
|
||||
M680X_INS_LEAU,
|
||||
M680X_INS_LEAX,
|
||||
M680X_INS_LEAY,
|
||||
M680X_INS_LSL,
|
||||
M680X_INS_LSLA,
|
||||
M680X_INS_LSLB,
|
||||
M680X_INS_LSLD,
|
||||
M680X_INS_LSLX,
|
||||
M680X_INS_LSR,
|
||||
M680X_INS_LSRA,
|
||||
M680X_INS_LSRB,
|
||||
M680X_INS_LSRD, ///< or ASRD
|
||||
M680X_INS_LSRW,
|
||||
M680X_INS_LSRX,
|
||||
M680X_INS_MAXA,
|
||||
M680X_INS_MAXM,
|
||||
M680X_INS_MEM,
|
||||
M680X_INS_MINA,
|
||||
M680X_INS_MINM,
|
||||
M680X_INS_MOV,
|
||||
M680X_INS_MOVB,
|
||||
M680X_INS_MOVW,
|
||||
M680X_INS_MUL,
|
||||
M680X_INS_MULD,
|
||||
M680X_INS_NEG,
|
||||
M680X_INS_NEGA,
|
||||
M680X_INS_NEGB,
|
||||
M680X_INS_NEGD,
|
||||
M680X_INS_NEGX,
|
||||
M680X_INS_NOP,
|
||||
M680X_INS_NSA,
|
||||
M680X_INS_OIM,
|
||||
M680X_INS_ORA,
|
||||
M680X_INS_ORAA, ///< M6800/1/2/3
|
||||
M680X_INS_ORAB, ///< M6800/1/2/3
|
||||
M680X_INS_ORB,
|
||||
M680X_INS_ORCC,
|
||||
M680X_INS_ORD,
|
||||
M680X_INS_ORR,
|
||||
M680X_INS_PSHA, ///< M6800/1/2/3
|
||||
M680X_INS_PSHB, ///< M6800/1/2/3
|
||||
M680X_INS_PSHC,
|
||||
M680X_INS_PSHD,
|
||||
M680X_INS_PSHH,
|
||||
M680X_INS_PSHS,
|
||||
M680X_INS_PSHSW,
|
||||
M680X_INS_PSHU,
|
||||
M680X_INS_PSHUW,
|
||||
M680X_INS_PSHX, ///< M6800/1/2/3
|
||||
M680X_INS_PSHY,
|
||||
M680X_INS_PULA, ///< M6800/1/2/3
|
||||
M680X_INS_PULB, ///< M6800/1/2/3
|
||||
M680X_INS_PULC,
|
||||
M680X_INS_PULD,
|
||||
M680X_INS_PULH,
|
||||
M680X_INS_PULS,
|
||||
M680X_INS_PULSW,
|
||||
M680X_INS_PULU,
|
||||
M680X_INS_PULUW,
|
||||
M680X_INS_PULX, ///< M6800/1/2/3
|
||||
M680X_INS_PULY,
|
||||
M680X_INS_REV,
|
||||
M680X_INS_REVW,
|
||||
M680X_INS_ROL,
|
||||
M680X_INS_ROLA,
|
||||
M680X_INS_ROLB,
|
||||
M680X_INS_ROLD,
|
||||
M680X_INS_ROLW,
|
||||
M680X_INS_ROLX,
|
||||
M680X_INS_ROR,
|
||||
M680X_INS_RORA,
|
||||
M680X_INS_RORB,
|
||||
M680X_INS_RORD,
|
||||
M680X_INS_RORW,
|
||||
M680X_INS_RORX,
|
||||
M680X_INS_RSP,
|
||||
M680X_INS_RTC,
|
||||
M680X_INS_RTI,
|
||||
M680X_INS_RTS,
|
||||
M680X_INS_SBA, ///< M6800/1/2/3
|
||||
M680X_INS_SBC,
|
||||
M680X_INS_SBCA,
|
||||
M680X_INS_SBCB,
|
||||
M680X_INS_SBCD,
|
||||
M680X_INS_SBCR,
|
||||
M680X_INS_SEC,
|
||||
M680X_INS_SEI,
|
||||
M680X_INS_SEV,
|
||||
M680X_INS_SEX,
|
||||
M680X_INS_SEXW,
|
||||
M680X_INS_SLP,
|
||||
M680X_INS_STA,
|
||||
M680X_INS_STAA, ///< M6800/1/2/3
|
||||
M680X_INS_STAB, ///< M6800/1/2/3
|
||||
M680X_INS_STB,
|
||||
M680X_INS_STBT,
|
||||
M680X_INS_STD,
|
||||
M680X_INS_STE,
|
||||
M680X_INS_STF,
|
||||
M680X_INS_STOP,
|
||||
M680X_INS_STHX,
|
||||
M680X_INS_STQ,
|
||||
M680X_INS_STS,
|
||||
M680X_INS_STU,
|
||||
M680X_INS_STW,
|
||||
M680X_INS_STX,
|
||||
M680X_INS_STY,
|
||||
M680X_INS_SUB,
|
||||
M680X_INS_SUBA,
|
||||
M680X_INS_SUBB,
|
||||
M680X_INS_SUBD,
|
||||
M680X_INS_SUBE,
|
||||
M680X_INS_SUBF,
|
||||
M680X_INS_SUBR,
|
||||
M680X_INS_SUBW,
|
||||
M680X_INS_SWI,
|
||||
M680X_INS_SWI2,
|
||||
M680X_INS_SWI3,
|
||||
M680X_INS_SYNC,
|
||||
M680X_INS_TAB, ///< M6800/1/2/3
|
||||
M680X_INS_TAP, ///< M6800/1/2/3
|
||||
M680X_INS_TAX,
|
||||
M680X_INS_TBA, ///< M6800/1/2/3
|
||||
M680X_INS_TBEQ,
|
||||
M680X_INS_TBL,
|
||||
M680X_INS_TBNE,
|
||||
M680X_INS_TEST,
|
||||
M680X_INS_TFM,
|
||||
M680X_INS_TFR,
|
||||
M680X_INS_TIM,
|
||||
M680X_INS_TPA, ///< M6800/1/2/3
|
||||
M680X_INS_TST,
|
||||
M680X_INS_TSTA,
|
||||
M680X_INS_TSTB,
|
||||
M680X_INS_TSTD,
|
||||
M680X_INS_TSTE,
|
||||
M680X_INS_TSTF,
|
||||
M680X_INS_TSTW,
|
||||
M680X_INS_TSTX,
|
||||
M680X_INS_TSX, ///< M6800/1/2/3
|
||||
M680X_INS_TSY,
|
||||
M680X_INS_TXA,
|
||||
M680X_INS_TXS, ///< M6800/1/2/3
|
||||
M680X_INS_TYS,
|
||||
M680X_INS_WAI, ///< M6800/1/2/3
|
||||
M680X_INS_WAIT,
|
||||
M680X_INS_WAV,
|
||||
M680X_INS_WAVR,
|
||||
M680X_INS_XGDX, ///< HD6301
|
||||
M680X_INS_XGDY,
|
||||
M680X_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} m680x_insn;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
613
ai_anti_malware/capstone/include/capstone/m68k.h
Normal file
613
ai_anti_malware/capstone/include/capstone/m68k.h
Normal file
@@ -0,0 +1,613 @@
|
||||
#ifndef CAPSTONE_M68K_H
|
||||
#define CAPSTONE_M68K_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Daniel Collin <daniel@collin.com>, 2015-2016 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
#define M68K_OPERAND_COUNT 4
|
||||
|
||||
/// M68K registers and special registers
|
||||
typedef enum m68k_reg {
|
||||
M68K_REG_INVALID = 0,
|
||||
|
||||
M68K_REG_D0,
|
||||
M68K_REG_D1,
|
||||
M68K_REG_D2,
|
||||
M68K_REG_D3,
|
||||
M68K_REG_D4,
|
||||
M68K_REG_D5,
|
||||
M68K_REG_D6,
|
||||
M68K_REG_D7,
|
||||
|
||||
M68K_REG_A0,
|
||||
M68K_REG_A1,
|
||||
M68K_REG_A2,
|
||||
M68K_REG_A3,
|
||||
M68K_REG_A4,
|
||||
M68K_REG_A5,
|
||||
M68K_REG_A6,
|
||||
M68K_REG_A7,
|
||||
|
||||
M68K_REG_FP0,
|
||||
M68K_REG_FP1,
|
||||
M68K_REG_FP2,
|
||||
M68K_REG_FP3,
|
||||
M68K_REG_FP4,
|
||||
M68K_REG_FP5,
|
||||
M68K_REG_FP6,
|
||||
M68K_REG_FP7,
|
||||
|
||||
M68K_REG_PC,
|
||||
|
||||
M68K_REG_SR,
|
||||
M68K_REG_CCR,
|
||||
M68K_REG_SFC,
|
||||
M68K_REG_DFC,
|
||||
M68K_REG_USP,
|
||||
M68K_REG_VBR,
|
||||
M68K_REG_CACR,
|
||||
M68K_REG_CAAR,
|
||||
M68K_REG_MSP,
|
||||
M68K_REG_ISP,
|
||||
M68K_REG_TC,
|
||||
M68K_REG_ITT0,
|
||||
M68K_REG_ITT1,
|
||||
M68K_REG_DTT0,
|
||||
M68K_REG_DTT1,
|
||||
M68K_REG_MMUSR,
|
||||
M68K_REG_URP,
|
||||
M68K_REG_SRP,
|
||||
|
||||
M68K_REG_FPCR,
|
||||
M68K_REG_FPSR,
|
||||
M68K_REG_FPIAR,
|
||||
|
||||
M68K_REG_ENDING, // <-- mark the end of the list of registers
|
||||
} m68k_reg;
|
||||
|
||||
/// M68K Addressing Modes
|
||||
typedef enum m68k_address_mode {
|
||||
M68K_AM_NONE = 0, ///< No address mode.
|
||||
|
||||
M68K_AM_REG_DIRECT_DATA, ///< Register Direct - Data
|
||||
M68K_AM_REG_DIRECT_ADDR, ///< Register Direct - Address
|
||||
|
||||
M68K_AM_REGI_ADDR, ///< Register Indirect - Address
|
||||
M68K_AM_REGI_ADDR_POST_INC, ///< Register Indirect - Address with Postincrement
|
||||
M68K_AM_REGI_ADDR_PRE_DEC, ///< Register Indirect - Address with Predecrement
|
||||
M68K_AM_REGI_ADDR_DISP, ///< Register Indirect - Address with Displacement
|
||||
|
||||
M68K_AM_AREGI_INDEX_8_BIT_DISP, ///< Address Register Indirect With Index- 8-bit displacement
|
||||
M68K_AM_AREGI_INDEX_BASE_DISP, ///< Address Register Indirect With Index- Base displacement
|
||||
|
||||
M68K_AM_MEMI_POST_INDEX, ///< Memory indirect - Postindex
|
||||
M68K_AM_MEMI_PRE_INDEX, ///< Memory indirect - Preindex
|
||||
|
||||
M68K_AM_PCI_DISP, ///< Program Counter Indirect - with Displacement
|
||||
|
||||
M68K_AM_PCI_INDEX_8_BIT_DISP, ///< Program Counter Indirect with Index - with 8-Bit Displacement
|
||||
M68K_AM_PCI_INDEX_BASE_DISP, ///< Program Counter Indirect with Index - with Base Displacement
|
||||
|
||||
M68K_AM_PC_MEMI_POST_INDEX, ///< Program Counter Memory Indirect - Postindexed
|
||||
M68K_AM_PC_MEMI_PRE_INDEX, ///< Program Counter Memory Indirect - Preindexed
|
||||
|
||||
M68K_AM_ABSOLUTE_DATA_SHORT, ///< Absolute Data Addressing - Short
|
||||
M68K_AM_ABSOLUTE_DATA_LONG, ///< Absolute Data Addressing - Long
|
||||
M68K_AM_IMMEDIATE, ///< Immediate value
|
||||
|
||||
M68K_AM_BRANCH_DISPLACEMENT, ///< Address as displacement from (PC+2) used by branches
|
||||
} m68k_address_mode;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum m68k_op_type {
|
||||
M68K_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
M68K_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
M68K_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
M68K_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
M68K_OP_FP_SINGLE, ///< single precision Floating-Point operand
|
||||
M68K_OP_FP_DOUBLE, ///< double precision Floating-Point operand
|
||||
M68K_OP_REG_BITS, ///< Register bits move
|
||||
M68K_OP_REG_PAIR, ///< Register pair in the same op (upper 4 bits for first reg, lower for second)
|
||||
M68K_OP_BR_DISP, ///< Branch displacement
|
||||
} m68k_op_type;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with M68K_OP_MEM operand type above
|
||||
typedef struct m68k_op_mem {
|
||||
m68k_reg base_reg; ///< base register (or M68K_REG_INVALID if irrelevant)
|
||||
m68k_reg index_reg; ///< index register (or M68K_REG_INVALID if irrelevant)
|
||||
m68k_reg in_base_reg; ///< indirect base register (or M68K_REG_INVALID if irrelevant)
|
||||
uint32_t in_disp; ///< indirect displacement
|
||||
uint32_t out_disp; ///< other displacement
|
||||
int16_t disp; ///< displacement value
|
||||
uint8_t scale; ///< scale for index register
|
||||
uint8_t bitfield; ///< set to true if the two values below should be used
|
||||
uint8_t width; ///< used for bf* instructions
|
||||
uint8_t offset; ///< used for bf* instructions
|
||||
uint8_t index_size; ///< 0 = w, 1 = l
|
||||
} m68k_op_mem;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum m68k_op_br_disp_size {
|
||||
M68K_OP_BR_DISP_SIZE_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
M68K_OP_BR_DISP_SIZE_BYTE = 1, ///< signed 8-bit displacement
|
||||
M68K_OP_BR_DISP_SIZE_WORD = 2, ///< signed 16-bit displacement
|
||||
M68K_OP_BR_DISP_SIZE_LONG = 4, ///< signed 32-bit displacement
|
||||
} m68k_op_br_disp_size;
|
||||
|
||||
typedef struct m68k_op_br_disp {
|
||||
int32_t disp; ///< displacement value
|
||||
uint8_t disp_size; ///< Size from m68k_op_br_disp_size type above
|
||||
} m68k_op_br_disp;
|
||||
|
||||
/// Register pair in one operand.
|
||||
typedef struct cs_m68k_op_reg_pair {
|
||||
m68k_reg reg_0;
|
||||
m68k_reg reg_1;
|
||||
} cs_m68k_op_reg_pair;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_m68k_op {
|
||||
union {
|
||||
uint64_t imm; ///< immediate value for IMM operand
|
||||
double dimm; ///< double imm
|
||||
float simm; ///< float imm
|
||||
m68k_reg reg; ///< register value for REG operand
|
||||
cs_m68k_op_reg_pair reg_pair; ///< register pair in one operand
|
||||
};
|
||||
|
||||
m68k_op_mem mem; ///< data when operand is targeting memory
|
||||
m68k_op_br_disp br_disp; ///< data when operand is a branch displacement
|
||||
uint32_t register_bits; ///< register bits for movem etc. (always in d0-d7, a0-a7, fp0 - fp7 order)
|
||||
m68k_op_type type;
|
||||
m68k_address_mode address_mode; ///< M68K addressing mode for this op
|
||||
} cs_m68k_op;
|
||||
|
||||
/// Operation size of the CPU instructions
|
||||
typedef enum m68k_cpu_size {
|
||||
M68K_CPU_SIZE_NONE = 0, ///< unsized or unspecified
|
||||
M68K_CPU_SIZE_BYTE = 1, ///< 1 byte in size
|
||||
M68K_CPU_SIZE_WORD = 2, ///< 2 bytes in size
|
||||
M68K_CPU_SIZE_LONG = 4, ///< 4 bytes in size
|
||||
} m68k_cpu_size;
|
||||
|
||||
/// Operation size of the FPU instructions (Notice that FPU instruction can also use CPU sizes if needed)
|
||||
typedef enum m68k_fpu_size {
|
||||
M68K_FPU_SIZE_NONE = 0, ///< unsized like fsave/frestore
|
||||
M68K_FPU_SIZE_SINGLE = 4, ///< 4 byte in size (single float)
|
||||
M68K_FPU_SIZE_DOUBLE = 8, ///< 8 byte in size (double)
|
||||
M68K_FPU_SIZE_EXTENDED = 12, ///< 12 byte in size (extended real format)
|
||||
} m68k_fpu_size;
|
||||
|
||||
/// Type of size that is being used for the current instruction
|
||||
typedef enum m68k_size_type {
|
||||
M68K_SIZE_TYPE_INVALID = 0,
|
||||
|
||||
M68K_SIZE_TYPE_CPU,
|
||||
M68K_SIZE_TYPE_FPU,
|
||||
} m68k_size_type;
|
||||
|
||||
/// Operation size of the current instruction (NOT the actually size of instruction)
|
||||
typedef struct m68k_op_size {
|
||||
m68k_size_type type;
|
||||
union {
|
||||
m68k_cpu_size cpu_size;
|
||||
m68k_fpu_size fpu_size;
|
||||
};
|
||||
} m68k_op_size;
|
||||
|
||||
/// The M68K instruction and it's operands
|
||||
typedef struct cs_m68k {
|
||||
// Number of operands of this instruction or 0 when instruction has no operand.
|
||||
cs_m68k_op operands[M68K_OPERAND_COUNT]; ///< operands for this instruction.
|
||||
m68k_op_size op_size; ///< size of data operand works on in bytes (.b, .w, .l, etc)
|
||||
uint8_t op_count; ///< number of operands for the instruction
|
||||
} cs_m68k;
|
||||
|
||||
/// M68K instruction
|
||||
typedef enum m68k_insn {
|
||||
M68K_INS_INVALID = 0,
|
||||
|
||||
M68K_INS_ABCD,
|
||||
M68K_INS_ADD,
|
||||
M68K_INS_ADDA,
|
||||
M68K_INS_ADDI,
|
||||
M68K_INS_ADDQ,
|
||||
M68K_INS_ADDX,
|
||||
M68K_INS_AND,
|
||||
M68K_INS_ANDI,
|
||||
M68K_INS_ASL,
|
||||
M68K_INS_ASR,
|
||||
M68K_INS_BHS,
|
||||
M68K_INS_BLO,
|
||||
M68K_INS_BHI,
|
||||
M68K_INS_BLS,
|
||||
M68K_INS_BCC,
|
||||
M68K_INS_BCS,
|
||||
M68K_INS_BNE,
|
||||
M68K_INS_BEQ,
|
||||
M68K_INS_BVC,
|
||||
M68K_INS_BVS,
|
||||
M68K_INS_BPL,
|
||||
M68K_INS_BMI,
|
||||
M68K_INS_BGE,
|
||||
M68K_INS_BLT,
|
||||
M68K_INS_BGT,
|
||||
M68K_INS_BLE,
|
||||
M68K_INS_BRA,
|
||||
M68K_INS_BSR,
|
||||
M68K_INS_BCHG,
|
||||
M68K_INS_BCLR,
|
||||
M68K_INS_BSET,
|
||||
M68K_INS_BTST,
|
||||
M68K_INS_BFCHG,
|
||||
M68K_INS_BFCLR,
|
||||
M68K_INS_BFEXTS,
|
||||
M68K_INS_BFEXTU,
|
||||
M68K_INS_BFFFO,
|
||||
M68K_INS_BFINS,
|
||||
M68K_INS_BFSET,
|
||||
M68K_INS_BFTST,
|
||||
M68K_INS_BKPT,
|
||||
M68K_INS_CALLM,
|
||||
M68K_INS_CAS,
|
||||
M68K_INS_CAS2,
|
||||
M68K_INS_CHK,
|
||||
M68K_INS_CHK2,
|
||||
M68K_INS_CLR,
|
||||
M68K_INS_CMP,
|
||||
M68K_INS_CMPA,
|
||||
M68K_INS_CMPI,
|
||||
M68K_INS_CMPM,
|
||||
M68K_INS_CMP2,
|
||||
M68K_INS_CINVL,
|
||||
M68K_INS_CINVP,
|
||||
M68K_INS_CINVA,
|
||||
M68K_INS_CPUSHL,
|
||||
M68K_INS_CPUSHP,
|
||||
M68K_INS_CPUSHA,
|
||||
M68K_INS_DBT,
|
||||
M68K_INS_DBF,
|
||||
M68K_INS_DBHI,
|
||||
M68K_INS_DBLS,
|
||||
M68K_INS_DBCC,
|
||||
M68K_INS_DBCS,
|
||||
M68K_INS_DBNE,
|
||||
M68K_INS_DBEQ,
|
||||
M68K_INS_DBVC,
|
||||
M68K_INS_DBVS,
|
||||
M68K_INS_DBPL,
|
||||
M68K_INS_DBMI,
|
||||
M68K_INS_DBGE,
|
||||
M68K_INS_DBLT,
|
||||
M68K_INS_DBGT,
|
||||
M68K_INS_DBLE,
|
||||
M68K_INS_DBRA,
|
||||
M68K_INS_DIVS,
|
||||
M68K_INS_DIVSL,
|
||||
M68K_INS_DIVU,
|
||||
M68K_INS_DIVUL,
|
||||
M68K_INS_EOR,
|
||||
M68K_INS_EORI,
|
||||
M68K_INS_EXG,
|
||||
M68K_INS_EXT,
|
||||
M68K_INS_EXTB,
|
||||
M68K_INS_FABS,
|
||||
M68K_INS_FSABS,
|
||||
M68K_INS_FDABS,
|
||||
M68K_INS_FACOS,
|
||||
M68K_INS_FADD,
|
||||
M68K_INS_FSADD,
|
||||
M68K_INS_FDADD,
|
||||
M68K_INS_FASIN,
|
||||
M68K_INS_FATAN,
|
||||
M68K_INS_FATANH,
|
||||
M68K_INS_FBF,
|
||||
M68K_INS_FBEQ,
|
||||
M68K_INS_FBOGT,
|
||||
M68K_INS_FBOGE,
|
||||
M68K_INS_FBOLT,
|
||||
M68K_INS_FBOLE,
|
||||
M68K_INS_FBOGL,
|
||||
M68K_INS_FBOR,
|
||||
M68K_INS_FBUN,
|
||||
M68K_INS_FBUEQ,
|
||||
M68K_INS_FBUGT,
|
||||
M68K_INS_FBUGE,
|
||||
M68K_INS_FBULT,
|
||||
M68K_INS_FBULE,
|
||||
M68K_INS_FBNE,
|
||||
M68K_INS_FBT,
|
||||
M68K_INS_FBSF,
|
||||
M68K_INS_FBSEQ,
|
||||
M68K_INS_FBGT,
|
||||
M68K_INS_FBGE,
|
||||
M68K_INS_FBLT,
|
||||
M68K_INS_FBLE,
|
||||
M68K_INS_FBGL,
|
||||
M68K_INS_FBGLE,
|
||||
M68K_INS_FBNGLE,
|
||||
M68K_INS_FBNGL,
|
||||
M68K_INS_FBNLE,
|
||||
M68K_INS_FBNLT,
|
||||
M68K_INS_FBNGE,
|
||||
M68K_INS_FBNGT,
|
||||
M68K_INS_FBSNE,
|
||||
M68K_INS_FBST,
|
||||
M68K_INS_FCMP,
|
||||
M68K_INS_FCOS,
|
||||
M68K_INS_FCOSH,
|
||||
M68K_INS_FDBF,
|
||||
M68K_INS_FDBEQ,
|
||||
M68K_INS_FDBOGT,
|
||||
M68K_INS_FDBOGE,
|
||||
M68K_INS_FDBOLT,
|
||||
M68K_INS_FDBOLE,
|
||||
M68K_INS_FDBOGL,
|
||||
M68K_INS_FDBOR,
|
||||
M68K_INS_FDBUN,
|
||||
M68K_INS_FDBUEQ,
|
||||
M68K_INS_FDBUGT,
|
||||
M68K_INS_FDBUGE,
|
||||
M68K_INS_FDBULT,
|
||||
M68K_INS_FDBULE,
|
||||
M68K_INS_FDBNE,
|
||||
M68K_INS_FDBT,
|
||||
M68K_INS_FDBSF,
|
||||
M68K_INS_FDBSEQ,
|
||||
M68K_INS_FDBGT,
|
||||
M68K_INS_FDBGE,
|
||||
M68K_INS_FDBLT,
|
||||
M68K_INS_FDBLE,
|
||||
M68K_INS_FDBGL,
|
||||
M68K_INS_FDBGLE,
|
||||
M68K_INS_FDBNGLE,
|
||||
M68K_INS_FDBNGL,
|
||||
M68K_INS_FDBNLE,
|
||||
M68K_INS_FDBNLT,
|
||||
M68K_INS_FDBNGE,
|
||||
M68K_INS_FDBNGT,
|
||||
M68K_INS_FDBSNE,
|
||||
M68K_INS_FDBST,
|
||||
M68K_INS_FDIV,
|
||||
M68K_INS_FSDIV,
|
||||
M68K_INS_FDDIV,
|
||||
M68K_INS_FETOX,
|
||||
M68K_INS_FETOXM1,
|
||||
M68K_INS_FGETEXP,
|
||||
M68K_INS_FGETMAN,
|
||||
M68K_INS_FINT,
|
||||
M68K_INS_FINTRZ,
|
||||
M68K_INS_FLOG10,
|
||||
M68K_INS_FLOG2,
|
||||
M68K_INS_FLOGN,
|
||||
M68K_INS_FLOGNP1,
|
||||
M68K_INS_FMOD,
|
||||
M68K_INS_FMOVE,
|
||||
M68K_INS_FSMOVE,
|
||||
M68K_INS_FDMOVE,
|
||||
M68K_INS_FMOVECR,
|
||||
M68K_INS_FMOVEM,
|
||||
M68K_INS_FMUL,
|
||||
M68K_INS_FSMUL,
|
||||
M68K_INS_FDMUL,
|
||||
M68K_INS_FNEG,
|
||||
M68K_INS_FSNEG,
|
||||
M68K_INS_FDNEG,
|
||||
M68K_INS_FNOP,
|
||||
M68K_INS_FREM,
|
||||
M68K_INS_FRESTORE,
|
||||
M68K_INS_FSAVE,
|
||||
M68K_INS_FSCALE,
|
||||
M68K_INS_FSGLDIV,
|
||||
M68K_INS_FSGLMUL,
|
||||
M68K_INS_FSIN,
|
||||
M68K_INS_FSINCOS,
|
||||
M68K_INS_FSINH,
|
||||
M68K_INS_FSQRT,
|
||||
M68K_INS_FSSQRT,
|
||||
M68K_INS_FDSQRT,
|
||||
M68K_INS_FSF,
|
||||
M68K_INS_FSBEQ,
|
||||
M68K_INS_FSOGT,
|
||||
M68K_INS_FSOGE,
|
||||
M68K_INS_FSOLT,
|
||||
M68K_INS_FSOLE,
|
||||
M68K_INS_FSOGL,
|
||||
M68K_INS_FSOR,
|
||||
M68K_INS_FSUN,
|
||||
M68K_INS_FSUEQ,
|
||||
M68K_INS_FSUGT,
|
||||
M68K_INS_FSUGE,
|
||||
M68K_INS_FSULT,
|
||||
M68K_INS_FSULE,
|
||||
M68K_INS_FSNE,
|
||||
M68K_INS_FST,
|
||||
M68K_INS_FSSF,
|
||||
M68K_INS_FSSEQ,
|
||||
M68K_INS_FSGT,
|
||||
M68K_INS_FSGE,
|
||||
M68K_INS_FSLT,
|
||||
M68K_INS_FSLE,
|
||||
M68K_INS_FSGL,
|
||||
M68K_INS_FSGLE,
|
||||
M68K_INS_FSNGLE,
|
||||
M68K_INS_FSNGL,
|
||||
M68K_INS_FSNLE,
|
||||
M68K_INS_FSNLT,
|
||||
M68K_INS_FSNGE,
|
||||
M68K_INS_FSNGT,
|
||||
M68K_INS_FSSNE,
|
||||
M68K_INS_FSST,
|
||||
M68K_INS_FSUB,
|
||||
M68K_INS_FSSUB,
|
||||
M68K_INS_FDSUB,
|
||||
M68K_INS_FTAN,
|
||||
M68K_INS_FTANH,
|
||||
M68K_INS_FTENTOX,
|
||||
M68K_INS_FTRAPF,
|
||||
M68K_INS_FTRAPEQ,
|
||||
M68K_INS_FTRAPOGT,
|
||||
M68K_INS_FTRAPOGE,
|
||||
M68K_INS_FTRAPOLT,
|
||||
M68K_INS_FTRAPOLE,
|
||||
M68K_INS_FTRAPOGL,
|
||||
M68K_INS_FTRAPOR,
|
||||
M68K_INS_FTRAPUN,
|
||||
M68K_INS_FTRAPUEQ,
|
||||
M68K_INS_FTRAPUGT,
|
||||
M68K_INS_FTRAPUGE,
|
||||
M68K_INS_FTRAPULT,
|
||||
M68K_INS_FTRAPULE,
|
||||
M68K_INS_FTRAPNE,
|
||||
M68K_INS_FTRAPT,
|
||||
M68K_INS_FTRAPSF,
|
||||
M68K_INS_FTRAPSEQ,
|
||||
M68K_INS_FTRAPGT,
|
||||
M68K_INS_FTRAPGE,
|
||||
M68K_INS_FTRAPLT,
|
||||
M68K_INS_FTRAPLE,
|
||||
M68K_INS_FTRAPGL,
|
||||
M68K_INS_FTRAPGLE,
|
||||
M68K_INS_FTRAPNGLE,
|
||||
M68K_INS_FTRAPNGL,
|
||||
M68K_INS_FTRAPNLE,
|
||||
M68K_INS_FTRAPNLT,
|
||||
M68K_INS_FTRAPNGE,
|
||||
M68K_INS_FTRAPNGT,
|
||||
M68K_INS_FTRAPSNE,
|
||||
M68K_INS_FTRAPST,
|
||||
M68K_INS_FTST,
|
||||
M68K_INS_FTWOTOX,
|
||||
M68K_INS_HALT,
|
||||
M68K_INS_ILLEGAL,
|
||||
M68K_INS_JMP,
|
||||
M68K_INS_JSR,
|
||||
M68K_INS_LEA,
|
||||
M68K_INS_LINK,
|
||||
M68K_INS_LPSTOP,
|
||||
M68K_INS_LSL,
|
||||
M68K_INS_LSR,
|
||||
M68K_INS_MOVE,
|
||||
M68K_INS_MOVEA,
|
||||
M68K_INS_MOVEC,
|
||||
M68K_INS_MOVEM,
|
||||
M68K_INS_MOVEP,
|
||||
M68K_INS_MOVEQ,
|
||||
M68K_INS_MOVES,
|
||||
M68K_INS_MOVE16,
|
||||
M68K_INS_MULS,
|
||||
M68K_INS_MULU,
|
||||
M68K_INS_NBCD,
|
||||
M68K_INS_NEG,
|
||||
M68K_INS_NEGX,
|
||||
M68K_INS_NOP,
|
||||
M68K_INS_NOT,
|
||||
M68K_INS_OR,
|
||||
M68K_INS_ORI,
|
||||
M68K_INS_PACK,
|
||||
M68K_INS_PEA,
|
||||
M68K_INS_PFLUSH,
|
||||
M68K_INS_PFLUSHA,
|
||||
M68K_INS_PFLUSHAN,
|
||||
M68K_INS_PFLUSHN,
|
||||
M68K_INS_PLOADR,
|
||||
M68K_INS_PLOADW,
|
||||
M68K_INS_PLPAR,
|
||||
M68K_INS_PLPAW,
|
||||
M68K_INS_PMOVE,
|
||||
M68K_INS_PMOVEFD,
|
||||
M68K_INS_PTESTR,
|
||||
M68K_INS_PTESTW,
|
||||
M68K_INS_PULSE,
|
||||
M68K_INS_REMS,
|
||||
M68K_INS_REMU,
|
||||
M68K_INS_RESET,
|
||||
M68K_INS_ROL,
|
||||
M68K_INS_ROR,
|
||||
M68K_INS_ROXL,
|
||||
M68K_INS_ROXR,
|
||||
M68K_INS_RTD,
|
||||
M68K_INS_RTE,
|
||||
M68K_INS_RTM,
|
||||
M68K_INS_RTR,
|
||||
M68K_INS_RTS,
|
||||
M68K_INS_SBCD,
|
||||
M68K_INS_ST,
|
||||
M68K_INS_SF,
|
||||
M68K_INS_SHI,
|
||||
M68K_INS_SLS,
|
||||
M68K_INS_SCC,
|
||||
M68K_INS_SHS,
|
||||
M68K_INS_SCS,
|
||||
M68K_INS_SLO,
|
||||
M68K_INS_SNE,
|
||||
M68K_INS_SEQ,
|
||||
M68K_INS_SVC,
|
||||
M68K_INS_SVS,
|
||||
M68K_INS_SPL,
|
||||
M68K_INS_SMI,
|
||||
M68K_INS_SGE,
|
||||
M68K_INS_SLT,
|
||||
M68K_INS_SGT,
|
||||
M68K_INS_SLE,
|
||||
M68K_INS_STOP,
|
||||
M68K_INS_SUB,
|
||||
M68K_INS_SUBA,
|
||||
M68K_INS_SUBI,
|
||||
M68K_INS_SUBQ,
|
||||
M68K_INS_SUBX,
|
||||
M68K_INS_SWAP,
|
||||
M68K_INS_TAS,
|
||||
M68K_INS_TRAP,
|
||||
M68K_INS_TRAPV,
|
||||
M68K_INS_TRAPT,
|
||||
M68K_INS_TRAPF,
|
||||
M68K_INS_TRAPHI,
|
||||
M68K_INS_TRAPLS,
|
||||
M68K_INS_TRAPCC,
|
||||
M68K_INS_TRAPHS,
|
||||
M68K_INS_TRAPCS,
|
||||
M68K_INS_TRAPLO,
|
||||
M68K_INS_TRAPNE,
|
||||
M68K_INS_TRAPEQ,
|
||||
M68K_INS_TRAPVC,
|
||||
M68K_INS_TRAPVS,
|
||||
M68K_INS_TRAPPL,
|
||||
M68K_INS_TRAPMI,
|
||||
M68K_INS_TRAPGE,
|
||||
M68K_INS_TRAPLT,
|
||||
M68K_INS_TRAPGT,
|
||||
M68K_INS_TRAPLE,
|
||||
M68K_INS_TST,
|
||||
M68K_INS_UNLK,
|
||||
M68K_INS_UNPK,
|
||||
M68K_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} m68k_insn;
|
||||
|
||||
/// Group of M68K instructions
|
||||
typedef enum m68k_group_type {
|
||||
M68K_GRP_INVALID = 0, ///< CS_GRUP_INVALID
|
||||
M68K_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
M68K_GRP_RET = 3, ///< = CS_GRP_RET
|
||||
M68K_GRP_IRET = 5, ///< = CS_GRP_IRET
|
||||
M68K_GRP_BRANCH_RELATIVE = 7, ///< = CS_GRP_BRANCH_RELATIVE
|
||||
|
||||
M68K_GRP_ENDING,// <-- mark the end of the list of groups
|
||||
} m68k_group_type;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
956
ai_anti_malware/capstone/include/capstone/mips.h
Normal file
956
ai_anti_malware/capstone/include/capstone/mips.h
Normal file
@@ -0,0 +1,956 @@
|
||||
#ifndef CAPSTONE_MIPS_H
|
||||
#define CAPSTONE_MIPS_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
// GCC MIPS toolchain has a default macro called "mips" which breaks
|
||||
// compilation
|
||||
#undef mips
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum mips_op_type {
|
||||
MIPS_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
MIPS_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
MIPS_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
MIPS_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
} mips_op_type;
|
||||
|
||||
/// MIPS registers
|
||||
typedef enum mips_reg {
|
||||
MIPS_REG_INVALID = 0,
|
||||
// General purpose registers
|
||||
MIPS_REG_PC,
|
||||
|
||||
MIPS_REG_0,
|
||||
MIPS_REG_1,
|
||||
MIPS_REG_2,
|
||||
MIPS_REG_3,
|
||||
MIPS_REG_4,
|
||||
MIPS_REG_5,
|
||||
MIPS_REG_6,
|
||||
MIPS_REG_7,
|
||||
MIPS_REG_8,
|
||||
MIPS_REG_9,
|
||||
MIPS_REG_10,
|
||||
MIPS_REG_11,
|
||||
MIPS_REG_12,
|
||||
MIPS_REG_13,
|
||||
MIPS_REG_14,
|
||||
MIPS_REG_15,
|
||||
MIPS_REG_16,
|
||||
MIPS_REG_17,
|
||||
MIPS_REG_18,
|
||||
MIPS_REG_19,
|
||||
MIPS_REG_20,
|
||||
MIPS_REG_21,
|
||||
MIPS_REG_22,
|
||||
MIPS_REG_23,
|
||||
MIPS_REG_24,
|
||||
MIPS_REG_25,
|
||||
MIPS_REG_26,
|
||||
MIPS_REG_27,
|
||||
MIPS_REG_28,
|
||||
MIPS_REG_29,
|
||||
MIPS_REG_30,
|
||||
MIPS_REG_31,
|
||||
|
||||
// DSP registers
|
||||
MIPS_REG_DSPCCOND,
|
||||
MIPS_REG_DSPCARRY,
|
||||
MIPS_REG_DSPEFI,
|
||||
MIPS_REG_DSPOUTFLAG,
|
||||
MIPS_REG_DSPOUTFLAG16_19,
|
||||
MIPS_REG_DSPOUTFLAG20,
|
||||
MIPS_REG_DSPOUTFLAG21,
|
||||
MIPS_REG_DSPOUTFLAG22,
|
||||
MIPS_REG_DSPOUTFLAG23,
|
||||
MIPS_REG_DSPPOS,
|
||||
MIPS_REG_DSPSCOUNT,
|
||||
|
||||
// ACC registers
|
||||
MIPS_REG_AC0,
|
||||
MIPS_REG_AC1,
|
||||
MIPS_REG_AC2,
|
||||
MIPS_REG_AC3,
|
||||
|
||||
// COP registers
|
||||
MIPS_REG_CC0,
|
||||
MIPS_REG_CC1,
|
||||
MIPS_REG_CC2,
|
||||
MIPS_REG_CC3,
|
||||
MIPS_REG_CC4,
|
||||
MIPS_REG_CC5,
|
||||
MIPS_REG_CC6,
|
||||
MIPS_REG_CC7,
|
||||
|
||||
// FPU registers
|
||||
MIPS_REG_F0,
|
||||
MIPS_REG_F1,
|
||||
MIPS_REG_F2,
|
||||
MIPS_REG_F3,
|
||||
MIPS_REG_F4,
|
||||
MIPS_REG_F5,
|
||||
MIPS_REG_F6,
|
||||
MIPS_REG_F7,
|
||||
MIPS_REG_F8,
|
||||
MIPS_REG_F9,
|
||||
MIPS_REG_F10,
|
||||
MIPS_REG_F11,
|
||||
MIPS_REG_F12,
|
||||
MIPS_REG_F13,
|
||||
MIPS_REG_F14,
|
||||
MIPS_REG_F15,
|
||||
MIPS_REG_F16,
|
||||
MIPS_REG_F17,
|
||||
MIPS_REG_F18,
|
||||
MIPS_REG_F19,
|
||||
MIPS_REG_F20,
|
||||
MIPS_REG_F21,
|
||||
MIPS_REG_F22,
|
||||
MIPS_REG_F23,
|
||||
MIPS_REG_F24,
|
||||
MIPS_REG_F25,
|
||||
MIPS_REG_F26,
|
||||
MIPS_REG_F27,
|
||||
MIPS_REG_F28,
|
||||
MIPS_REG_F29,
|
||||
MIPS_REG_F30,
|
||||
MIPS_REG_F31,
|
||||
|
||||
MIPS_REG_FCC0,
|
||||
MIPS_REG_FCC1,
|
||||
MIPS_REG_FCC2,
|
||||
MIPS_REG_FCC3,
|
||||
MIPS_REG_FCC4,
|
||||
MIPS_REG_FCC5,
|
||||
MIPS_REG_FCC6,
|
||||
MIPS_REG_FCC7,
|
||||
|
||||
// AFPR128
|
||||
MIPS_REG_W0,
|
||||
MIPS_REG_W1,
|
||||
MIPS_REG_W2,
|
||||
MIPS_REG_W3,
|
||||
MIPS_REG_W4,
|
||||
MIPS_REG_W5,
|
||||
MIPS_REG_W6,
|
||||
MIPS_REG_W7,
|
||||
MIPS_REG_W8,
|
||||
MIPS_REG_W9,
|
||||
MIPS_REG_W10,
|
||||
MIPS_REG_W11,
|
||||
MIPS_REG_W12,
|
||||
MIPS_REG_W13,
|
||||
MIPS_REG_W14,
|
||||
MIPS_REG_W15,
|
||||
MIPS_REG_W16,
|
||||
MIPS_REG_W17,
|
||||
MIPS_REG_W18,
|
||||
MIPS_REG_W19,
|
||||
MIPS_REG_W20,
|
||||
MIPS_REG_W21,
|
||||
MIPS_REG_W22,
|
||||
MIPS_REG_W23,
|
||||
MIPS_REG_W24,
|
||||
MIPS_REG_W25,
|
||||
MIPS_REG_W26,
|
||||
MIPS_REG_W27,
|
||||
MIPS_REG_W28,
|
||||
MIPS_REG_W29,
|
||||
MIPS_REG_W30,
|
||||
MIPS_REG_W31,
|
||||
|
||||
MIPS_REG_HI,
|
||||
MIPS_REG_LO,
|
||||
|
||||
MIPS_REG_P0,
|
||||
MIPS_REG_P1,
|
||||
MIPS_REG_P2,
|
||||
|
||||
MIPS_REG_MPL0,
|
||||
MIPS_REG_MPL1,
|
||||
MIPS_REG_MPL2,
|
||||
|
||||
MIPS_REG_ENDING, // <-- mark the end of the list or registers
|
||||
|
||||
// alias registers
|
||||
MIPS_REG_ZERO = MIPS_REG_0,
|
||||
MIPS_REG_AT = MIPS_REG_1,
|
||||
MIPS_REG_V0 = MIPS_REG_2,
|
||||
MIPS_REG_V1 = MIPS_REG_3,
|
||||
MIPS_REG_A0 = MIPS_REG_4,
|
||||
MIPS_REG_A1 = MIPS_REG_5,
|
||||
MIPS_REG_A2 = MIPS_REG_6,
|
||||
MIPS_REG_A3 = MIPS_REG_7,
|
||||
MIPS_REG_T0 = MIPS_REG_8,
|
||||
MIPS_REG_T1 = MIPS_REG_9,
|
||||
MIPS_REG_T2 = MIPS_REG_10,
|
||||
MIPS_REG_T3 = MIPS_REG_11,
|
||||
MIPS_REG_T4 = MIPS_REG_12,
|
||||
MIPS_REG_T5 = MIPS_REG_13,
|
||||
MIPS_REG_T6 = MIPS_REG_14,
|
||||
MIPS_REG_T7 = MIPS_REG_15,
|
||||
MIPS_REG_S0 = MIPS_REG_16,
|
||||
MIPS_REG_S1 = MIPS_REG_17,
|
||||
MIPS_REG_S2 = MIPS_REG_18,
|
||||
MIPS_REG_S3 = MIPS_REG_19,
|
||||
MIPS_REG_S4 = MIPS_REG_20,
|
||||
MIPS_REG_S5 = MIPS_REG_21,
|
||||
MIPS_REG_S6 = MIPS_REG_22,
|
||||
MIPS_REG_S7 = MIPS_REG_23,
|
||||
MIPS_REG_T8 = MIPS_REG_24,
|
||||
MIPS_REG_T9 = MIPS_REG_25,
|
||||
MIPS_REG_K0 = MIPS_REG_26,
|
||||
MIPS_REG_K1 = MIPS_REG_27,
|
||||
MIPS_REG_GP = MIPS_REG_28,
|
||||
MIPS_REG_SP = MIPS_REG_29,
|
||||
MIPS_REG_FP = MIPS_REG_30, MIPS_REG_S8 = MIPS_REG_30,
|
||||
MIPS_REG_RA = MIPS_REG_31,
|
||||
|
||||
MIPS_REG_HI0 = MIPS_REG_AC0,
|
||||
MIPS_REG_HI1 = MIPS_REG_AC1,
|
||||
MIPS_REG_HI2 = MIPS_REG_AC2,
|
||||
MIPS_REG_HI3 = MIPS_REG_AC3,
|
||||
|
||||
MIPS_REG_LO0 = MIPS_REG_HI0,
|
||||
MIPS_REG_LO1 = MIPS_REG_HI1,
|
||||
MIPS_REG_LO2 = MIPS_REG_HI2,
|
||||
MIPS_REG_LO3 = MIPS_REG_HI3,
|
||||
} mips_reg;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with MIPS_OP_MEM operand type above
|
||||
typedef struct mips_op_mem {
|
||||
mips_reg base; ///< base register
|
||||
int64_t disp; ///< displacement/offset value
|
||||
} mips_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_mips_op {
|
||||
mips_op_type type; ///< operand type
|
||||
union {
|
||||
mips_reg reg; ///< register value for REG operand
|
||||
int64_t imm; ///< immediate value for IMM operand
|
||||
mips_op_mem mem; ///< base/index/scale/disp value for MEM operand
|
||||
};
|
||||
} cs_mips_op;
|
||||
|
||||
/// Instruction structure
|
||||
typedef struct cs_mips {
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
cs_mips_op operands[10]; ///< operands for this instruction.
|
||||
} cs_mips;
|
||||
|
||||
/// MIPS instruction
|
||||
typedef enum mips_insn {
|
||||
MIPS_INS_INVALID = 0,
|
||||
|
||||
MIPS_INS_ABSQ_S,
|
||||
MIPS_INS_ADD,
|
||||
MIPS_INS_ADDIUPC,
|
||||
MIPS_INS_ADDIUR1SP,
|
||||
MIPS_INS_ADDIUR2,
|
||||
MIPS_INS_ADDIUS5,
|
||||
MIPS_INS_ADDIUSP,
|
||||
MIPS_INS_ADDQH,
|
||||
MIPS_INS_ADDQH_R,
|
||||
MIPS_INS_ADDQ,
|
||||
MIPS_INS_ADDQ_S,
|
||||
MIPS_INS_ADDSC,
|
||||
MIPS_INS_ADDS_A,
|
||||
MIPS_INS_ADDS_S,
|
||||
MIPS_INS_ADDS_U,
|
||||
MIPS_INS_ADDU16,
|
||||
MIPS_INS_ADDUH,
|
||||
MIPS_INS_ADDUH_R,
|
||||
MIPS_INS_ADDU,
|
||||
MIPS_INS_ADDU_S,
|
||||
MIPS_INS_ADDVI,
|
||||
MIPS_INS_ADDV,
|
||||
MIPS_INS_ADDWC,
|
||||
MIPS_INS_ADD_A,
|
||||
MIPS_INS_ADDI,
|
||||
MIPS_INS_ADDIU,
|
||||
MIPS_INS_ALIGN,
|
||||
MIPS_INS_ALUIPC,
|
||||
MIPS_INS_AND,
|
||||
MIPS_INS_AND16,
|
||||
MIPS_INS_ANDI16,
|
||||
MIPS_INS_ANDI,
|
||||
MIPS_INS_APPEND,
|
||||
MIPS_INS_ASUB_S,
|
||||
MIPS_INS_ASUB_U,
|
||||
MIPS_INS_AUI,
|
||||
MIPS_INS_AUIPC,
|
||||
MIPS_INS_AVER_S,
|
||||
MIPS_INS_AVER_U,
|
||||
MIPS_INS_AVE_S,
|
||||
MIPS_INS_AVE_U,
|
||||
MIPS_INS_B16,
|
||||
MIPS_INS_BADDU,
|
||||
MIPS_INS_BAL,
|
||||
MIPS_INS_BALC,
|
||||
MIPS_INS_BALIGN,
|
||||
MIPS_INS_BBIT0,
|
||||
MIPS_INS_BBIT032,
|
||||
MIPS_INS_BBIT1,
|
||||
MIPS_INS_BBIT132,
|
||||
MIPS_INS_BC,
|
||||
MIPS_INS_BC0F,
|
||||
MIPS_INS_BC0FL,
|
||||
MIPS_INS_BC0T,
|
||||
MIPS_INS_BC0TL,
|
||||
MIPS_INS_BC1EQZ,
|
||||
MIPS_INS_BC1F,
|
||||
MIPS_INS_BC1FL,
|
||||
MIPS_INS_BC1NEZ,
|
||||
MIPS_INS_BC1T,
|
||||
MIPS_INS_BC1TL,
|
||||
MIPS_INS_BC2EQZ,
|
||||
MIPS_INS_BC2F,
|
||||
MIPS_INS_BC2FL,
|
||||
MIPS_INS_BC2NEZ,
|
||||
MIPS_INS_BC2T,
|
||||
MIPS_INS_BC2TL,
|
||||
MIPS_INS_BC3F,
|
||||
MIPS_INS_BC3FL,
|
||||
MIPS_INS_BC3T,
|
||||
MIPS_INS_BC3TL,
|
||||
MIPS_INS_BCLRI,
|
||||
MIPS_INS_BCLR,
|
||||
MIPS_INS_BEQ,
|
||||
MIPS_INS_BEQC,
|
||||
MIPS_INS_BEQL,
|
||||
MIPS_INS_BEQZ16,
|
||||
MIPS_INS_BEQZALC,
|
||||
MIPS_INS_BEQZC,
|
||||
MIPS_INS_BGEC,
|
||||
MIPS_INS_BGEUC,
|
||||
MIPS_INS_BGEZ,
|
||||
MIPS_INS_BGEZAL,
|
||||
MIPS_INS_BGEZALC,
|
||||
MIPS_INS_BGEZALL,
|
||||
MIPS_INS_BGEZALS,
|
||||
MIPS_INS_BGEZC,
|
||||
MIPS_INS_BGEZL,
|
||||
MIPS_INS_BGTZ,
|
||||
MIPS_INS_BGTZALC,
|
||||
MIPS_INS_BGTZC,
|
||||
MIPS_INS_BGTZL,
|
||||
MIPS_INS_BINSLI,
|
||||
MIPS_INS_BINSL,
|
||||
MIPS_INS_BINSRI,
|
||||
MIPS_INS_BINSR,
|
||||
MIPS_INS_BITREV,
|
||||
MIPS_INS_BITSWAP,
|
||||
MIPS_INS_BLEZ,
|
||||
MIPS_INS_BLEZALC,
|
||||
MIPS_INS_BLEZC,
|
||||
MIPS_INS_BLEZL,
|
||||
MIPS_INS_BLTC,
|
||||
MIPS_INS_BLTUC,
|
||||
MIPS_INS_BLTZ,
|
||||
MIPS_INS_BLTZAL,
|
||||
MIPS_INS_BLTZALC,
|
||||
MIPS_INS_BLTZALL,
|
||||
MIPS_INS_BLTZALS,
|
||||
MIPS_INS_BLTZC,
|
||||
MIPS_INS_BLTZL,
|
||||
MIPS_INS_BMNZI,
|
||||
MIPS_INS_BMNZ,
|
||||
MIPS_INS_BMZI,
|
||||
MIPS_INS_BMZ,
|
||||
MIPS_INS_BNE,
|
||||
MIPS_INS_BNEC,
|
||||
MIPS_INS_BNEGI,
|
||||
MIPS_INS_BNEG,
|
||||
MIPS_INS_BNEL,
|
||||
MIPS_INS_BNEZ16,
|
||||
MIPS_INS_BNEZALC,
|
||||
MIPS_INS_BNEZC,
|
||||
MIPS_INS_BNVC,
|
||||
MIPS_INS_BNZ,
|
||||
MIPS_INS_BOVC,
|
||||
MIPS_INS_BPOSGE32,
|
||||
MIPS_INS_BREAK,
|
||||
MIPS_INS_BREAK16,
|
||||
MIPS_INS_BSELI,
|
||||
MIPS_INS_BSEL,
|
||||
MIPS_INS_BSETI,
|
||||
MIPS_INS_BSET,
|
||||
MIPS_INS_BZ,
|
||||
MIPS_INS_BEQZ,
|
||||
MIPS_INS_B,
|
||||
MIPS_INS_BNEZ,
|
||||
MIPS_INS_BTEQZ,
|
||||
MIPS_INS_BTNEZ,
|
||||
MIPS_INS_CACHE,
|
||||
MIPS_INS_CEIL,
|
||||
MIPS_INS_CEQI,
|
||||
MIPS_INS_CEQ,
|
||||
MIPS_INS_CFC1,
|
||||
MIPS_INS_CFCMSA,
|
||||
MIPS_INS_CINS,
|
||||
MIPS_INS_CINS32,
|
||||
MIPS_INS_CLASS,
|
||||
MIPS_INS_CLEI_S,
|
||||
MIPS_INS_CLEI_U,
|
||||
MIPS_INS_CLE_S,
|
||||
MIPS_INS_CLE_U,
|
||||
MIPS_INS_CLO,
|
||||
MIPS_INS_CLTI_S,
|
||||
MIPS_INS_CLTI_U,
|
||||
MIPS_INS_CLT_S,
|
||||
MIPS_INS_CLT_U,
|
||||
MIPS_INS_CLZ,
|
||||
MIPS_INS_CMPGDU,
|
||||
MIPS_INS_CMPGU,
|
||||
MIPS_INS_CMPU,
|
||||
MIPS_INS_CMP,
|
||||
MIPS_INS_COPY_S,
|
||||
MIPS_INS_COPY_U,
|
||||
MIPS_INS_CTC1,
|
||||
MIPS_INS_CTCMSA,
|
||||
MIPS_INS_CVT,
|
||||
MIPS_INS_C,
|
||||
MIPS_INS_CMPI,
|
||||
MIPS_INS_DADD,
|
||||
MIPS_INS_DADDI,
|
||||
MIPS_INS_DADDIU,
|
||||
MIPS_INS_DADDU,
|
||||
MIPS_INS_DAHI,
|
||||
MIPS_INS_DALIGN,
|
||||
MIPS_INS_DATI,
|
||||
MIPS_INS_DAUI,
|
||||
MIPS_INS_DBITSWAP,
|
||||
MIPS_INS_DCLO,
|
||||
MIPS_INS_DCLZ,
|
||||
MIPS_INS_DDIV,
|
||||
MIPS_INS_DDIVU,
|
||||
MIPS_INS_DERET,
|
||||
MIPS_INS_DEXT,
|
||||
MIPS_INS_DEXTM,
|
||||
MIPS_INS_DEXTU,
|
||||
MIPS_INS_DI,
|
||||
MIPS_INS_DINS,
|
||||
MIPS_INS_DINSM,
|
||||
MIPS_INS_DINSU,
|
||||
MIPS_INS_DIV,
|
||||
MIPS_INS_DIVU,
|
||||
MIPS_INS_DIV_S,
|
||||
MIPS_INS_DIV_U,
|
||||
MIPS_INS_DLSA,
|
||||
MIPS_INS_DMFC0,
|
||||
MIPS_INS_DMFC1,
|
||||
MIPS_INS_DMFC2,
|
||||
MIPS_INS_DMOD,
|
||||
MIPS_INS_DMODU,
|
||||
MIPS_INS_DMTC0,
|
||||
MIPS_INS_DMTC1,
|
||||
MIPS_INS_DMTC2,
|
||||
MIPS_INS_DMUH,
|
||||
MIPS_INS_DMUHU,
|
||||
MIPS_INS_DMUL,
|
||||
MIPS_INS_DMULT,
|
||||
MIPS_INS_DMULTU,
|
||||
MIPS_INS_DMULU,
|
||||
MIPS_INS_DOTP_S,
|
||||
MIPS_INS_DOTP_U,
|
||||
MIPS_INS_DPADD_S,
|
||||
MIPS_INS_DPADD_U,
|
||||
MIPS_INS_DPAQX_SA,
|
||||
MIPS_INS_DPAQX_S,
|
||||
MIPS_INS_DPAQ_SA,
|
||||
MIPS_INS_DPAQ_S,
|
||||
MIPS_INS_DPAU,
|
||||
MIPS_INS_DPAX,
|
||||
MIPS_INS_DPA,
|
||||
MIPS_INS_DPOP,
|
||||
MIPS_INS_DPSQX_SA,
|
||||
MIPS_INS_DPSQX_S,
|
||||
MIPS_INS_DPSQ_SA,
|
||||
MIPS_INS_DPSQ_S,
|
||||
MIPS_INS_DPSUB_S,
|
||||
MIPS_INS_DPSUB_U,
|
||||
MIPS_INS_DPSU,
|
||||
MIPS_INS_DPSX,
|
||||
MIPS_INS_DPS,
|
||||
MIPS_INS_DROTR,
|
||||
MIPS_INS_DROTR32,
|
||||
MIPS_INS_DROTRV,
|
||||
MIPS_INS_DSBH,
|
||||
MIPS_INS_DSHD,
|
||||
MIPS_INS_DSLL,
|
||||
MIPS_INS_DSLL32,
|
||||
MIPS_INS_DSLLV,
|
||||
MIPS_INS_DSRA,
|
||||
MIPS_INS_DSRA32,
|
||||
MIPS_INS_DSRAV,
|
||||
MIPS_INS_DSRL,
|
||||
MIPS_INS_DSRL32,
|
||||
MIPS_INS_DSRLV,
|
||||
MIPS_INS_DSUB,
|
||||
MIPS_INS_DSUBU,
|
||||
MIPS_INS_EHB,
|
||||
MIPS_INS_EI,
|
||||
MIPS_INS_ERET,
|
||||
MIPS_INS_EXT,
|
||||
MIPS_INS_EXTP,
|
||||
MIPS_INS_EXTPDP,
|
||||
MIPS_INS_EXTPDPV,
|
||||
MIPS_INS_EXTPV,
|
||||
MIPS_INS_EXTRV_RS,
|
||||
MIPS_INS_EXTRV_R,
|
||||
MIPS_INS_EXTRV_S,
|
||||
MIPS_INS_EXTRV,
|
||||
MIPS_INS_EXTR_RS,
|
||||
MIPS_INS_EXTR_R,
|
||||
MIPS_INS_EXTR_S,
|
||||
MIPS_INS_EXTR,
|
||||
MIPS_INS_EXTS,
|
||||
MIPS_INS_EXTS32,
|
||||
MIPS_INS_ABS,
|
||||
MIPS_INS_FADD,
|
||||
MIPS_INS_FCAF,
|
||||
MIPS_INS_FCEQ,
|
||||
MIPS_INS_FCLASS,
|
||||
MIPS_INS_FCLE,
|
||||
MIPS_INS_FCLT,
|
||||
MIPS_INS_FCNE,
|
||||
MIPS_INS_FCOR,
|
||||
MIPS_INS_FCUEQ,
|
||||
MIPS_INS_FCULE,
|
||||
MIPS_INS_FCULT,
|
||||
MIPS_INS_FCUNE,
|
||||
MIPS_INS_FCUN,
|
||||
MIPS_INS_FDIV,
|
||||
MIPS_INS_FEXDO,
|
||||
MIPS_INS_FEXP2,
|
||||
MIPS_INS_FEXUPL,
|
||||
MIPS_INS_FEXUPR,
|
||||
MIPS_INS_FFINT_S,
|
||||
MIPS_INS_FFINT_U,
|
||||
MIPS_INS_FFQL,
|
||||
MIPS_INS_FFQR,
|
||||
MIPS_INS_FILL,
|
||||
MIPS_INS_FLOG2,
|
||||
MIPS_INS_FLOOR,
|
||||
MIPS_INS_FMADD,
|
||||
MIPS_INS_FMAX_A,
|
||||
MIPS_INS_FMAX,
|
||||
MIPS_INS_FMIN_A,
|
||||
MIPS_INS_FMIN,
|
||||
MIPS_INS_MOV,
|
||||
MIPS_INS_FMSUB,
|
||||
MIPS_INS_FMUL,
|
||||
MIPS_INS_MUL,
|
||||
MIPS_INS_NEG,
|
||||
MIPS_INS_FRCP,
|
||||
MIPS_INS_FRINT,
|
||||
MIPS_INS_FRSQRT,
|
||||
MIPS_INS_FSAF,
|
||||
MIPS_INS_FSEQ,
|
||||
MIPS_INS_FSLE,
|
||||
MIPS_INS_FSLT,
|
||||
MIPS_INS_FSNE,
|
||||
MIPS_INS_FSOR,
|
||||
MIPS_INS_FSQRT,
|
||||
MIPS_INS_SQRT,
|
||||
MIPS_INS_FSUB,
|
||||
MIPS_INS_SUB,
|
||||
MIPS_INS_FSUEQ,
|
||||
MIPS_INS_FSULE,
|
||||
MIPS_INS_FSULT,
|
||||
MIPS_INS_FSUNE,
|
||||
MIPS_INS_FSUN,
|
||||
MIPS_INS_FTINT_S,
|
||||
MIPS_INS_FTINT_U,
|
||||
MIPS_INS_FTQ,
|
||||
MIPS_INS_FTRUNC_S,
|
||||
MIPS_INS_FTRUNC_U,
|
||||
MIPS_INS_HADD_S,
|
||||
MIPS_INS_HADD_U,
|
||||
MIPS_INS_HSUB_S,
|
||||
MIPS_INS_HSUB_U,
|
||||
MIPS_INS_ILVEV,
|
||||
MIPS_INS_ILVL,
|
||||
MIPS_INS_ILVOD,
|
||||
MIPS_INS_ILVR,
|
||||
MIPS_INS_INS,
|
||||
MIPS_INS_INSERT,
|
||||
MIPS_INS_INSV,
|
||||
MIPS_INS_INSVE,
|
||||
MIPS_INS_J,
|
||||
MIPS_INS_JAL,
|
||||
MIPS_INS_JALR,
|
||||
MIPS_INS_JALRS16,
|
||||
MIPS_INS_JALRS,
|
||||
MIPS_INS_JALS,
|
||||
MIPS_INS_JALX,
|
||||
MIPS_INS_JIALC,
|
||||
MIPS_INS_JIC,
|
||||
MIPS_INS_JR,
|
||||
MIPS_INS_JR16,
|
||||
MIPS_INS_JRADDIUSP,
|
||||
MIPS_INS_JRC,
|
||||
MIPS_INS_JALRC,
|
||||
MIPS_INS_LB,
|
||||
MIPS_INS_LBU16,
|
||||
MIPS_INS_LBUX,
|
||||
MIPS_INS_LBU,
|
||||
MIPS_INS_LD,
|
||||
MIPS_INS_LDC1,
|
||||
MIPS_INS_LDC2,
|
||||
MIPS_INS_LDC3,
|
||||
MIPS_INS_LDI,
|
||||
MIPS_INS_LDL,
|
||||
MIPS_INS_LDPC,
|
||||
MIPS_INS_LDR,
|
||||
MIPS_INS_LDXC1,
|
||||
MIPS_INS_LH,
|
||||
MIPS_INS_LHU16,
|
||||
MIPS_INS_LHX,
|
||||
MIPS_INS_LHU,
|
||||
MIPS_INS_LI16,
|
||||
MIPS_INS_LL,
|
||||
MIPS_INS_LLD,
|
||||
MIPS_INS_LSA,
|
||||
MIPS_INS_LUXC1,
|
||||
MIPS_INS_LUI,
|
||||
MIPS_INS_LW,
|
||||
MIPS_INS_LW16,
|
||||
MIPS_INS_LWC1,
|
||||
MIPS_INS_LWC2,
|
||||
MIPS_INS_LWC3,
|
||||
MIPS_INS_LWL,
|
||||
MIPS_INS_LWM16,
|
||||
MIPS_INS_LWM32,
|
||||
MIPS_INS_LWPC,
|
||||
MIPS_INS_LWP,
|
||||
MIPS_INS_LWR,
|
||||
MIPS_INS_LWUPC,
|
||||
MIPS_INS_LWU,
|
||||
MIPS_INS_LWX,
|
||||
MIPS_INS_LWXC1,
|
||||
MIPS_INS_LWXS,
|
||||
MIPS_INS_LI,
|
||||
MIPS_INS_MADD,
|
||||
MIPS_INS_MADDF,
|
||||
MIPS_INS_MADDR_Q,
|
||||
MIPS_INS_MADDU,
|
||||
MIPS_INS_MADDV,
|
||||
MIPS_INS_MADD_Q,
|
||||
MIPS_INS_MAQ_SA,
|
||||
MIPS_INS_MAQ_S,
|
||||
MIPS_INS_MAXA,
|
||||
MIPS_INS_MAXI_S,
|
||||
MIPS_INS_MAXI_U,
|
||||
MIPS_INS_MAX_A,
|
||||
MIPS_INS_MAX,
|
||||
MIPS_INS_MAX_S,
|
||||
MIPS_INS_MAX_U,
|
||||
MIPS_INS_MFC0,
|
||||
MIPS_INS_MFC1,
|
||||
MIPS_INS_MFC2,
|
||||
MIPS_INS_MFHC1,
|
||||
MIPS_INS_MFHI,
|
||||
MIPS_INS_MFLO,
|
||||
MIPS_INS_MINA,
|
||||
MIPS_INS_MINI_S,
|
||||
MIPS_INS_MINI_U,
|
||||
MIPS_INS_MIN_A,
|
||||
MIPS_INS_MIN,
|
||||
MIPS_INS_MIN_S,
|
||||
MIPS_INS_MIN_U,
|
||||
MIPS_INS_MOD,
|
||||
MIPS_INS_MODSUB,
|
||||
MIPS_INS_MODU,
|
||||
MIPS_INS_MOD_S,
|
||||
MIPS_INS_MOD_U,
|
||||
MIPS_INS_MOVE,
|
||||
MIPS_INS_MOVEP,
|
||||
MIPS_INS_MOVF,
|
||||
MIPS_INS_MOVN,
|
||||
MIPS_INS_MOVT,
|
||||
MIPS_INS_MOVZ,
|
||||
MIPS_INS_MSUB,
|
||||
MIPS_INS_MSUBF,
|
||||
MIPS_INS_MSUBR_Q,
|
||||
MIPS_INS_MSUBU,
|
||||
MIPS_INS_MSUBV,
|
||||
MIPS_INS_MSUB_Q,
|
||||
MIPS_INS_MTC0,
|
||||
MIPS_INS_MTC1,
|
||||
MIPS_INS_MTC2,
|
||||
MIPS_INS_MTHC1,
|
||||
MIPS_INS_MTHI,
|
||||
MIPS_INS_MTHLIP,
|
||||
MIPS_INS_MTLO,
|
||||
MIPS_INS_MTM0,
|
||||
MIPS_INS_MTM1,
|
||||
MIPS_INS_MTM2,
|
||||
MIPS_INS_MTP0,
|
||||
MIPS_INS_MTP1,
|
||||
MIPS_INS_MTP2,
|
||||
MIPS_INS_MUH,
|
||||
MIPS_INS_MUHU,
|
||||
MIPS_INS_MULEQ_S,
|
||||
MIPS_INS_MULEU_S,
|
||||
MIPS_INS_MULQ_RS,
|
||||
MIPS_INS_MULQ_S,
|
||||
MIPS_INS_MULR_Q,
|
||||
MIPS_INS_MULSAQ_S,
|
||||
MIPS_INS_MULSA,
|
||||
MIPS_INS_MULT,
|
||||
MIPS_INS_MULTU,
|
||||
MIPS_INS_MULU,
|
||||
MIPS_INS_MULV,
|
||||
MIPS_INS_MUL_Q,
|
||||
MIPS_INS_MUL_S,
|
||||
MIPS_INS_NLOC,
|
||||
MIPS_INS_NLZC,
|
||||
MIPS_INS_NMADD,
|
||||
MIPS_INS_NMSUB,
|
||||
MIPS_INS_NOR,
|
||||
MIPS_INS_NORI,
|
||||
MIPS_INS_NOT16,
|
||||
MIPS_INS_NOT,
|
||||
MIPS_INS_OR,
|
||||
MIPS_INS_OR16,
|
||||
MIPS_INS_ORI,
|
||||
MIPS_INS_PACKRL,
|
||||
MIPS_INS_PAUSE,
|
||||
MIPS_INS_PCKEV,
|
||||
MIPS_INS_PCKOD,
|
||||
MIPS_INS_PCNT,
|
||||
MIPS_INS_PICK,
|
||||
MIPS_INS_POP,
|
||||
MIPS_INS_PRECEQU,
|
||||
MIPS_INS_PRECEQ,
|
||||
MIPS_INS_PRECEU,
|
||||
MIPS_INS_PRECRQU_S,
|
||||
MIPS_INS_PRECRQ,
|
||||
MIPS_INS_PRECRQ_RS,
|
||||
MIPS_INS_PRECR,
|
||||
MIPS_INS_PRECR_SRA,
|
||||
MIPS_INS_PRECR_SRA_R,
|
||||
MIPS_INS_PREF,
|
||||
MIPS_INS_PREPEND,
|
||||
MIPS_INS_RADDU,
|
||||
MIPS_INS_RDDSP,
|
||||
MIPS_INS_RDHWR,
|
||||
MIPS_INS_REPLV,
|
||||
MIPS_INS_REPL,
|
||||
MIPS_INS_RINT,
|
||||
MIPS_INS_ROTR,
|
||||
MIPS_INS_ROTRV,
|
||||
MIPS_INS_ROUND,
|
||||
MIPS_INS_SAT_S,
|
||||
MIPS_INS_SAT_U,
|
||||
MIPS_INS_SB,
|
||||
MIPS_INS_SB16,
|
||||
MIPS_INS_SC,
|
||||
MIPS_INS_SCD,
|
||||
MIPS_INS_SD,
|
||||
MIPS_INS_SDBBP,
|
||||
MIPS_INS_SDBBP16,
|
||||
MIPS_INS_SDC1,
|
||||
MIPS_INS_SDC2,
|
||||
MIPS_INS_SDC3,
|
||||
MIPS_INS_SDL,
|
||||
MIPS_INS_SDR,
|
||||
MIPS_INS_SDXC1,
|
||||
MIPS_INS_SEB,
|
||||
MIPS_INS_SEH,
|
||||
MIPS_INS_SELEQZ,
|
||||
MIPS_INS_SELNEZ,
|
||||
MIPS_INS_SEL,
|
||||
MIPS_INS_SEQ,
|
||||
MIPS_INS_SEQI,
|
||||
MIPS_INS_SH,
|
||||
MIPS_INS_SH16,
|
||||
MIPS_INS_SHF,
|
||||
MIPS_INS_SHILO,
|
||||
MIPS_INS_SHILOV,
|
||||
MIPS_INS_SHLLV,
|
||||
MIPS_INS_SHLLV_S,
|
||||
MIPS_INS_SHLL,
|
||||
MIPS_INS_SHLL_S,
|
||||
MIPS_INS_SHRAV,
|
||||
MIPS_INS_SHRAV_R,
|
||||
MIPS_INS_SHRA,
|
||||
MIPS_INS_SHRA_R,
|
||||
MIPS_INS_SHRLV,
|
||||
MIPS_INS_SHRL,
|
||||
MIPS_INS_SLDI,
|
||||
MIPS_INS_SLD,
|
||||
MIPS_INS_SLL,
|
||||
MIPS_INS_SLL16,
|
||||
MIPS_INS_SLLI,
|
||||
MIPS_INS_SLLV,
|
||||
MIPS_INS_SLT,
|
||||
MIPS_INS_SLTI,
|
||||
MIPS_INS_SLTIU,
|
||||
MIPS_INS_SLTU,
|
||||
MIPS_INS_SNE,
|
||||
MIPS_INS_SNEI,
|
||||
MIPS_INS_SPLATI,
|
||||
MIPS_INS_SPLAT,
|
||||
MIPS_INS_SRA,
|
||||
MIPS_INS_SRAI,
|
||||
MIPS_INS_SRARI,
|
||||
MIPS_INS_SRAR,
|
||||
MIPS_INS_SRAV,
|
||||
MIPS_INS_SRL,
|
||||
MIPS_INS_SRL16,
|
||||
MIPS_INS_SRLI,
|
||||
MIPS_INS_SRLRI,
|
||||
MIPS_INS_SRLR,
|
||||
MIPS_INS_SRLV,
|
||||
MIPS_INS_SSNOP,
|
||||
MIPS_INS_ST,
|
||||
MIPS_INS_SUBQH,
|
||||
MIPS_INS_SUBQH_R,
|
||||
MIPS_INS_SUBQ,
|
||||
MIPS_INS_SUBQ_S,
|
||||
MIPS_INS_SUBSUS_U,
|
||||
MIPS_INS_SUBSUU_S,
|
||||
MIPS_INS_SUBS_S,
|
||||
MIPS_INS_SUBS_U,
|
||||
MIPS_INS_SUBU16,
|
||||
MIPS_INS_SUBUH,
|
||||
MIPS_INS_SUBUH_R,
|
||||
MIPS_INS_SUBU,
|
||||
MIPS_INS_SUBU_S,
|
||||
MIPS_INS_SUBVI,
|
||||
MIPS_INS_SUBV,
|
||||
MIPS_INS_SUXC1,
|
||||
MIPS_INS_SW,
|
||||
MIPS_INS_SW16,
|
||||
MIPS_INS_SWC1,
|
||||
MIPS_INS_SWC2,
|
||||
MIPS_INS_SWC3,
|
||||
MIPS_INS_SWL,
|
||||
MIPS_INS_SWM16,
|
||||
MIPS_INS_SWM32,
|
||||
MIPS_INS_SWP,
|
||||
MIPS_INS_SWR,
|
||||
MIPS_INS_SWXC1,
|
||||
MIPS_INS_SYNC,
|
||||
MIPS_INS_SYNCI,
|
||||
MIPS_INS_SYSCALL,
|
||||
MIPS_INS_TEQ,
|
||||
MIPS_INS_TEQI,
|
||||
MIPS_INS_TGE,
|
||||
MIPS_INS_TGEI,
|
||||
MIPS_INS_TGEIU,
|
||||
MIPS_INS_TGEU,
|
||||
MIPS_INS_TLBP,
|
||||
MIPS_INS_TLBR,
|
||||
MIPS_INS_TLBWI,
|
||||
MIPS_INS_TLBWR,
|
||||
MIPS_INS_TLT,
|
||||
MIPS_INS_TLTI,
|
||||
MIPS_INS_TLTIU,
|
||||
MIPS_INS_TLTU,
|
||||
MIPS_INS_TNE,
|
||||
MIPS_INS_TNEI,
|
||||
MIPS_INS_TRUNC,
|
||||
MIPS_INS_V3MULU,
|
||||
MIPS_INS_VMM0,
|
||||
MIPS_INS_VMULU,
|
||||
MIPS_INS_VSHF,
|
||||
MIPS_INS_WAIT,
|
||||
MIPS_INS_WRDSP,
|
||||
MIPS_INS_WSBH,
|
||||
MIPS_INS_XOR,
|
||||
MIPS_INS_XOR16,
|
||||
MIPS_INS_XORI,
|
||||
|
||||
//> some alias instructions
|
||||
MIPS_INS_NOP,
|
||||
MIPS_INS_NEGU,
|
||||
|
||||
//> special instructions
|
||||
MIPS_INS_JALR_HB, // jump and link with Hazard Barrier
|
||||
MIPS_INS_JR_HB, // jump register with Hazard Barrier
|
||||
|
||||
MIPS_INS_ENDING,
|
||||
} mips_insn;
|
||||
|
||||
/// Group of MIPS instructions
|
||||
typedef enum mips_insn_group {
|
||||
MIPS_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
MIPS_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
// all call instructions
|
||||
MIPS_GRP_CALL, ///< = CS_GRP_CALL
|
||||
// all return instructions
|
||||
MIPS_GRP_RET, ///< = CS_GRP_RET
|
||||
// all interrupt instructions (int+syscall)
|
||||
MIPS_GRP_INT, ///< = CS_GRP_INT
|
||||
// all interrupt return instructions
|
||||
MIPS_GRP_IRET, ///< = CS_GRP_IRET
|
||||
// all privileged instructions
|
||||
MIPS_GRP_PRIVILEGE, ///< = CS_GRP_PRIVILEGE
|
||||
// all relative branching instructions
|
||||
MIPS_GRP_BRANCH_RELATIVE, ///< = CS_GRP_BRANCH_RELATIVE
|
||||
|
||||
// Architecture-specific groups
|
||||
MIPS_GRP_BITCOUNT = 128,
|
||||
MIPS_GRP_DSP,
|
||||
MIPS_GRP_DSPR2,
|
||||
MIPS_GRP_FPIDX,
|
||||
MIPS_GRP_MSA,
|
||||
MIPS_GRP_MIPS32R2,
|
||||
MIPS_GRP_MIPS64,
|
||||
MIPS_GRP_MIPS64R2,
|
||||
MIPS_GRP_SEINREG,
|
||||
MIPS_GRP_STDENC,
|
||||
MIPS_GRP_SWAP,
|
||||
MIPS_GRP_MICROMIPS,
|
||||
MIPS_GRP_MIPS16MODE,
|
||||
MIPS_GRP_FP64BIT,
|
||||
MIPS_GRP_NONANSFPMATH,
|
||||
MIPS_GRP_NOTFP64BIT,
|
||||
MIPS_GRP_NOTINMICROMIPS,
|
||||
MIPS_GRP_NOTNACL,
|
||||
MIPS_GRP_NOTMIPS32R6,
|
||||
MIPS_GRP_NOTMIPS64R6,
|
||||
MIPS_GRP_CNMIPS,
|
||||
MIPS_GRP_MIPS32,
|
||||
MIPS_GRP_MIPS32R6,
|
||||
MIPS_GRP_MIPS64R6,
|
||||
MIPS_GRP_MIPS2,
|
||||
MIPS_GRP_MIPS3,
|
||||
MIPS_GRP_MIPS3_32,
|
||||
MIPS_GRP_MIPS3_32R2,
|
||||
MIPS_GRP_MIPS4_32,
|
||||
MIPS_GRP_MIPS4_32R2,
|
||||
MIPS_GRP_MIPS5_32R2,
|
||||
MIPS_GRP_GP32BIT,
|
||||
MIPS_GRP_GP64BIT,
|
||||
|
||||
MIPS_GRP_ENDING,
|
||||
} mips_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
122
ai_anti_malware/capstone/include/capstone/platform.h
Normal file
122
ai_anti_malware/capstone/include/capstone/platform.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Axel Souchet & Nguyen Anh Quynh, 2014 */
|
||||
|
||||
#ifndef CAPSTONE_PLATFORM_H
|
||||
#define CAPSTONE_PLATFORM_H
|
||||
|
||||
|
||||
// handle C99 issue (for pre-2013 VisualStudio)
|
||||
#if !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64))
|
||||
// MSVC
|
||||
|
||||
// stdbool.h
|
||||
#if (_MSC_VER < 1800) || defined(_KERNEL_MODE)
|
||||
// this system does not have stdbool.h
|
||||
#ifndef __cplusplus
|
||||
typedef unsigned char bool;
|
||||
#define false 0
|
||||
#define true 1
|
||||
#endif // __cplusplus
|
||||
|
||||
#else
|
||||
// VisualStudio 2013+ -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif // (_MSC_VER < 1800) || defined(_KERNEL_MODE)
|
||||
|
||||
#else
|
||||
// not MSVC -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif // !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64))
|
||||
|
||||
|
||||
// handle inttypes.h / stdint.h compatibility
|
||||
#if defined(_WIN32_WCE) && (_WIN32_WCE < 0x800)
|
||||
#include "windowsce/stdint.h"
|
||||
#endif // defined(_WIN32_WCE) && (_WIN32_WCE < 0x800)
|
||||
|
||||
#if defined(CAPSTONE_HAS_OSXKERNEL) || (defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE)))
|
||||
// this system does not have inttypes.h
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1600 || defined(_KERNEL_MODE))
|
||||
// this system does not have stdint.h
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef signed long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER <= 1600 || defined(_KERNEL_MODE))
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600 || defined(_KERNEL_MODE))
|
||||
#define INT8_MIN (-127i8 - 1)
|
||||
#define INT16_MIN (-32767i16 - 1)
|
||||
#define INT32_MIN (-2147483647i32 - 1)
|
||||
#define INT64_MIN (-9223372036854775807i64 - 1)
|
||||
#define INT8_MAX 127i8
|
||||
#define INT16_MAX 32767i16
|
||||
#define INT32_MAX 2147483647i32
|
||||
#define INT64_MAX 9223372036854775807i64
|
||||
#define UINT8_MAX 0xffui8
|
||||
#define UINT16_MAX 0xffffui16
|
||||
#define UINT32_MAX 0xffffffffui32
|
||||
#define UINT64_MAX 0xffffffffffffffffui64
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER < 1600 || defined(_KERNEL_MODE))
|
||||
|
||||
#ifdef CAPSTONE_HAS_OSXKERNEL
|
||||
// this system has stdint.h
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#define __PRI_8_LENGTH_MODIFIER__ "hh"
|
||||
#define __PRI_64_LENGTH_MODIFIER__ "ll"
|
||||
|
||||
#define PRId8 __PRI_8_LENGTH_MODIFIER__ "d"
|
||||
#define PRIi8 __PRI_8_LENGTH_MODIFIER__ "i"
|
||||
#define PRIo8 __PRI_8_LENGTH_MODIFIER__ "o"
|
||||
#define PRIu8 __PRI_8_LENGTH_MODIFIER__ "u"
|
||||
#define PRIx8 __PRI_8_LENGTH_MODIFIER__ "x"
|
||||
#define PRIX8 __PRI_8_LENGTH_MODIFIER__ "X"
|
||||
|
||||
#define PRId16 "hd"
|
||||
#define PRIi16 "hi"
|
||||
#define PRIo16 "ho"
|
||||
#define PRIu16 "hu"
|
||||
#define PRIx16 "hx"
|
||||
#define PRIX16 "hX"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
#define PRId32 "ld"
|
||||
#define PRIi32 "li"
|
||||
#define PRIo32 "lo"
|
||||
#define PRIu32 "lu"
|
||||
#define PRIx32 "lx"
|
||||
#define PRIX32 "lX"
|
||||
#else // OSX
|
||||
#define PRId32 "d"
|
||||
#define PRIi32 "i"
|
||||
#define PRIo32 "o"
|
||||
#define PRIu32 "u"
|
||||
#define PRIx32 "x"
|
||||
#define PRIX32 "X"
|
||||
#endif // defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
// redefine functions from inttypes.h used in cstool
|
||||
#define strtoull _strtoui64
|
||||
#endif
|
||||
|
||||
#define PRId64 __PRI_64_LENGTH_MODIFIER__ "d"
|
||||
#define PRIi64 __PRI_64_LENGTH_MODIFIER__ "i"
|
||||
#define PRIo64 __PRI_64_LENGTH_MODIFIER__ "o"
|
||||
#define PRIu64 __PRI_64_LENGTH_MODIFIER__ "u"
|
||||
#define PRIx64 __PRI_64_LENGTH_MODIFIER__ "x"
|
||||
#define PRIX64 __PRI_64_LENGTH_MODIFIER__ "X"
|
||||
|
||||
#else
|
||||
// this system has inttypes.h by default
|
||||
#include <inttypes.h>
|
||||
#endif // defined(CAPSTONE_HAS_OSXKERNEL) || (defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE)))
|
||||
|
||||
#endif
|
||||
1463
ai_anti_malware/capstone/include/capstone/ppc.h
Normal file
1463
ai_anti_malware/capstone/include/capstone/ppc.h
Normal file
File diff suppressed because it is too large
Load Diff
520
ai_anti_malware/capstone/include/capstone/sparc.h
Normal file
520
ai_anti_malware/capstone/include/capstone/sparc.h
Normal file
@@ -0,0 +1,520 @@
|
||||
#ifndef CAPSTONE_SPARC_H
|
||||
#define CAPSTONE_SPARC_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2014-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
// GCC SPARC toolchain has a default macro called "sparc" which breaks
|
||||
// compilation
|
||||
#undef sparc
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// Enums corresponding to Sparc condition codes, both icc's and fcc's.
|
||||
typedef enum sparc_cc {
|
||||
SPARC_CC_INVALID = 0, ///< invalid CC (default)
|
||||
// Integer condition codes
|
||||
SPARC_CC_ICC_A = 8+256, ///< Always
|
||||
SPARC_CC_ICC_N = 0+256, ///< Never
|
||||
SPARC_CC_ICC_NE = 9+256, ///< Not Equal
|
||||
SPARC_CC_ICC_E = 1+256, ///< Equal
|
||||
SPARC_CC_ICC_G = 10+256, ///< Greater
|
||||
SPARC_CC_ICC_LE = 2+256, ///< Less or Equal
|
||||
SPARC_CC_ICC_GE = 11+256, ///< Greater or Equal
|
||||
SPARC_CC_ICC_L = 3+256, ///< Less
|
||||
SPARC_CC_ICC_GU = 12+256, ///< Greater Unsigned
|
||||
SPARC_CC_ICC_LEU = 4+256, ///< Less or Equal Unsigned
|
||||
SPARC_CC_ICC_CC = 13+256, ///< Carry Clear/Great or Equal Unsigned
|
||||
SPARC_CC_ICC_CS = 5+256, ///< Carry Set/Less Unsigned
|
||||
SPARC_CC_ICC_POS = 14+256, ///< Positive
|
||||
SPARC_CC_ICC_NEG = 6+256, ///< Negative
|
||||
SPARC_CC_ICC_VC = 15+256, ///< Overflow Clear
|
||||
SPARC_CC_ICC_VS = 7+256, ///< Overflow Set
|
||||
|
||||
// Floating condition codes
|
||||
SPARC_CC_FCC_A = 8+16+256, ///< Always
|
||||
SPARC_CC_FCC_N = 0+16+256, ///< Never
|
||||
SPARC_CC_FCC_U = 7+16+256, ///< Unordered
|
||||
SPARC_CC_FCC_G = 6+16+256, ///< Greater
|
||||
SPARC_CC_FCC_UG = 5+16+256, ///< Unordered or Greater
|
||||
SPARC_CC_FCC_L = 4+16+256, ///< Less
|
||||
SPARC_CC_FCC_UL = 3+16+256, ///< Unordered or Less
|
||||
SPARC_CC_FCC_LG = 2+16+256, ///< Less or Greater
|
||||
SPARC_CC_FCC_NE = 1+16+256, ///< Not Equal
|
||||
SPARC_CC_FCC_E = 9+16+256, ///< Equal
|
||||
SPARC_CC_FCC_UE = 10+16+256, ///< Unordered or Equal
|
||||
SPARC_CC_FCC_GE = 11+16+256, ///< Greater or Equal
|
||||
SPARC_CC_FCC_UGE = 12+16+256, ///< Unordered or Greater or Equal
|
||||
SPARC_CC_FCC_LE = 13+16+256, ///< Less or Equal
|
||||
SPARC_CC_FCC_ULE = 14+16+256, ///< Unordered or Less or Equal
|
||||
SPARC_CC_FCC_O = 15+16+256, ///< Ordered
|
||||
} sparc_cc;
|
||||
|
||||
/// Branch hint
|
||||
typedef enum sparc_hint {
|
||||
SPARC_HINT_INVALID = 0, ///< no hint
|
||||
SPARC_HINT_A = 1 << 0, ///< annul delay slot instruction
|
||||
SPARC_HINT_PT = 1 << 1, ///< branch taken
|
||||
SPARC_HINT_PN = 1 << 2, ///< branch NOT taken
|
||||
} sparc_hint;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum sparc_op_type {
|
||||
SPARC_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
SPARC_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
SPARC_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
SPARC_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
} sparc_op_type;
|
||||
|
||||
/// SPARC registers
|
||||
typedef enum sparc_reg {
|
||||
SPARC_REG_INVALID = 0,
|
||||
|
||||
SPARC_REG_F0,
|
||||
SPARC_REG_F1,
|
||||
SPARC_REG_F2,
|
||||
SPARC_REG_F3,
|
||||
SPARC_REG_F4,
|
||||
SPARC_REG_F5,
|
||||
SPARC_REG_F6,
|
||||
SPARC_REG_F7,
|
||||
SPARC_REG_F8,
|
||||
SPARC_REG_F9,
|
||||
SPARC_REG_F10,
|
||||
SPARC_REG_F11,
|
||||
SPARC_REG_F12,
|
||||
SPARC_REG_F13,
|
||||
SPARC_REG_F14,
|
||||
SPARC_REG_F15,
|
||||
SPARC_REG_F16,
|
||||
SPARC_REG_F17,
|
||||
SPARC_REG_F18,
|
||||
SPARC_REG_F19,
|
||||
SPARC_REG_F20,
|
||||
SPARC_REG_F21,
|
||||
SPARC_REG_F22,
|
||||
SPARC_REG_F23,
|
||||
SPARC_REG_F24,
|
||||
SPARC_REG_F25,
|
||||
SPARC_REG_F26,
|
||||
SPARC_REG_F27,
|
||||
SPARC_REG_F28,
|
||||
SPARC_REG_F29,
|
||||
SPARC_REG_F30,
|
||||
SPARC_REG_F31,
|
||||
SPARC_REG_F32,
|
||||
SPARC_REG_F34,
|
||||
SPARC_REG_F36,
|
||||
SPARC_REG_F38,
|
||||
SPARC_REG_F40,
|
||||
SPARC_REG_F42,
|
||||
SPARC_REG_F44,
|
||||
SPARC_REG_F46,
|
||||
SPARC_REG_F48,
|
||||
SPARC_REG_F50,
|
||||
SPARC_REG_F52,
|
||||
SPARC_REG_F54,
|
||||
SPARC_REG_F56,
|
||||
SPARC_REG_F58,
|
||||
SPARC_REG_F60,
|
||||
SPARC_REG_F62,
|
||||
SPARC_REG_FCC0, // Floating condition codes
|
||||
SPARC_REG_FCC1,
|
||||
SPARC_REG_FCC2,
|
||||
SPARC_REG_FCC3,
|
||||
SPARC_REG_FP,
|
||||
SPARC_REG_G0,
|
||||
SPARC_REG_G1,
|
||||
SPARC_REG_G2,
|
||||
SPARC_REG_G3,
|
||||
SPARC_REG_G4,
|
||||
SPARC_REG_G5,
|
||||
SPARC_REG_G6,
|
||||
SPARC_REG_G7,
|
||||
SPARC_REG_I0,
|
||||
SPARC_REG_I1,
|
||||
SPARC_REG_I2,
|
||||
SPARC_REG_I3,
|
||||
SPARC_REG_I4,
|
||||
SPARC_REG_I5,
|
||||
SPARC_REG_I7,
|
||||
SPARC_REG_ICC, // Integer condition codes
|
||||
SPARC_REG_L0,
|
||||
SPARC_REG_L1,
|
||||
SPARC_REG_L2,
|
||||
SPARC_REG_L3,
|
||||
SPARC_REG_L4,
|
||||
SPARC_REG_L5,
|
||||
SPARC_REG_L6,
|
||||
SPARC_REG_L7,
|
||||
SPARC_REG_O0,
|
||||
SPARC_REG_O1,
|
||||
SPARC_REG_O2,
|
||||
SPARC_REG_O3,
|
||||
SPARC_REG_O4,
|
||||
SPARC_REG_O5,
|
||||
SPARC_REG_O7,
|
||||
SPARC_REG_SP,
|
||||
SPARC_REG_Y,
|
||||
|
||||
// special register
|
||||
SPARC_REG_XCC,
|
||||
|
||||
SPARC_REG_ENDING, // <-- mark the end of the list of registers
|
||||
|
||||
// extras
|
||||
SPARC_REG_O6 = SPARC_REG_SP,
|
||||
SPARC_REG_I6 = SPARC_REG_FP,
|
||||
} sparc_reg;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with SPARC_OP_MEM operand type above
|
||||
typedef struct sparc_op_mem {
|
||||
uint8_t base; ///< base register, can be safely interpreted as
|
||||
///< a value of type `sparc_reg`, but it is only
|
||||
///< one byte wide
|
||||
uint8_t index; ///< index register, same conditions apply here
|
||||
int32_t disp; ///< displacement/offset value
|
||||
} sparc_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_sparc_op {
|
||||
sparc_op_type type; ///< operand type
|
||||
union {
|
||||
sparc_reg reg; ///< register value for REG operand
|
||||
int64_t imm; ///< immediate value for IMM operand
|
||||
sparc_op_mem mem; ///< base/disp value for MEM operand
|
||||
};
|
||||
} cs_sparc_op;
|
||||
|
||||
/// Instruction structure
|
||||
typedef struct cs_sparc {
|
||||
sparc_cc cc; ///< code condition for this insn
|
||||
sparc_hint hint; ///< branch hint: encoding as bitwise OR of sparc_hint.
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
cs_sparc_op operands[4]; ///< operands for this instruction.
|
||||
} cs_sparc;
|
||||
|
||||
/// SPARC instruction
|
||||
typedef enum sparc_insn {
|
||||
SPARC_INS_INVALID = 0,
|
||||
|
||||
SPARC_INS_ADDCC,
|
||||
SPARC_INS_ADDX,
|
||||
SPARC_INS_ADDXCC,
|
||||
SPARC_INS_ADDXC,
|
||||
SPARC_INS_ADDXCCC,
|
||||
SPARC_INS_ADD,
|
||||
SPARC_INS_ALIGNADDR,
|
||||
SPARC_INS_ALIGNADDRL,
|
||||
SPARC_INS_ANDCC,
|
||||
SPARC_INS_ANDNCC,
|
||||
SPARC_INS_ANDN,
|
||||
SPARC_INS_AND,
|
||||
SPARC_INS_ARRAY16,
|
||||
SPARC_INS_ARRAY32,
|
||||
SPARC_INS_ARRAY8,
|
||||
SPARC_INS_B,
|
||||
SPARC_INS_JMP,
|
||||
SPARC_INS_BMASK,
|
||||
SPARC_INS_FB,
|
||||
SPARC_INS_BRGEZ,
|
||||
SPARC_INS_BRGZ,
|
||||
SPARC_INS_BRLEZ,
|
||||
SPARC_INS_BRLZ,
|
||||
SPARC_INS_BRNZ,
|
||||
SPARC_INS_BRZ,
|
||||
SPARC_INS_BSHUFFLE,
|
||||
SPARC_INS_CALL,
|
||||
SPARC_INS_CASX,
|
||||
SPARC_INS_CAS,
|
||||
SPARC_INS_CMASK16,
|
||||
SPARC_INS_CMASK32,
|
||||
SPARC_INS_CMASK8,
|
||||
SPARC_INS_CMP,
|
||||
SPARC_INS_EDGE16,
|
||||
SPARC_INS_EDGE16L,
|
||||
SPARC_INS_EDGE16LN,
|
||||
SPARC_INS_EDGE16N,
|
||||
SPARC_INS_EDGE32,
|
||||
SPARC_INS_EDGE32L,
|
||||
SPARC_INS_EDGE32LN,
|
||||
SPARC_INS_EDGE32N,
|
||||
SPARC_INS_EDGE8,
|
||||
SPARC_INS_EDGE8L,
|
||||
SPARC_INS_EDGE8LN,
|
||||
SPARC_INS_EDGE8N,
|
||||
SPARC_INS_FABSD,
|
||||
SPARC_INS_FABSQ,
|
||||
SPARC_INS_FABSS,
|
||||
SPARC_INS_FADDD,
|
||||
SPARC_INS_FADDQ,
|
||||
SPARC_INS_FADDS,
|
||||
SPARC_INS_FALIGNDATA,
|
||||
SPARC_INS_FAND,
|
||||
SPARC_INS_FANDNOT1,
|
||||
SPARC_INS_FANDNOT1S,
|
||||
SPARC_INS_FANDNOT2,
|
||||
SPARC_INS_FANDNOT2S,
|
||||
SPARC_INS_FANDS,
|
||||
SPARC_INS_FCHKSM16,
|
||||
SPARC_INS_FCMPD,
|
||||
SPARC_INS_FCMPEQ16,
|
||||
SPARC_INS_FCMPEQ32,
|
||||
SPARC_INS_FCMPGT16,
|
||||
SPARC_INS_FCMPGT32,
|
||||
SPARC_INS_FCMPLE16,
|
||||
SPARC_INS_FCMPLE32,
|
||||
SPARC_INS_FCMPNE16,
|
||||
SPARC_INS_FCMPNE32,
|
||||
SPARC_INS_FCMPQ,
|
||||
SPARC_INS_FCMPS,
|
||||
SPARC_INS_FDIVD,
|
||||
SPARC_INS_FDIVQ,
|
||||
SPARC_INS_FDIVS,
|
||||
SPARC_INS_FDMULQ,
|
||||
SPARC_INS_FDTOI,
|
||||
SPARC_INS_FDTOQ,
|
||||
SPARC_INS_FDTOS,
|
||||
SPARC_INS_FDTOX,
|
||||
SPARC_INS_FEXPAND,
|
||||
SPARC_INS_FHADDD,
|
||||
SPARC_INS_FHADDS,
|
||||
SPARC_INS_FHSUBD,
|
||||
SPARC_INS_FHSUBS,
|
||||
SPARC_INS_FITOD,
|
||||
SPARC_INS_FITOQ,
|
||||
SPARC_INS_FITOS,
|
||||
SPARC_INS_FLCMPD,
|
||||
SPARC_INS_FLCMPS,
|
||||
SPARC_INS_FLUSHW,
|
||||
SPARC_INS_FMEAN16,
|
||||
SPARC_INS_FMOVD,
|
||||
SPARC_INS_FMOVQ,
|
||||
SPARC_INS_FMOVRDGEZ,
|
||||
SPARC_INS_FMOVRQGEZ,
|
||||
SPARC_INS_FMOVRSGEZ,
|
||||
SPARC_INS_FMOVRDGZ,
|
||||
SPARC_INS_FMOVRQGZ,
|
||||
SPARC_INS_FMOVRSGZ,
|
||||
SPARC_INS_FMOVRDLEZ,
|
||||
SPARC_INS_FMOVRQLEZ,
|
||||
SPARC_INS_FMOVRSLEZ,
|
||||
SPARC_INS_FMOVRDLZ,
|
||||
SPARC_INS_FMOVRQLZ,
|
||||
SPARC_INS_FMOVRSLZ,
|
||||
SPARC_INS_FMOVRDNZ,
|
||||
SPARC_INS_FMOVRQNZ,
|
||||
SPARC_INS_FMOVRSNZ,
|
||||
SPARC_INS_FMOVRDZ,
|
||||
SPARC_INS_FMOVRQZ,
|
||||
SPARC_INS_FMOVRSZ,
|
||||
SPARC_INS_FMOVS,
|
||||
SPARC_INS_FMUL8SUX16,
|
||||
SPARC_INS_FMUL8ULX16,
|
||||
SPARC_INS_FMUL8X16,
|
||||
SPARC_INS_FMUL8X16AL,
|
||||
SPARC_INS_FMUL8X16AU,
|
||||
SPARC_INS_FMULD,
|
||||
SPARC_INS_FMULD8SUX16,
|
||||
SPARC_INS_FMULD8ULX16,
|
||||
SPARC_INS_FMULQ,
|
||||
SPARC_INS_FMULS,
|
||||
SPARC_INS_FNADDD,
|
||||
SPARC_INS_FNADDS,
|
||||
SPARC_INS_FNAND,
|
||||
SPARC_INS_FNANDS,
|
||||
SPARC_INS_FNEGD,
|
||||
SPARC_INS_FNEGQ,
|
||||
SPARC_INS_FNEGS,
|
||||
SPARC_INS_FNHADDD,
|
||||
SPARC_INS_FNHADDS,
|
||||
SPARC_INS_FNOR,
|
||||
SPARC_INS_FNORS,
|
||||
SPARC_INS_FNOT1,
|
||||
SPARC_INS_FNOT1S,
|
||||
SPARC_INS_FNOT2,
|
||||
SPARC_INS_FNOT2S,
|
||||
SPARC_INS_FONE,
|
||||
SPARC_INS_FONES,
|
||||
SPARC_INS_FOR,
|
||||
SPARC_INS_FORNOT1,
|
||||
SPARC_INS_FORNOT1S,
|
||||
SPARC_INS_FORNOT2,
|
||||
SPARC_INS_FORNOT2S,
|
||||
SPARC_INS_FORS,
|
||||
SPARC_INS_FPACK16,
|
||||
SPARC_INS_FPACK32,
|
||||
SPARC_INS_FPACKFIX,
|
||||
SPARC_INS_FPADD16,
|
||||
SPARC_INS_FPADD16S,
|
||||
SPARC_INS_FPADD32,
|
||||
SPARC_INS_FPADD32S,
|
||||
SPARC_INS_FPADD64,
|
||||
SPARC_INS_FPMERGE,
|
||||
SPARC_INS_FPSUB16,
|
||||
SPARC_INS_FPSUB16S,
|
||||
SPARC_INS_FPSUB32,
|
||||
SPARC_INS_FPSUB32S,
|
||||
SPARC_INS_FQTOD,
|
||||
SPARC_INS_FQTOI,
|
||||
SPARC_INS_FQTOS,
|
||||
SPARC_INS_FQTOX,
|
||||
SPARC_INS_FSLAS16,
|
||||
SPARC_INS_FSLAS32,
|
||||
SPARC_INS_FSLL16,
|
||||
SPARC_INS_FSLL32,
|
||||
SPARC_INS_FSMULD,
|
||||
SPARC_INS_FSQRTD,
|
||||
SPARC_INS_FSQRTQ,
|
||||
SPARC_INS_FSQRTS,
|
||||
SPARC_INS_FSRA16,
|
||||
SPARC_INS_FSRA32,
|
||||
SPARC_INS_FSRC1,
|
||||
SPARC_INS_FSRC1S,
|
||||
SPARC_INS_FSRC2,
|
||||
SPARC_INS_FSRC2S,
|
||||
SPARC_INS_FSRL16,
|
||||
SPARC_INS_FSRL32,
|
||||
SPARC_INS_FSTOD,
|
||||
SPARC_INS_FSTOI,
|
||||
SPARC_INS_FSTOQ,
|
||||
SPARC_INS_FSTOX,
|
||||
SPARC_INS_FSUBD,
|
||||
SPARC_INS_FSUBQ,
|
||||
SPARC_INS_FSUBS,
|
||||
SPARC_INS_FXNOR,
|
||||
SPARC_INS_FXNORS,
|
||||
SPARC_INS_FXOR,
|
||||
SPARC_INS_FXORS,
|
||||
SPARC_INS_FXTOD,
|
||||
SPARC_INS_FXTOQ,
|
||||
SPARC_INS_FXTOS,
|
||||
SPARC_INS_FZERO,
|
||||
SPARC_INS_FZEROS,
|
||||
SPARC_INS_JMPL,
|
||||
SPARC_INS_LDD,
|
||||
SPARC_INS_LD,
|
||||
SPARC_INS_LDQ,
|
||||
SPARC_INS_LDSB,
|
||||
SPARC_INS_LDSH,
|
||||
SPARC_INS_LDSW,
|
||||
SPARC_INS_LDUB,
|
||||
SPARC_INS_LDUH,
|
||||
SPARC_INS_LDX,
|
||||
SPARC_INS_LZCNT,
|
||||
SPARC_INS_MEMBAR,
|
||||
SPARC_INS_MOVDTOX,
|
||||
SPARC_INS_MOV,
|
||||
SPARC_INS_MOVRGEZ,
|
||||
SPARC_INS_MOVRGZ,
|
||||
SPARC_INS_MOVRLEZ,
|
||||
SPARC_INS_MOVRLZ,
|
||||
SPARC_INS_MOVRNZ,
|
||||
SPARC_INS_MOVRZ,
|
||||
SPARC_INS_MOVSTOSW,
|
||||
SPARC_INS_MOVSTOUW,
|
||||
SPARC_INS_MULX,
|
||||
SPARC_INS_NOP,
|
||||
SPARC_INS_ORCC,
|
||||
SPARC_INS_ORNCC,
|
||||
SPARC_INS_ORN,
|
||||
SPARC_INS_OR,
|
||||
SPARC_INS_PDIST,
|
||||
SPARC_INS_PDISTN,
|
||||
SPARC_INS_POPC,
|
||||
SPARC_INS_RD,
|
||||
SPARC_INS_RESTORE,
|
||||
SPARC_INS_RETT,
|
||||
SPARC_INS_SAVE,
|
||||
SPARC_INS_SDIVCC,
|
||||
SPARC_INS_SDIVX,
|
||||
SPARC_INS_SDIV,
|
||||
SPARC_INS_SETHI,
|
||||
SPARC_INS_SHUTDOWN,
|
||||
SPARC_INS_SIAM,
|
||||
SPARC_INS_SLLX,
|
||||
SPARC_INS_SLL,
|
||||
SPARC_INS_SMULCC,
|
||||
SPARC_INS_SMUL,
|
||||
SPARC_INS_SRAX,
|
||||
SPARC_INS_SRA,
|
||||
SPARC_INS_SRLX,
|
||||
SPARC_INS_SRL,
|
||||
SPARC_INS_STBAR,
|
||||
SPARC_INS_STB,
|
||||
SPARC_INS_STD,
|
||||
SPARC_INS_ST,
|
||||
SPARC_INS_STH,
|
||||
SPARC_INS_STQ,
|
||||
SPARC_INS_STX,
|
||||
SPARC_INS_SUBCC,
|
||||
SPARC_INS_SUBX,
|
||||
SPARC_INS_SUBXCC,
|
||||
SPARC_INS_SUB,
|
||||
SPARC_INS_SWAP,
|
||||
SPARC_INS_TADDCCTV,
|
||||
SPARC_INS_TADDCC,
|
||||
SPARC_INS_T,
|
||||
SPARC_INS_TSUBCCTV,
|
||||
SPARC_INS_TSUBCC,
|
||||
SPARC_INS_UDIVCC,
|
||||
SPARC_INS_UDIVX,
|
||||
SPARC_INS_UDIV,
|
||||
SPARC_INS_UMULCC,
|
||||
SPARC_INS_UMULXHI,
|
||||
SPARC_INS_UMUL,
|
||||
SPARC_INS_UNIMP,
|
||||
SPARC_INS_FCMPED,
|
||||
SPARC_INS_FCMPEQ,
|
||||
SPARC_INS_FCMPES,
|
||||
SPARC_INS_WR,
|
||||
SPARC_INS_XMULX,
|
||||
SPARC_INS_XMULXHI,
|
||||
SPARC_INS_XNORCC,
|
||||
SPARC_INS_XNOR,
|
||||
SPARC_INS_XORCC,
|
||||
SPARC_INS_XOR,
|
||||
|
||||
// alias instructions
|
||||
SPARC_INS_RET,
|
||||
SPARC_INS_RETL,
|
||||
|
||||
SPARC_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} sparc_insn;
|
||||
|
||||
/// Group of SPARC instructions
|
||||
typedef enum sparc_insn_group {
|
||||
SPARC_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
SPARC_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
|
||||
// Architecture-specific groups
|
||||
SPARC_GRP_HARDQUAD = 128,
|
||||
SPARC_GRP_V9,
|
||||
SPARC_GRP_VIS,
|
||||
SPARC_GRP_VIS2,
|
||||
SPARC_GRP_VIS3,
|
||||
SPARC_GRP_32BIT,
|
||||
SPARC_GRP_64BIT,
|
||||
|
||||
SPARC_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} sparc_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
830
ai_anti_malware/capstone/include/capstone/systemz.h
Normal file
830
ai_anti_malware/capstone/include/capstone/systemz.h
Normal file
@@ -0,0 +1,830 @@
|
||||
#ifndef CAPSTONE_SYSTEMZ_H
|
||||
#define CAPSTONE_SYSTEMZ_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2014-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// Enums corresponding to SystemZ condition codes
|
||||
typedef enum sysz_cc {
|
||||
SYSZ_CC_INVALID = 0, ///< invalid CC (default)
|
||||
|
||||
SYSZ_CC_O,
|
||||
SYSZ_CC_H,
|
||||
SYSZ_CC_NLE,
|
||||
SYSZ_CC_L,
|
||||
SYSZ_CC_NHE,
|
||||
SYSZ_CC_LH,
|
||||
SYSZ_CC_NE,
|
||||
SYSZ_CC_E,
|
||||
SYSZ_CC_NLH,
|
||||
SYSZ_CC_HE,
|
||||
SYSZ_CC_NL,
|
||||
SYSZ_CC_LE,
|
||||
SYSZ_CC_NH,
|
||||
SYSZ_CC_NO,
|
||||
} sysz_cc;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum sysz_op_type {
|
||||
SYSZ_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
SYSZ_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
SYSZ_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
SYSZ_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
SYSZ_OP_ACREG = 64, ///< Access register operand.
|
||||
} sysz_op_type;
|
||||
|
||||
/// SystemZ registers
|
||||
typedef enum sysz_reg {
|
||||
SYSZ_REG_INVALID = 0,
|
||||
|
||||
SYSZ_REG_0,
|
||||
SYSZ_REG_1,
|
||||
SYSZ_REG_2,
|
||||
SYSZ_REG_3,
|
||||
SYSZ_REG_4,
|
||||
SYSZ_REG_5,
|
||||
SYSZ_REG_6,
|
||||
SYSZ_REG_7,
|
||||
SYSZ_REG_8,
|
||||
SYSZ_REG_9,
|
||||
SYSZ_REG_10,
|
||||
SYSZ_REG_11,
|
||||
SYSZ_REG_12,
|
||||
SYSZ_REG_13,
|
||||
SYSZ_REG_14,
|
||||
SYSZ_REG_15,
|
||||
SYSZ_REG_CC,
|
||||
SYSZ_REG_F0,
|
||||
SYSZ_REG_F1,
|
||||
SYSZ_REG_F2,
|
||||
SYSZ_REG_F3,
|
||||
SYSZ_REG_F4,
|
||||
SYSZ_REG_F5,
|
||||
SYSZ_REG_F6,
|
||||
SYSZ_REG_F7,
|
||||
SYSZ_REG_F8,
|
||||
SYSZ_REG_F9,
|
||||
SYSZ_REG_F10,
|
||||
SYSZ_REG_F11,
|
||||
SYSZ_REG_F12,
|
||||
SYSZ_REG_F13,
|
||||
SYSZ_REG_F14,
|
||||
SYSZ_REG_F15,
|
||||
|
||||
SYSZ_REG_R0L,
|
||||
|
||||
SYSZ_REG_ENDING,
|
||||
} sysz_reg;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with SYSZ_OP_MEM operand type above
|
||||
typedef struct sysz_op_mem {
|
||||
uint8_t base; ///< base register, can be safely interpreted as
|
||||
///< a value of type `sysz_reg`, but it is only
|
||||
///< one byte wide
|
||||
uint8_t index; ///< index register, same conditions apply here
|
||||
uint64_t length; ///< BDLAddr operand
|
||||
int64_t disp; ///< displacement/offset value
|
||||
} sysz_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_sysz_op {
|
||||
sysz_op_type type; ///< operand type
|
||||
union {
|
||||
sysz_reg reg; ///< register value for REG operand
|
||||
int64_t imm; ///< immediate value for IMM operand
|
||||
sysz_op_mem mem; ///< base/disp value for MEM operand
|
||||
};
|
||||
} cs_sysz_op;
|
||||
|
||||
// Instruction structure
|
||||
typedef struct cs_sysz {
|
||||
sysz_cc cc; ///< Code condition
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
cs_sysz_op operands[6]; ///< operands for this instruction.
|
||||
} cs_sysz;
|
||||
|
||||
/// SystemZ instruction
|
||||
typedef enum sysz_insn {
|
||||
SYSZ_INS_INVALID = 0,
|
||||
|
||||
SYSZ_INS_A,
|
||||
SYSZ_INS_ADB,
|
||||
SYSZ_INS_ADBR,
|
||||
SYSZ_INS_AEB,
|
||||
SYSZ_INS_AEBR,
|
||||
SYSZ_INS_AFI,
|
||||
SYSZ_INS_AG,
|
||||
SYSZ_INS_AGF,
|
||||
SYSZ_INS_AGFI,
|
||||
SYSZ_INS_AGFR,
|
||||
SYSZ_INS_AGHI,
|
||||
SYSZ_INS_AGHIK,
|
||||
SYSZ_INS_AGR,
|
||||
SYSZ_INS_AGRK,
|
||||
SYSZ_INS_AGSI,
|
||||
SYSZ_INS_AH,
|
||||
SYSZ_INS_AHI,
|
||||
SYSZ_INS_AHIK,
|
||||
SYSZ_INS_AHY,
|
||||
SYSZ_INS_AIH,
|
||||
SYSZ_INS_AL,
|
||||
SYSZ_INS_ALC,
|
||||
SYSZ_INS_ALCG,
|
||||
SYSZ_INS_ALCGR,
|
||||
SYSZ_INS_ALCR,
|
||||
SYSZ_INS_ALFI,
|
||||
SYSZ_INS_ALG,
|
||||
SYSZ_INS_ALGF,
|
||||
SYSZ_INS_ALGFI,
|
||||
SYSZ_INS_ALGFR,
|
||||
SYSZ_INS_ALGHSIK,
|
||||
SYSZ_INS_ALGR,
|
||||
SYSZ_INS_ALGRK,
|
||||
SYSZ_INS_ALHSIK,
|
||||
SYSZ_INS_ALR,
|
||||
SYSZ_INS_ALRK,
|
||||
SYSZ_INS_ALY,
|
||||
SYSZ_INS_AR,
|
||||
SYSZ_INS_ARK,
|
||||
SYSZ_INS_ASI,
|
||||
SYSZ_INS_AXBR,
|
||||
SYSZ_INS_AY,
|
||||
SYSZ_INS_BCR,
|
||||
SYSZ_INS_BRC,
|
||||
SYSZ_INS_BRCL,
|
||||
SYSZ_INS_CGIJ,
|
||||
SYSZ_INS_CGRJ,
|
||||
SYSZ_INS_CIJ,
|
||||
SYSZ_INS_CLGIJ,
|
||||
SYSZ_INS_CLGRJ,
|
||||
SYSZ_INS_CLIJ,
|
||||
SYSZ_INS_CLRJ,
|
||||
SYSZ_INS_CRJ,
|
||||
SYSZ_INS_BER,
|
||||
SYSZ_INS_JE,
|
||||
SYSZ_INS_JGE,
|
||||
SYSZ_INS_LOCE,
|
||||
SYSZ_INS_LOCGE,
|
||||
SYSZ_INS_LOCGRE,
|
||||
SYSZ_INS_LOCRE,
|
||||
SYSZ_INS_STOCE,
|
||||
SYSZ_INS_STOCGE,
|
||||
SYSZ_INS_BHR,
|
||||
SYSZ_INS_BHER,
|
||||
SYSZ_INS_JHE,
|
||||
SYSZ_INS_JGHE,
|
||||
SYSZ_INS_LOCHE,
|
||||
SYSZ_INS_LOCGHE,
|
||||
SYSZ_INS_LOCGRHE,
|
||||
SYSZ_INS_LOCRHE,
|
||||
SYSZ_INS_STOCHE,
|
||||
SYSZ_INS_STOCGHE,
|
||||
SYSZ_INS_JH,
|
||||
SYSZ_INS_JGH,
|
||||
SYSZ_INS_LOCH,
|
||||
SYSZ_INS_LOCGH,
|
||||
SYSZ_INS_LOCGRH,
|
||||
SYSZ_INS_LOCRH,
|
||||
SYSZ_INS_STOCH,
|
||||
SYSZ_INS_STOCGH,
|
||||
SYSZ_INS_CGIJNLH,
|
||||
SYSZ_INS_CGRJNLH,
|
||||
SYSZ_INS_CIJNLH,
|
||||
SYSZ_INS_CLGIJNLH,
|
||||
SYSZ_INS_CLGRJNLH,
|
||||
SYSZ_INS_CLIJNLH,
|
||||
SYSZ_INS_CLRJNLH,
|
||||
SYSZ_INS_CRJNLH,
|
||||
SYSZ_INS_CGIJE,
|
||||
SYSZ_INS_CGRJE,
|
||||
SYSZ_INS_CIJE,
|
||||
SYSZ_INS_CLGIJE,
|
||||
SYSZ_INS_CLGRJE,
|
||||
SYSZ_INS_CLIJE,
|
||||
SYSZ_INS_CLRJE,
|
||||
SYSZ_INS_CRJE,
|
||||
SYSZ_INS_CGIJNLE,
|
||||
SYSZ_INS_CGRJNLE,
|
||||
SYSZ_INS_CIJNLE,
|
||||
SYSZ_INS_CLGIJNLE,
|
||||
SYSZ_INS_CLGRJNLE,
|
||||
SYSZ_INS_CLIJNLE,
|
||||
SYSZ_INS_CLRJNLE,
|
||||
SYSZ_INS_CRJNLE,
|
||||
SYSZ_INS_CGIJH,
|
||||
SYSZ_INS_CGRJH,
|
||||
SYSZ_INS_CIJH,
|
||||
SYSZ_INS_CLGIJH,
|
||||
SYSZ_INS_CLGRJH,
|
||||
SYSZ_INS_CLIJH,
|
||||
SYSZ_INS_CLRJH,
|
||||
SYSZ_INS_CRJH,
|
||||
SYSZ_INS_CGIJNL,
|
||||
SYSZ_INS_CGRJNL,
|
||||
SYSZ_INS_CIJNL,
|
||||
SYSZ_INS_CLGIJNL,
|
||||
SYSZ_INS_CLGRJNL,
|
||||
SYSZ_INS_CLIJNL,
|
||||
SYSZ_INS_CLRJNL,
|
||||
SYSZ_INS_CRJNL,
|
||||
SYSZ_INS_CGIJHE,
|
||||
SYSZ_INS_CGRJHE,
|
||||
SYSZ_INS_CIJHE,
|
||||
SYSZ_INS_CLGIJHE,
|
||||
SYSZ_INS_CLGRJHE,
|
||||
SYSZ_INS_CLIJHE,
|
||||
SYSZ_INS_CLRJHE,
|
||||
SYSZ_INS_CRJHE,
|
||||
SYSZ_INS_CGIJNHE,
|
||||
SYSZ_INS_CGRJNHE,
|
||||
SYSZ_INS_CIJNHE,
|
||||
SYSZ_INS_CLGIJNHE,
|
||||
SYSZ_INS_CLGRJNHE,
|
||||
SYSZ_INS_CLIJNHE,
|
||||
SYSZ_INS_CLRJNHE,
|
||||
SYSZ_INS_CRJNHE,
|
||||
SYSZ_INS_CGIJL,
|
||||
SYSZ_INS_CGRJL,
|
||||
SYSZ_INS_CIJL,
|
||||
SYSZ_INS_CLGIJL,
|
||||
SYSZ_INS_CLGRJL,
|
||||
SYSZ_INS_CLIJL,
|
||||
SYSZ_INS_CLRJL,
|
||||
SYSZ_INS_CRJL,
|
||||
SYSZ_INS_CGIJNH,
|
||||
SYSZ_INS_CGRJNH,
|
||||
SYSZ_INS_CIJNH,
|
||||
SYSZ_INS_CLGIJNH,
|
||||
SYSZ_INS_CLGRJNH,
|
||||
SYSZ_INS_CLIJNH,
|
||||
SYSZ_INS_CLRJNH,
|
||||
SYSZ_INS_CRJNH,
|
||||
SYSZ_INS_CGIJLE,
|
||||
SYSZ_INS_CGRJLE,
|
||||
SYSZ_INS_CIJLE,
|
||||
SYSZ_INS_CLGIJLE,
|
||||
SYSZ_INS_CLGRJLE,
|
||||
SYSZ_INS_CLIJLE,
|
||||
SYSZ_INS_CLRJLE,
|
||||
SYSZ_INS_CRJLE,
|
||||
SYSZ_INS_CGIJNE,
|
||||
SYSZ_INS_CGRJNE,
|
||||
SYSZ_INS_CIJNE,
|
||||
SYSZ_INS_CLGIJNE,
|
||||
SYSZ_INS_CLGRJNE,
|
||||
SYSZ_INS_CLIJNE,
|
||||
SYSZ_INS_CLRJNE,
|
||||
SYSZ_INS_CRJNE,
|
||||
SYSZ_INS_CGIJLH,
|
||||
SYSZ_INS_CGRJLH,
|
||||
SYSZ_INS_CIJLH,
|
||||
SYSZ_INS_CLGIJLH,
|
||||
SYSZ_INS_CLGRJLH,
|
||||
SYSZ_INS_CLIJLH,
|
||||
SYSZ_INS_CLRJLH,
|
||||
SYSZ_INS_CRJLH,
|
||||
SYSZ_INS_BLR,
|
||||
SYSZ_INS_BLER,
|
||||
SYSZ_INS_JLE,
|
||||
SYSZ_INS_JGLE,
|
||||
SYSZ_INS_LOCLE,
|
||||
SYSZ_INS_LOCGLE,
|
||||
SYSZ_INS_LOCGRLE,
|
||||
SYSZ_INS_LOCRLE,
|
||||
SYSZ_INS_STOCLE,
|
||||
SYSZ_INS_STOCGLE,
|
||||
SYSZ_INS_BLHR,
|
||||
SYSZ_INS_JLH,
|
||||
SYSZ_INS_JGLH,
|
||||
SYSZ_INS_LOCLH,
|
||||
SYSZ_INS_LOCGLH,
|
||||
SYSZ_INS_LOCGRLH,
|
||||
SYSZ_INS_LOCRLH,
|
||||
SYSZ_INS_STOCLH,
|
||||
SYSZ_INS_STOCGLH,
|
||||
SYSZ_INS_JL,
|
||||
SYSZ_INS_JGL,
|
||||
SYSZ_INS_LOCL,
|
||||
SYSZ_INS_LOCGL,
|
||||
SYSZ_INS_LOCGRL,
|
||||
SYSZ_INS_LOCRL,
|
||||
SYSZ_INS_LOC,
|
||||
SYSZ_INS_LOCG,
|
||||
SYSZ_INS_LOCGR,
|
||||
SYSZ_INS_LOCR,
|
||||
SYSZ_INS_STOCL,
|
||||
SYSZ_INS_STOCGL,
|
||||
SYSZ_INS_BNER,
|
||||
SYSZ_INS_JNE,
|
||||
SYSZ_INS_JGNE,
|
||||
SYSZ_INS_LOCNE,
|
||||
SYSZ_INS_LOCGNE,
|
||||
SYSZ_INS_LOCGRNE,
|
||||
SYSZ_INS_LOCRNE,
|
||||
SYSZ_INS_STOCNE,
|
||||
SYSZ_INS_STOCGNE,
|
||||
SYSZ_INS_BNHR,
|
||||
SYSZ_INS_BNHER,
|
||||
SYSZ_INS_JNHE,
|
||||
SYSZ_INS_JGNHE,
|
||||
SYSZ_INS_LOCNHE,
|
||||
SYSZ_INS_LOCGNHE,
|
||||
SYSZ_INS_LOCGRNHE,
|
||||
SYSZ_INS_LOCRNHE,
|
||||
SYSZ_INS_STOCNHE,
|
||||
SYSZ_INS_STOCGNHE,
|
||||
SYSZ_INS_JNH,
|
||||
SYSZ_INS_JGNH,
|
||||
SYSZ_INS_LOCNH,
|
||||
SYSZ_INS_LOCGNH,
|
||||
SYSZ_INS_LOCGRNH,
|
||||
SYSZ_INS_LOCRNH,
|
||||
SYSZ_INS_STOCNH,
|
||||
SYSZ_INS_STOCGNH,
|
||||
SYSZ_INS_BNLR,
|
||||
SYSZ_INS_BNLER,
|
||||
SYSZ_INS_JNLE,
|
||||
SYSZ_INS_JGNLE,
|
||||
SYSZ_INS_LOCNLE,
|
||||
SYSZ_INS_LOCGNLE,
|
||||
SYSZ_INS_LOCGRNLE,
|
||||
SYSZ_INS_LOCRNLE,
|
||||
SYSZ_INS_STOCNLE,
|
||||
SYSZ_INS_STOCGNLE,
|
||||
SYSZ_INS_BNLHR,
|
||||
SYSZ_INS_JNLH,
|
||||
SYSZ_INS_JGNLH,
|
||||
SYSZ_INS_LOCNLH,
|
||||
SYSZ_INS_LOCGNLH,
|
||||
SYSZ_INS_LOCGRNLH,
|
||||
SYSZ_INS_LOCRNLH,
|
||||
SYSZ_INS_STOCNLH,
|
||||
SYSZ_INS_STOCGNLH,
|
||||
SYSZ_INS_JNL,
|
||||
SYSZ_INS_JGNL,
|
||||
SYSZ_INS_LOCNL,
|
||||
SYSZ_INS_LOCGNL,
|
||||
SYSZ_INS_LOCGRNL,
|
||||
SYSZ_INS_LOCRNL,
|
||||
SYSZ_INS_STOCNL,
|
||||
SYSZ_INS_STOCGNL,
|
||||
SYSZ_INS_BNOR,
|
||||
SYSZ_INS_JNO,
|
||||
SYSZ_INS_JGNO,
|
||||
SYSZ_INS_LOCNO,
|
||||
SYSZ_INS_LOCGNO,
|
||||
SYSZ_INS_LOCGRNO,
|
||||
SYSZ_INS_LOCRNO,
|
||||
SYSZ_INS_STOCNO,
|
||||
SYSZ_INS_STOCGNO,
|
||||
SYSZ_INS_BOR,
|
||||
SYSZ_INS_JO,
|
||||
SYSZ_INS_JGO,
|
||||
SYSZ_INS_LOCO,
|
||||
SYSZ_INS_LOCGO,
|
||||
SYSZ_INS_LOCGRO,
|
||||
SYSZ_INS_LOCRO,
|
||||
SYSZ_INS_STOCO,
|
||||
SYSZ_INS_STOCGO,
|
||||
SYSZ_INS_STOC,
|
||||
SYSZ_INS_STOCG,
|
||||
SYSZ_INS_BASR,
|
||||
SYSZ_INS_BR,
|
||||
SYSZ_INS_BRAS,
|
||||
SYSZ_INS_BRASL,
|
||||
SYSZ_INS_J,
|
||||
SYSZ_INS_JG,
|
||||
SYSZ_INS_BRCT,
|
||||
SYSZ_INS_BRCTG,
|
||||
SYSZ_INS_C,
|
||||
SYSZ_INS_CDB,
|
||||
SYSZ_INS_CDBR,
|
||||
SYSZ_INS_CDFBR,
|
||||
SYSZ_INS_CDGBR,
|
||||
SYSZ_INS_CDLFBR,
|
||||
SYSZ_INS_CDLGBR,
|
||||
SYSZ_INS_CEB,
|
||||
SYSZ_INS_CEBR,
|
||||
SYSZ_INS_CEFBR,
|
||||
SYSZ_INS_CEGBR,
|
||||
SYSZ_INS_CELFBR,
|
||||
SYSZ_INS_CELGBR,
|
||||
SYSZ_INS_CFDBR,
|
||||
SYSZ_INS_CFEBR,
|
||||
SYSZ_INS_CFI,
|
||||
SYSZ_INS_CFXBR,
|
||||
SYSZ_INS_CG,
|
||||
SYSZ_INS_CGDBR,
|
||||
SYSZ_INS_CGEBR,
|
||||
SYSZ_INS_CGF,
|
||||
SYSZ_INS_CGFI,
|
||||
SYSZ_INS_CGFR,
|
||||
SYSZ_INS_CGFRL,
|
||||
SYSZ_INS_CGH,
|
||||
SYSZ_INS_CGHI,
|
||||
SYSZ_INS_CGHRL,
|
||||
SYSZ_INS_CGHSI,
|
||||
SYSZ_INS_CGR,
|
||||
SYSZ_INS_CGRL,
|
||||
SYSZ_INS_CGXBR,
|
||||
SYSZ_INS_CH,
|
||||
SYSZ_INS_CHF,
|
||||
SYSZ_INS_CHHSI,
|
||||
SYSZ_INS_CHI,
|
||||
SYSZ_INS_CHRL,
|
||||
SYSZ_INS_CHSI,
|
||||
SYSZ_INS_CHY,
|
||||
SYSZ_INS_CIH,
|
||||
SYSZ_INS_CL,
|
||||
SYSZ_INS_CLC,
|
||||
SYSZ_INS_CLFDBR,
|
||||
SYSZ_INS_CLFEBR,
|
||||
SYSZ_INS_CLFHSI,
|
||||
SYSZ_INS_CLFI,
|
||||
SYSZ_INS_CLFXBR,
|
||||
SYSZ_INS_CLG,
|
||||
SYSZ_INS_CLGDBR,
|
||||
SYSZ_INS_CLGEBR,
|
||||
SYSZ_INS_CLGF,
|
||||
SYSZ_INS_CLGFI,
|
||||
SYSZ_INS_CLGFR,
|
||||
SYSZ_INS_CLGFRL,
|
||||
SYSZ_INS_CLGHRL,
|
||||
SYSZ_INS_CLGHSI,
|
||||
SYSZ_INS_CLGR,
|
||||
SYSZ_INS_CLGRL,
|
||||
SYSZ_INS_CLGXBR,
|
||||
SYSZ_INS_CLHF,
|
||||
SYSZ_INS_CLHHSI,
|
||||
SYSZ_INS_CLHRL,
|
||||
SYSZ_INS_CLI,
|
||||
SYSZ_INS_CLIH,
|
||||
SYSZ_INS_CLIY,
|
||||
SYSZ_INS_CLR,
|
||||
SYSZ_INS_CLRL,
|
||||
SYSZ_INS_CLST,
|
||||
SYSZ_INS_CLY,
|
||||
SYSZ_INS_CPSDR,
|
||||
SYSZ_INS_CR,
|
||||
SYSZ_INS_CRL,
|
||||
SYSZ_INS_CS,
|
||||
SYSZ_INS_CSG,
|
||||
SYSZ_INS_CSY,
|
||||
SYSZ_INS_CXBR,
|
||||
SYSZ_INS_CXFBR,
|
||||
SYSZ_INS_CXGBR,
|
||||
SYSZ_INS_CXLFBR,
|
||||
SYSZ_INS_CXLGBR,
|
||||
SYSZ_INS_CY,
|
||||
SYSZ_INS_DDB,
|
||||
SYSZ_INS_DDBR,
|
||||
SYSZ_INS_DEB,
|
||||
SYSZ_INS_DEBR,
|
||||
SYSZ_INS_DL,
|
||||
SYSZ_INS_DLG,
|
||||
SYSZ_INS_DLGR,
|
||||
SYSZ_INS_DLR,
|
||||
SYSZ_INS_DSG,
|
||||
SYSZ_INS_DSGF,
|
||||
SYSZ_INS_DSGFR,
|
||||
SYSZ_INS_DSGR,
|
||||
SYSZ_INS_DXBR,
|
||||
SYSZ_INS_EAR,
|
||||
SYSZ_INS_FIDBR,
|
||||
SYSZ_INS_FIDBRA,
|
||||
SYSZ_INS_FIEBR,
|
||||
SYSZ_INS_FIEBRA,
|
||||
SYSZ_INS_FIXBR,
|
||||
SYSZ_INS_FIXBRA,
|
||||
SYSZ_INS_FLOGR,
|
||||
SYSZ_INS_IC,
|
||||
SYSZ_INS_ICY,
|
||||
SYSZ_INS_IIHF,
|
||||
SYSZ_INS_IIHH,
|
||||
SYSZ_INS_IIHL,
|
||||
SYSZ_INS_IILF,
|
||||
SYSZ_INS_IILH,
|
||||
SYSZ_INS_IILL,
|
||||
SYSZ_INS_IPM,
|
||||
SYSZ_INS_L,
|
||||
SYSZ_INS_LA,
|
||||
SYSZ_INS_LAA,
|
||||
SYSZ_INS_LAAG,
|
||||
SYSZ_INS_LAAL,
|
||||
SYSZ_INS_LAALG,
|
||||
SYSZ_INS_LAN,
|
||||
SYSZ_INS_LANG,
|
||||
SYSZ_INS_LAO,
|
||||
SYSZ_INS_LAOG,
|
||||
SYSZ_INS_LARL,
|
||||
SYSZ_INS_LAX,
|
||||
SYSZ_INS_LAXG,
|
||||
SYSZ_INS_LAY,
|
||||
SYSZ_INS_LB,
|
||||
SYSZ_INS_LBH,
|
||||
SYSZ_INS_LBR,
|
||||
SYSZ_INS_LCDBR,
|
||||
SYSZ_INS_LCEBR,
|
||||
SYSZ_INS_LCGFR,
|
||||
SYSZ_INS_LCGR,
|
||||
SYSZ_INS_LCR,
|
||||
SYSZ_INS_LCXBR,
|
||||
SYSZ_INS_LD,
|
||||
SYSZ_INS_LDEB,
|
||||
SYSZ_INS_LDEBR,
|
||||
SYSZ_INS_LDGR,
|
||||
SYSZ_INS_LDR,
|
||||
SYSZ_INS_LDXBR,
|
||||
SYSZ_INS_LDXBRA,
|
||||
SYSZ_INS_LDY,
|
||||
SYSZ_INS_LE,
|
||||
SYSZ_INS_LEDBR,
|
||||
SYSZ_INS_LEDBRA,
|
||||
SYSZ_INS_LER,
|
||||
SYSZ_INS_LEXBR,
|
||||
SYSZ_INS_LEXBRA,
|
||||
SYSZ_INS_LEY,
|
||||
SYSZ_INS_LFH,
|
||||
SYSZ_INS_LG,
|
||||
SYSZ_INS_LGB,
|
||||
SYSZ_INS_LGBR,
|
||||
SYSZ_INS_LGDR,
|
||||
SYSZ_INS_LGF,
|
||||
SYSZ_INS_LGFI,
|
||||
SYSZ_INS_LGFR,
|
||||
SYSZ_INS_LGFRL,
|
||||
SYSZ_INS_LGH,
|
||||
SYSZ_INS_LGHI,
|
||||
SYSZ_INS_LGHR,
|
||||
SYSZ_INS_LGHRL,
|
||||
SYSZ_INS_LGR,
|
||||
SYSZ_INS_LGRL,
|
||||
SYSZ_INS_LH,
|
||||
SYSZ_INS_LHH,
|
||||
SYSZ_INS_LHI,
|
||||
SYSZ_INS_LHR,
|
||||
SYSZ_INS_LHRL,
|
||||
SYSZ_INS_LHY,
|
||||
SYSZ_INS_LLC,
|
||||
SYSZ_INS_LLCH,
|
||||
SYSZ_INS_LLCR,
|
||||
SYSZ_INS_LLGC,
|
||||
SYSZ_INS_LLGCR,
|
||||
SYSZ_INS_LLGF,
|
||||
SYSZ_INS_LLGFR,
|
||||
SYSZ_INS_LLGFRL,
|
||||
SYSZ_INS_LLGH,
|
||||
SYSZ_INS_LLGHR,
|
||||
SYSZ_INS_LLGHRL,
|
||||
SYSZ_INS_LLH,
|
||||
SYSZ_INS_LLHH,
|
||||
SYSZ_INS_LLHR,
|
||||
SYSZ_INS_LLHRL,
|
||||
SYSZ_INS_LLIHF,
|
||||
SYSZ_INS_LLIHH,
|
||||
SYSZ_INS_LLIHL,
|
||||
SYSZ_INS_LLILF,
|
||||
SYSZ_INS_LLILH,
|
||||
SYSZ_INS_LLILL,
|
||||
SYSZ_INS_LMG,
|
||||
SYSZ_INS_LNDBR,
|
||||
SYSZ_INS_LNEBR,
|
||||
SYSZ_INS_LNGFR,
|
||||
SYSZ_INS_LNGR,
|
||||
SYSZ_INS_LNR,
|
||||
SYSZ_INS_LNXBR,
|
||||
SYSZ_INS_LPDBR,
|
||||
SYSZ_INS_LPEBR,
|
||||
SYSZ_INS_LPGFR,
|
||||
SYSZ_INS_LPGR,
|
||||
SYSZ_INS_LPR,
|
||||
SYSZ_INS_LPXBR,
|
||||
SYSZ_INS_LR,
|
||||
SYSZ_INS_LRL,
|
||||
SYSZ_INS_LRV,
|
||||
SYSZ_INS_LRVG,
|
||||
SYSZ_INS_LRVGR,
|
||||
SYSZ_INS_LRVR,
|
||||
SYSZ_INS_LT,
|
||||
SYSZ_INS_LTDBR,
|
||||
SYSZ_INS_LTEBR,
|
||||
SYSZ_INS_LTG,
|
||||
SYSZ_INS_LTGF,
|
||||
SYSZ_INS_LTGFR,
|
||||
SYSZ_INS_LTGR,
|
||||
SYSZ_INS_LTR,
|
||||
SYSZ_INS_LTXBR,
|
||||
SYSZ_INS_LXDB,
|
||||
SYSZ_INS_LXDBR,
|
||||
SYSZ_INS_LXEB,
|
||||
SYSZ_INS_LXEBR,
|
||||
SYSZ_INS_LXR,
|
||||
SYSZ_INS_LY,
|
||||
SYSZ_INS_LZDR,
|
||||
SYSZ_INS_LZER,
|
||||
SYSZ_INS_LZXR,
|
||||
SYSZ_INS_MADB,
|
||||
SYSZ_INS_MADBR,
|
||||
SYSZ_INS_MAEB,
|
||||
SYSZ_INS_MAEBR,
|
||||
SYSZ_INS_MDB,
|
||||
SYSZ_INS_MDBR,
|
||||
SYSZ_INS_MDEB,
|
||||
SYSZ_INS_MDEBR,
|
||||
SYSZ_INS_MEEB,
|
||||
SYSZ_INS_MEEBR,
|
||||
SYSZ_INS_MGHI,
|
||||
SYSZ_INS_MH,
|
||||
SYSZ_INS_MHI,
|
||||
SYSZ_INS_MHY,
|
||||
SYSZ_INS_MLG,
|
||||
SYSZ_INS_MLGR,
|
||||
SYSZ_INS_MS,
|
||||
SYSZ_INS_MSDB,
|
||||
SYSZ_INS_MSDBR,
|
||||
SYSZ_INS_MSEB,
|
||||
SYSZ_INS_MSEBR,
|
||||
SYSZ_INS_MSFI,
|
||||
SYSZ_INS_MSG,
|
||||
SYSZ_INS_MSGF,
|
||||
SYSZ_INS_MSGFI,
|
||||
SYSZ_INS_MSGFR,
|
||||
SYSZ_INS_MSGR,
|
||||
SYSZ_INS_MSR,
|
||||
SYSZ_INS_MSY,
|
||||
SYSZ_INS_MVC,
|
||||
SYSZ_INS_MVGHI,
|
||||
SYSZ_INS_MVHHI,
|
||||
SYSZ_INS_MVHI,
|
||||
SYSZ_INS_MVI,
|
||||
SYSZ_INS_MVIY,
|
||||
SYSZ_INS_MVST,
|
||||
SYSZ_INS_MXBR,
|
||||
SYSZ_INS_MXDB,
|
||||
SYSZ_INS_MXDBR,
|
||||
SYSZ_INS_N,
|
||||
SYSZ_INS_NC,
|
||||
SYSZ_INS_NG,
|
||||
SYSZ_INS_NGR,
|
||||
SYSZ_INS_NGRK,
|
||||
SYSZ_INS_NI,
|
||||
SYSZ_INS_NIHF,
|
||||
SYSZ_INS_NIHH,
|
||||
SYSZ_INS_NIHL,
|
||||
SYSZ_INS_NILF,
|
||||
SYSZ_INS_NILH,
|
||||
SYSZ_INS_NILL,
|
||||
SYSZ_INS_NIY,
|
||||
SYSZ_INS_NR,
|
||||
SYSZ_INS_NRK,
|
||||
SYSZ_INS_NY,
|
||||
SYSZ_INS_O,
|
||||
SYSZ_INS_OC,
|
||||
SYSZ_INS_OG,
|
||||
SYSZ_INS_OGR,
|
||||
SYSZ_INS_OGRK,
|
||||
SYSZ_INS_OI,
|
||||
SYSZ_INS_OIHF,
|
||||
SYSZ_INS_OIHH,
|
||||
SYSZ_INS_OIHL,
|
||||
SYSZ_INS_OILF,
|
||||
SYSZ_INS_OILH,
|
||||
SYSZ_INS_OILL,
|
||||
SYSZ_INS_OIY,
|
||||
SYSZ_INS_OR,
|
||||
SYSZ_INS_ORK,
|
||||
SYSZ_INS_OY,
|
||||
SYSZ_INS_PFD,
|
||||
SYSZ_INS_PFDRL,
|
||||
SYSZ_INS_RISBG,
|
||||
SYSZ_INS_RISBHG,
|
||||
SYSZ_INS_RISBLG,
|
||||
SYSZ_INS_RLL,
|
||||
SYSZ_INS_RLLG,
|
||||
SYSZ_INS_RNSBG,
|
||||
SYSZ_INS_ROSBG,
|
||||
SYSZ_INS_RXSBG,
|
||||
SYSZ_INS_S,
|
||||
SYSZ_INS_SDB,
|
||||
SYSZ_INS_SDBR,
|
||||
SYSZ_INS_SEB,
|
||||
SYSZ_INS_SEBR,
|
||||
SYSZ_INS_SG,
|
||||
SYSZ_INS_SGF,
|
||||
SYSZ_INS_SGFR,
|
||||
SYSZ_INS_SGR,
|
||||
SYSZ_INS_SGRK,
|
||||
SYSZ_INS_SH,
|
||||
SYSZ_INS_SHY,
|
||||
SYSZ_INS_SL,
|
||||
SYSZ_INS_SLB,
|
||||
SYSZ_INS_SLBG,
|
||||
SYSZ_INS_SLBR,
|
||||
SYSZ_INS_SLFI,
|
||||
SYSZ_INS_SLG,
|
||||
SYSZ_INS_SLBGR,
|
||||
SYSZ_INS_SLGF,
|
||||
SYSZ_INS_SLGFI,
|
||||
SYSZ_INS_SLGFR,
|
||||
SYSZ_INS_SLGR,
|
||||
SYSZ_INS_SLGRK,
|
||||
SYSZ_INS_SLL,
|
||||
SYSZ_INS_SLLG,
|
||||
SYSZ_INS_SLLK,
|
||||
SYSZ_INS_SLR,
|
||||
SYSZ_INS_SLRK,
|
||||
SYSZ_INS_SLY,
|
||||
SYSZ_INS_SQDB,
|
||||
SYSZ_INS_SQDBR,
|
||||
SYSZ_INS_SQEB,
|
||||
SYSZ_INS_SQEBR,
|
||||
SYSZ_INS_SQXBR,
|
||||
SYSZ_INS_SR,
|
||||
SYSZ_INS_SRA,
|
||||
SYSZ_INS_SRAG,
|
||||
SYSZ_INS_SRAK,
|
||||
SYSZ_INS_SRK,
|
||||
SYSZ_INS_SRL,
|
||||
SYSZ_INS_SRLG,
|
||||
SYSZ_INS_SRLK,
|
||||
SYSZ_INS_SRST,
|
||||
SYSZ_INS_ST,
|
||||
SYSZ_INS_STC,
|
||||
SYSZ_INS_STCH,
|
||||
SYSZ_INS_STCY,
|
||||
SYSZ_INS_STD,
|
||||
SYSZ_INS_STDY,
|
||||
SYSZ_INS_STE,
|
||||
SYSZ_INS_STEY,
|
||||
SYSZ_INS_STFH,
|
||||
SYSZ_INS_STG,
|
||||
SYSZ_INS_STGRL,
|
||||
SYSZ_INS_STH,
|
||||
SYSZ_INS_STHH,
|
||||
SYSZ_INS_STHRL,
|
||||
SYSZ_INS_STHY,
|
||||
SYSZ_INS_STMG,
|
||||
SYSZ_INS_STRL,
|
||||
SYSZ_INS_STRV,
|
||||
SYSZ_INS_STRVG,
|
||||
SYSZ_INS_STY,
|
||||
SYSZ_INS_SXBR,
|
||||
SYSZ_INS_SY,
|
||||
SYSZ_INS_TM,
|
||||
SYSZ_INS_TMHH,
|
||||
SYSZ_INS_TMHL,
|
||||
SYSZ_INS_TMLH,
|
||||
SYSZ_INS_TMLL,
|
||||
SYSZ_INS_TMY,
|
||||
SYSZ_INS_X,
|
||||
SYSZ_INS_XC,
|
||||
SYSZ_INS_XG,
|
||||
SYSZ_INS_XGR,
|
||||
SYSZ_INS_XGRK,
|
||||
SYSZ_INS_XI,
|
||||
SYSZ_INS_XIHF,
|
||||
SYSZ_INS_XILF,
|
||||
SYSZ_INS_XIY,
|
||||
SYSZ_INS_XR,
|
||||
SYSZ_INS_XRK,
|
||||
SYSZ_INS_XY,
|
||||
|
||||
SYSZ_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} sysz_insn;
|
||||
|
||||
/// Group of SystemZ instructions
|
||||
typedef enum sysz_insn_group {
|
||||
SYSZ_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
SYSZ_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
|
||||
// Architecture-specific groups
|
||||
SYSZ_GRP_DISTINCTOPS = 128,
|
||||
SYSZ_GRP_FPEXTENSION,
|
||||
SYSZ_GRP_HIGHWORD,
|
||||
SYSZ_GRP_INTERLOCKEDACCESS1,
|
||||
SYSZ_GRP_LOADSTOREONCOND,
|
||||
|
||||
SYSZ_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} sysz_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
359
ai_anti_malware/capstone/include/capstone/tms320c64x.h
Normal file
359
ai_anti_malware/capstone/include/capstone/tms320c64x.h
Normal file
@@ -0,0 +1,359 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* TMS320C64x Backend by Fotis Loukos <me@fotisl.com> 2016 */
|
||||
|
||||
#ifndef CAPSTONE_TMS320C64X_H
|
||||
#define CAPSTONE_TMS320C64X_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
typedef enum tms320c64x_op_type {
|
||||
TMS320C64X_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
TMS320C64X_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
TMS320C64X_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
TMS320C64X_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
TMS320C64X_OP_REGPAIR = 64, ///< Register pair for double word ops
|
||||
} tms320c64x_op_type;
|
||||
|
||||
typedef enum tms320c64x_mem_disp {
|
||||
TMS320C64X_MEM_DISP_INVALID = 0,
|
||||
TMS320C64X_MEM_DISP_CONSTANT,
|
||||
TMS320C64X_MEM_DISP_REGISTER,
|
||||
} tms320c64x_mem_disp;
|
||||
|
||||
typedef enum tms320c64x_mem_dir {
|
||||
TMS320C64X_MEM_DIR_INVALID = 0,
|
||||
TMS320C64X_MEM_DIR_FW,
|
||||
TMS320C64X_MEM_DIR_BW,
|
||||
} tms320c64x_mem_dir;
|
||||
|
||||
typedef enum tms320c64x_mem_mod {
|
||||
TMS320C64X_MEM_MOD_INVALID = 0,
|
||||
TMS320C64X_MEM_MOD_NO,
|
||||
TMS320C64X_MEM_MOD_PRE,
|
||||
TMS320C64X_MEM_MOD_POST,
|
||||
} tms320c64x_mem_mod;
|
||||
|
||||
typedef struct tms320c64x_op_mem {
|
||||
unsigned int base; ///< base register
|
||||
unsigned int disp; ///< displacement/offset value
|
||||
unsigned int unit; ///< unit of base and offset register
|
||||
unsigned int scaled; ///< offset scaled
|
||||
unsigned int disptype; ///< displacement type
|
||||
unsigned int direction; ///< direction
|
||||
unsigned int modify; ///< modification
|
||||
} tms320c64x_op_mem;
|
||||
|
||||
typedef struct cs_tms320c64x_op {
|
||||
tms320c64x_op_type type; ///< operand type
|
||||
union {
|
||||
unsigned int reg; ///< register value for REG operand or first register for REGPAIR operand
|
||||
int32_t imm; ///< immediate value for IMM operand
|
||||
tms320c64x_op_mem mem; ///< base/disp value for MEM operand
|
||||
};
|
||||
} cs_tms320c64x_op;
|
||||
|
||||
typedef struct cs_tms320c64x {
|
||||
uint8_t op_count;
|
||||
cs_tms320c64x_op operands[8]; ///< operands for this instruction.
|
||||
struct {
|
||||
unsigned int reg;
|
||||
unsigned int zero;
|
||||
} condition;
|
||||
struct {
|
||||
unsigned int unit;
|
||||
unsigned int side;
|
||||
unsigned int crosspath;
|
||||
} funit;
|
||||
unsigned int parallel;
|
||||
} cs_tms320c64x;
|
||||
|
||||
typedef enum tms320c64x_reg {
|
||||
TMS320C64X_REG_INVALID = 0,
|
||||
|
||||
TMS320C64X_REG_AMR,
|
||||
TMS320C64X_REG_CSR,
|
||||
TMS320C64X_REG_DIER,
|
||||
TMS320C64X_REG_DNUM,
|
||||
TMS320C64X_REG_ECR,
|
||||
TMS320C64X_REG_GFPGFR,
|
||||
TMS320C64X_REG_GPLYA,
|
||||
TMS320C64X_REG_GPLYB,
|
||||
TMS320C64X_REG_ICR,
|
||||
TMS320C64X_REG_IER,
|
||||
TMS320C64X_REG_IERR,
|
||||
TMS320C64X_REG_ILC,
|
||||
TMS320C64X_REG_IRP,
|
||||
TMS320C64X_REG_ISR,
|
||||
TMS320C64X_REG_ISTP,
|
||||
TMS320C64X_REG_ITSR,
|
||||
TMS320C64X_REG_NRP,
|
||||
TMS320C64X_REG_NTSR,
|
||||
TMS320C64X_REG_REP,
|
||||
TMS320C64X_REG_RILC,
|
||||
TMS320C64X_REG_SSR,
|
||||
TMS320C64X_REG_TSCH,
|
||||
TMS320C64X_REG_TSCL,
|
||||
TMS320C64X_REG_TSR,
|
||||
TMS320C64X_REG_A0,
|
||||
TMS320C64X_REG_A1,
|
||||
TMS320C64X_REG_A2,
|
||||
TMS320C64X_REG_A3,
|
||||
TMS320C64X_REG_A4,
|
||||
TMS320C64X_REG_A5,
|
||||
TMS320C64X_REG_A6,
|
||||
TMS320C64X_REG_A7,
|
||||
TMS320C64X_REG_A8,
|
||||
TMS320C64X_REG_A9,
|
||||
TMS320C64X_REG_A10,
|
||||
TMS320C64X_REG_A11,
|
||||
TMS320C64X_REG_A12,
|
||||
TMS320C64X_REG_A13,
|
||||
TMS320C64X_REG_A14,
|
||||
TMS320C64X_REG_A15,
|
||||
TMS320C64X_REG_A16,
|
||||
TMS320C64X_REG_A17,
|
||||
TMS320C64X_REG_A18,
|
||||
TMS320C64X_REG_A19,
|
||||
TMS320C64X_REG_A20,
|
||||
TMS320C64X_REG_A21,
|
||||
TMS320C64X_REG_A22,
|
||||
TMS320C64X_REG_A23,
|
||||
TMS320C64X_REG_A24,
|
||||
TMS320C64X_REG_A25,
|
||||
TMS320C64X_REG_A26,
|
||||
TMS320C64X_REG_A27,
|
||||
TMS320C64X_REG_A28,
|
||||
TMS320C64X_REG_A29,
|
||||
TMS320C64X_REG_A30,
|
||||
TMS320C64X_REG_A31,
|
||||
TMS320C64X_REG_B0,
|
||||
TMS320C64X_REG_B1,
|
||||
TMS320C64X_REG_B2,
|
||||
TMS320C64X_REG_B3,
|
||||
TMS320C64X_REG_B4,
|
||||
TMS320C64X_REG_B5,
|
||||
TMS320C64X_REG_B6,
|
||||
TMS320C64X_REG_B7,
|
||||
TMS320C64X_REG_B8,
|
||||
TMS320C64X_REG_B9,
|
||||
TMS320C64X_REG_B10,
|
||||
TMS320C64X_REG_B11,
|
||||
TMS320C64X_REG_B12,
|
||||
TMS320C64X_REG_B13,
|
||||
TMS320C64X_REG_B14,
|
||||
TMS320C64X_REG_B15,
|
||||
TMS320C64X_REG_B16,
|
||||
TMS320C64X_REG_B17,
|
||||
TMS320C64X_REG_B18,
|
||||
TMS320C64X_REG_B19,
|
||||
TMS320C64X_REG_B20,
|
||||
TMS320C64X_REG_B21,
|
||||
TMS320C64X_REG_B22,
|
||||
TMS320C64X_REG_B23,
|
||||
TMS320C64X_REG_B24,
|
||||
TMS320C64X_REG_B25,
|
||||
TMS320C64X_REG_B26,
|
||||
TMS320C64X_REG_B27,
|
||||
TMS320C64X_REG_B28,
|
||||
TMS320C64X_REG_B29,
|
||||
TMS320C64X_REG_B30,
|
||||
TMS320C64X_REG_B31,
|
||||
TMS320C64X_REG_PCE1,
|
||||
|
||||
TMS320C64X_REG_ENDING, // <-- mark the end of the list of registers
|
||||
|
||||
// Alias registers
|
||||
TMS320C64X_REG_EFR = TMS320C64X_REG_ECR,
|
||||
TMS320C64X_REG_IFR = TMS320C64X_REG_ISR,
|
||||
} tms320c64x_reg;
|
||||
|
||||
typedef enum tms320c64x_insn {
|
||||
TMS320C64X_INS_INVALID = 0,
|
||||
|
||||
TMS320C64X_INS_ABS,
|
||||
TMS320C64X_INS_ABS2,
|
||||
TMS320C64X_INS_ADD,
|
||||
TMS320C64X_INS_ADD2,
|
||||
TMS320C64X_INS_ADD4,
|
||||
TMS320C64X_INS_ADDAB,
|
||||
TMS320C64X_INS_ADDAD,
|
||||
TMS320C64X_INS_ADDAH,
|
||||
TMS320C64X_INS_ADDAW,
|
||||
TMS320C64X_INS_ADDK,
|
||||
TMS320C64X_INS_ADDKPC,
|
||||
TMS320C64X_INS_ADDU,
|
||||
TMS320C64X_INS_AND,
|
||||
TMS320C64X_INS_ANDN,
|
||||
TMS320C64X_INS_AVG2,
|
||||
TMS320C64X_INS_AVGU4,
|
||||
TMS320C64X_INS_B,
|
||||
TMS320C64X_INS_BDEC,
|
||||
TMS320C64X_INS_BITC4,
|
||||
TMS320C64X_INS_BNOP,
|
||||
TMS320C64X_INS_BPOS,
|
||||
TMS320C64X_INS_CLR,
|
||||
TMS320C64X_INS_CMPEQ,
|
||||
TMS320C64X_INS_CMPEQ2,
|
||||
TMS320C64X_INS_CMPEQ4,
|
||||
TMS320C64X_INS_CMPGT,
|
||||
TMS320C64X_INS_CMPGT2,
|
||||
TMS320C64X_INS_CMPGTU4,
|
||||
TMS320C64X_INS_CMPLT,
|
||||
TMS320C64X_INS_CMPLTU,
|
||||
TMS320C64X_INS_DEAL,
|
||||
TMS320C64X_INS_DOTP2,
|
||||
TMS320C64X_INS_DOTPN2,
|
||||
TMS320C64X_INS_DOTPNRSU2,
|
||||
TMS320C64X_INS_DOTPRSU2,
|
||||
TMS320C64X_INS_DOTPSU4,
|
||||
TMS320C64X_INS_DOTPU4,
|
||||
TMS320C64X_INS_EXT,
|
||||
TMS320C64X_INS_EXTU,
|
||||
TMS320C64X_INS_GMPGTU,
|
||||
TMS320C64X_INS_GMPY4,
|
||||
TMS320C64X_INS_LDB,
|
||||
TMS320C64X_INS_LDBU,
|
||||
TMS320C64X_INS_LDDW,
|
||||
TMS320C64X_INS_LDH,
|
||||
TMS320C64X_INS_LDHU,
|
||||
TMS320C64X_INS_LDNDW,
|
||||
TMS320C64X_INS_LDNW,
|
||||
TMS320C64X_INS_LDW,
|
||||
TMS320C64X_INS_LMBD,
|
||||
TMS320C64X_INS_MAX2,
|
||||
TMS320C64X_INS_MAXU4,
|
||||
TMS320C64X_INS_MIN2,
|
||||
TMS320C64X_INS_MINU4,
|
||||
TMS320C64X_INS_MPY,
|
||||
TMS320C64X_INS_MPY2,
|
||||
TMS320C64X_INS_MPYH,
|
||||
TMS320C64X_INS_MPYHI,
|
||||
TMS320C64X_INS_MPYHIR,
|
||||
TMS320C64X_INS_MPYHL,
|
||||
TMS320C64X_INS_MPYHLU,
|
||||
TMS320C64X_INS_MPYHSLU,
|
||||
TMS320C64X_INS_MPYHSU,
|
||||
TMS320C64X_INS_MPYHU,
|
||||
TMS320C64X_INS_MPYHULS,
|
||||
TMS320C64X_INS_MPYHUS,
|
||||
TMS320C64X_INS_MPYLH,
|
||||
TMS320C64X_INS_MPYLHU,
|
||||
TMS320C64X_INS_MPYLI,
|
||||
TMS320C64X_INS_MPYLIR,
|
||||
TMS320C64X_INS_MPYLSHU,
|
||||
TMS320C64X_INS_MPYLUHS,
|
||||
TMS320C64X_INS_MPYSU,
|
||||
TMS320C64X_INS_MPYSU4,
|
||||
TMS320C64X_INS_MPYU,
|
||||
TMS320C64X_INS_MPYU4,
|
||||
TMS320C64X_INS_MPYUS,
|
||||
TMS320C64X_INS_MVC,
|
||||
TMS320C64X_INS_MVD,
|
||||
TMS320C64X_INS_MVK,
|
||||
TMS320C64X_INS_MVKL,
|
||||
TMS320C64X_INS_MVKLH,
|
||||
TMS320C64X_INS_NOP,
|
||||
TMS320C64X_INS_NORM,
|
||||
TMS320C64X_INS_OR,
|
||||
TMS320C64X_INS_PACK2,
|
||||
TMS320C64X_INS_PACKH2,
|
||||
TMS320C64X_INS_PACKH4,
|
||||
TMS320C64X_INS_PACKHL2,
|
||||
TMS320C64X_INS_PACKL4,
|
||||
TMS320C64X_INS_PACKLH2,
|
||||
TMS320C64X_INS_ROTL,
|
||||
TMS320C64X_INS_SADD,
|
||||
TMS320C64X_INS_SADD2,
|
||||
TMS320C64X_INS_SADDU4,
|
||||
TMS320C64X_INS_SADDUS2,
|
||||
TMS320C64X_INS_SAT,
|
||||
TMS320C64X_INS_SET,
|
||||
TMS320C64X_INS_SHFL,
|
||||
TMS320C64X_INS_SHL,
|
||||
TMS320C64X_INS_SHLMB,
|
||||
TMS320C64X_INS_SHR,
|
||||
TMS320C64X_INS_SHR2,
|
||||
TMS320C64X_INS_SHRMB,
|
||||
TMS320C64X_INS_SHRU,
|
||||
TMS320C64X_INS_SHRU2,
|
||||
TMS320C64X_INS_SMPY,
|
||||
TMS320C64X_INS_SMPY2,
|
||||
TMS320C64X_INS_SMPYH,
|
||||
TMS320C64X_INS_SMPYHL,
|
||||
TMS320C64X_INS_SMPYLH,
|
||||
TMS320C64X_INS_SPACK2,
|
||||
TMS320C64X_INS_SPACKU4,
|
||||
TMS320C64X_INS_SSHL,
|
||||
TMS320C64X_INS_SSHVL,
|
||||
TMS320C64X_INS_SSHVR,
|
||||
TMS320C64X_INS_SSUB,
|
||||
TMS320C64X_INS_STB,
|
||||
TMS320C64X_INS_STDW,
|
||||
TMS320C64X_INS_STH,
|
||||
TMS320C64X_INS_STNDW,
|
||||
TMS320C64X_INS_STNW,
|
||||
TMS320C64X_INS_STW,
|
||||
TMS320C64X_INS_SUB,
|
||||
TMS320C64X_INS_SUB2,
|
||||
TMS320C64X_INS_SUB4,
|
||||
TMS320C64X_INS_SUBAB,
|
||||
TMS320C64X_INS_SUBABS4,
|
||||
TMS320C64X_INS_SUBAH,
|
||||
TMS320C64X_INS_SUBAW,
|
||||
TMS320C64X_INS_SUBC,
|
||||
TMS320C64X_INS_SUBU,
|
||||
TMS320C64X_INS_SWAP4,
|
||||
TMS320C64X_INS_UNPKHU4,
|
||||
TMS320C64X_INS_UNPKLU4,
|
||||
TMS320C64X_INS_XOR,
|
||||
TMS320C64X_INS_XPND2,
|
||||
TMS320C64X_INS_XPND4,
|
||||
// Aliases
|
||||
TMS320C64X_INS_IDLE,
|
||||
TMS320C64X_INS_MV,
|
||||
TMS320C64X_INS_NEG,
|
||||
TMS320C64X_INS_NOT,
|
||||
TMS320C64X_INS_SWAP2,
|
||||
TMS320C64X_INS_ZERO,
|
||||
|
||||
TMS320C64X_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} tms320c64x_insn;
|
||||
|
||||
typedef enum tms320c64x_insn_group {
|
||||
TMS320C64X_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
TMS320C64X_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
|
||||
TMS320C64X_GRP_FUNIT_D = 128,
|
||||
TMS320C64X_GRP_FUNIT_L,
|
||||
TMS320C64X_GRP_FUNIT_M,
|
||||
TMS320C64X_GRP_FUNIT_S,
|
||||
TMS320C64X_GRP_FUNIT_NO,
|
||||
|
||||
TMS320C64X_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} tms320c64x_insn_group;
|
||||
|
||||
typedef enum tms320c64x_funit {
|
||||
TMS320C64X_FUNIT_INVALID = 0,
|
||||
TMS320C64X_FUNIT_D,
|
||||
TMS320C64X_FUNIT_L,
|
||||
TMS320C64X_FUNIT_M,
|
||||
TMS320C64X_FUNIT_S,
|
||||
TMS320C64X_FUNIT_NO
|
||||
} tms320c64x_funit;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
1972
ai_anti_malware/capstone/include/capstone/x86.h
Normal file
1972
ai_anti_malware/capstone/include/capstone/x86.h
Normal file
File diff suppressed because it is too large
Load Diff
235
ai_anti_malware/capstone/include/capstone/xcore.h
Normal file
235
ai_anti_malware/capstone/include/capstone/xcore.h
Normal file
@@ -0,0 +1,235 @@
|
||||
#ifndef CAPSTONE_XCORE_H
|
||||
#define CAPSTONE_XCORE_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2014-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum xcore_op_type {
|
||||
XCORE_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
XCORE_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
XCORE_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
XCORE_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
} xcore_op_type;
|
||||
|
||||
/// XCore registers
|
||||
typedef enum xcore_reg {
|
||||
XCORE_REG_INVALID = 0,
|
||||
|
||||
XCORE_REG_CP,
|
||||
XCORE_REG_DP,
|
||||
XCORE_REG_LR,
|
||||
XCORE_REG_SP,
|
||||
XCORE_REG_R0,
|
||||
XCORE_REG_R1,
|
||||
XCORE_REG_R2,
|
||||
XCORE_REG_R3,
|
||||
XCORE_REG_R4,
|
||||
XCORE_REG_R5,
|
||||
XCORE_REG_R6,
|
||||
XCORE_REG_R7,
|
||||
XCORE_REG_R8,
|
||||
XCORE_REG_R9,
|
||||
XCORE_REG_R10,
|
||||
XCORE_REG_R11,
|
||||
|
||||
// pseudo registers
|
||||
XCORE_REG_PC, ///< pc
|
||||
|
||||
// internal thread registers
|
||||
// see The-XMOS-XS1-Architecture(X7879A).pdf
|
||||
XCORE_REG_SCP, ///< save pc
|
||||
XCORE_REG_SSR, //< save status
|
||||
XCORE_REG_ET, //< exception type
|
||||
XCORE_REG_ED, //< exception data
|
||||
XCORE_REG_SED, //< save exception data
|
||||
XCORE_REG_KEP, //< kernel entry pointer
|
||||
XCORE_REG_KSP, //< kernel stack pointer
|
||||
XCORE_REG_ID, //< thread ID
|
||||
|
||||
XCORE_REG_ENDING, // <-- mark the end of the list of registers
|
||||
} xcore_reg;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with XCORE_OP_MEM operand type above
|
||||
typedef struct xcore_op_mem {
|
||||
uint8_t base; ///< base register, can be safely interpreted as
|
||||
///< a value of type `xcore_reg`, but it is only
|
||||
///< one byte wide
|
||||
uint8_t index; ///< index register, same conditions apply here
|
||||
int32_t disp; ///< displacement/offset value
|
||||
int direct; ///< +1: forward, -1: backward
|
||||
} xcore_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_xcore_op {
|
||||
xcore_op_type type; ///< operand type
|
||||
union {
|
||||
xcore_reg reg; ///< register value for REG operand
|
||||
int32_t imm; ///< immediate value for IMM operand
|
||||
xcore_op_mem mem; ///< base/disp value for MEM operand
|
||||
};
|
||||
} cs_xcore_op;
|
||||
|
||||
/// Instruction structure
|
||||
typedef struct cs_xcore {
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
cs_xcore_op operands[8]; ///< operands for this instruction.
|
||||
} cs_xcore;
|
||||
|
||||
/// XCore instruction
|
||||
typedef enum xcore_insn {
|
||||
XCORE_INS_INVALID = 0,
|
||||
|
||||
XCORE_INS_ADD,
|
||||
XCORE_INS_ANDNOT,
|
||||
XCORE_INS_AND,
|
||||
XCORE_INS_ASHR,
|
||||
XCORE_INS_BAU,
|
||||
XCORE_INS_BITREV,
|
||||
XCORE_INS_BLA,
|
||||
XCORE_INS_BLAT,
|
||||
XCORE_INS_BL,
|
||||
XCORE_INS_BF,
|
||||
XCORE_INS_BT,
|
||||
XCORE_INS_BU,
|
||||
XCORE_INS_BRU,
|
||||
XCORE_INS_BYTEREV,
|
||||
XCORE_INS_CHKCT,
|
||||
XCORE_INS_CLRE,
|
||||
XCORE_INS_CLRPT,
|
||||
XCORE_INS_CLRSR,
|
||||
XCORE_INS_CLZ,
|
||||
XCORE_INS_CRC8,
|
||||
XCORE_INS_CRC32,
|
||||
XCORE_INS_DCALL,
|
||||
XCORE_INS_DENTSP,
|
||||
XCORE_INS_DGETREG,
|
||||
XCORE_INS_DIVS,
|
||||
XCORE_INS_DIVU,
|
||||
XCORE_INS_DRESTSP,
|
||||
XCORE_INS_DRET,
|
||||
XCORE_INS_ECALLF,
|
||||
XCORE_INS_ECALLT,
|
||||
XCORE_INS_EDU,
|
||||
XCORE_INS_EEF,
|
||||
XCORE_INS_EET,
|
||||
XCORE_INS_EEU,
|
||||
XCORE_INS_ENDIN,
|
||||
XCORE_INS_ENTSP,
|
||||
XCORE_INS_EQ,
|
||||
XCORE_INS_EXTDP,
|
||||
XCORE_INS_EXTSP,
|
||||
XCORE_INS_FREER,
|
||||
XCORE_INS_FREET,
|
||||
XCORE_INS_GETD,
|
||||
XCORE_INS_GET,
|
||||
XCORE_INS_GETN,
|
||||
XCORE_INS_GETR,
|
||||
XCORE_INS_GETSR,
|
||||
XCORE_INS_GETST,
|
||||
XCORE_INS_GETTS,
|
||||
XCORE_INS_INCT,
|
||||
XCORE_INS_INIT,
|
||||
XCORE_INS_INPW,
|
||||
XCORE_INS_INSHR,
|
||||
XCORE_INS_INT,
|
||||
XCORE_INS_IN,
|
||||
XCORE_INS_KCALL,
|
||||
XCORE_INS_KENTSP,
|
||||
XCORE_INS_KRESTSP,
|
||||
XCORE_INS_KRET,
|
||||
XCORE_INS_LADD,
|
||||
XCORE_INS_LD16S,
|
||||
XCORE_INS_LD8U,
|
||||
XCORE_INS_LDA16,
|
||||
XCORE_INS_LDAP,
|
||||
XCORE_INS_LDAW,
|
||||
XCORE_INS_LDC,
|
||||
XCORE_INS_LDW,
|
||||
XCORE_INS_LDIVU,
|
||||
XCORE_INS_LMUL,
|
||||
XCORE_INS_LSS,
|
||||
XCORE_INS_LSUB,
|
||||
XCORE_INS_LSU,
|
||||
XCORE_INS_MACCS,
|
||||
XCORE_INS_MACCU,
|
||||
XCORE_INS_MJOIN,
|
||||
XCORE_INS_MKMSK,
|
||||
XCORE_INS_MSYNC,
|
||||
XCORE_INS_MUL,
|
||||
XCORE_INS_NEG,
|
||||
XCORE_INS_NOT,
|
||||
XCORE_INS_OR,
|
||||
XCORE_INS_OUTCT,
|
||||
XCORE_INS_OUTPW,
|
||||
XCORE_INS_OUTSHR,
|
||||
XCORE_INS_OUTT,
|
||||
XCORE_INS_OUT,
|
||||
XCORE_INS_PEEK,
|
||||
XCORE_INS_REMS,
|
||||
XCORE_INS_REMU,
|
||||
XCORE_INS_RETSP,
|
||||
XCORE_INS_SETCLK,
|
||||
XCORE_INS_SET,
|
||||
XCORE_INS_SETC,
|
||||
XCORE_INS_SETD,
|
||||
XCORE_INS_SETEV,
|
||||
XCORE_INS_SETN,
|
||||
XCORE_INS_SETPSC,
|
||||
XCORE_INS_SETPT,
|
||||
XCORE_INS_SETRDY,
|
||||
XCORE_INS_SETSR,
|
||||
XCORE_INS_SETTW,
|
||||
XCORE_INS_SETV,
|
||||
XCORE_INS_SEXT,
|
||||
XCORE_INS_SHL,
|
||||
XCORE_INS_SHR,
|
||||
XCORE_INS_SSYNC,
|
||||
XCORE_INS_ST16,
|
||||
XCORE_INS_ST8,
|
||||
XCORE_INS_STW,
|
||||
XCORE_INS_SUB,
|
||||
XCORE_INS_SYNCR,
|
||||
XCORE_INS_TESTCT,
|
||||
XCORE_INS_TESTLCL,
|
||||
XCORE_INS_TESTWCT,
|
||||
XCORE_INS_TSETMR,
|
||||
XCORE_INS_START,
|
||||
XCORE_INS_WAITEF,
|
||||
XCORE_INS_WAITET,
|
||||
XCORE_INS_WAITEU,
|
||||
XCORE_INS_XOR,
|
||||
XCORE_INS_ZEXT,
|
||||
|
||||
XCORE_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} xcore_insn;
|
||||
|
||||
/// Group of XCore instructions
|
||||
typedef enum xcore_insn_group {
|
||||
XCORE_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
XCORE_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
|
||||
XCORE_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} xcore_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
110
ai_anti_malware/capstone/include/platform.h
Normal file
110
ai_anti_malware/capstone/include/platform.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Axel Souchet & Nguyen Anh Quynh, 2014 */
|
||||
|
||||
#ifndef CAPSTONE_PLATFORM_H
|
||||
#define CAPSTONE_PLATFORM_H
|
||||
|
||||
// handle C99 issue (for pre-2013 VisualStudio)
|
||||
#if !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64))
|
||||
// MSVC
|
||||
|
||||
// stdbool.h
|
||||
#if (_MSC_VER < 1800) || defined(_KERNEL_MODE)
|
||||
// this system does not have stdbool.h
|
||||
#ifndef __cplusplus
|
||||
typedef unsigned char bool;
|
||||
#define false 0
|
||||
#define true 1
|
||||
#endif
|
||||
|
||||
#else
|
||||
// VisualStudio 2013+ -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#else
|
||||
// not MSVC -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
|
||||
// handle C99 issue (for pre-2013 VisualStudio)
|
||||
#if defined(CAPSTONE_HAS_OSXKERNEL) || (defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE)))
|
||||
// this system does not have inttypes.h
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600 || defined(_KERNEL_MODE))
|
||||
// this system does not have stdint.h
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef signed long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
#define INT8_MIN (-127i8 - 1)
|
||||
#define INT16_MIN (-32767i16 - 1)
|
||||
#define INT32_MIN (-2147483647i32 - 1)
|
||||
#define INT64_MIN (-9223372036854775807i64 - 1)
|
||||
#define INT8_MAX 127i8
|
||||
#define INT16_MAX 32767i16
|
||||
#define INT32_MAX 2147483647i32
|
||||
#define INT64_MAX 9223372036854775807i64
|
||||
#define UINT8_MAX 0xffui8
|
||||
#define UINT16_MAX 0xffffui16
|
||||
#define UINT32_MAX 0xffffffffui32
|
||||
#define UINT64_MAX 0xffffffffffffffffui64
|
||||
#endif
|
||||
|
||||
#define __PRI_8_LENGTH_MODIFIER__ "hh"
|
||||
#define __PRI_64_LENGTH_MODIFIER__ "ll"
|
||||
|
||||
#define PRId8 __PRI_8_LENGTH_MODIFIER__ "d"
|
||||
#define PRIi8 __PRI_8_LENGTH_MODIFIER__ "i"
|
||||
#define PRIo8 __PRI_8_LENGTH_MODIFIER__ "o"
|
||||
#define PRIu8 __PRI_8_LENGTH_MODIFIER__ "u"
|
||||
#define PRIx8 __PRI_8_LENGTH_MODIFIER__ "x"
|
||||
#define PRIX8 __PRI_8_LENGTH_MODIFIER__ "X"
|
||||
|
||||
#define PRId16 "hd"
|
||||
#define PRIi16 "hi"
|
||||
#define PRIo16 "ho"
|
||||
#define PRIu16 "hu"
|
||||
#define PRIx16 "hx"
|
||||
#define PRIX16 "hX"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
#define PRId32 "ld"
|
||||
#define PRIi32 "li"
|
||||
#define PRIo32 "lo"
|
||||
#define PRIu32 "lu"
|
||||
#define PRIx32 "lx"
|
||||
#define PRIX32 "lX"
|
||||
#else // OSX
|
||||
#define PRId32 "d"
|
||||
#define PRIi32 "i"
|
||||
#define PRIo32 "o"
|
||||
#define PRIu32 "u"
|
||||
#define PRIx32 "x"
|
||||
#define PRIX32 "X"
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
// redefine functions from inttypes.h used in cstool
|
||||
#define strtoull _strtoui64
|
||||
#endif
|
||||
|
||||
#define PRId64 __PRI_64_LENGTH_MODIFIER__ "d"
|
||||
#define PRIi64 __PRI_64_LENGTH_MODIFIER__ "i"
|
||||
#define PRIo64 __PRI_64_LENGTH_MODIFIER__ "o"
|
||||
#define PRIu64 __PRI_64_LENGTH_MODIFIER__ "u"
|
||||
#define PRIx64 __PRI_64_LENGTH_MODIFIER__ "x"
|
||||
#define PRIX64 __PRI_64_LENGTH_MODIFIER__ "X"
|
||||
|
||||
#else
|
||||
// this system has inttypes.h by default
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
12
ai_anti_malware/capstone/include/windowsce/intrin.h
Normal file
12
ai_anti_malware/capstone/include/windowsce/intrin.h
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#if defined(_MSC_VER) && defined(_WIN32_WCE) && (_WIN32_WCE < 0x800) && !defined(__INTRIN_H_) && !defined(_INTRIN)
|
||||
#define _STDINT
|
||||
|
||||
#ifdef _M_ARM
|
||||
#include <armintr.h>
|
||||
#if (_WIN32_WCE >= 0x700) && defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
#endif // _M_ARM
|
||||
|
||||
#endif
|
||||
133
ai_anti_malware/capstone/include/windowsce/stdint.h
Normal file
133
ai_anti_malware/capstone/include/windowsce/stdint.h
Normal file
@@ -0,0 +1,133 @@
|
||||
|
||||
#if defined(_MSC_VER) && defined(_WIN32_WCE) && (_WIN32_WCE < 0x800) && !defined(_STDINT_H_) && !defined(_STDINT)
|
||||
#define _STDINT
|
||||
|
||||
typedef __int8
|
||||
int8_t,
|
||||
int_least8_t;
|
||||
|
||||
typedef __int16
|
||||
int16_t,
|
||||
int_least16_t;
|
||||
|
||||
typedef __int32
|
||||
int32_t,
|
||||
int_least32_t,
|
||||
int_fast8_t,
|
||||
int_fast16_t,
|
||||
int_fast32_t;
|
||||
|
||||
typedef __int64
|
||||
int64_t,
|
||||
intmax_t,
|
||||
int_least64_t,
|
||||
int_fast64_t;
|
||||
|
||||
typedef unsigned __int8
|
||||
uint8_t,
|
||||
uint_least8_t;
|
||||
|
||||
typedef unsigned __int16
|
||||
uint16_t,
|
||||
uint_least16_t;
|
||||
|
||||
typedef unsigned __int32
|
||||
uint32_t,
|
||||
uint_least32_t,
|
||||
uint_fast8_t,
|
||||
uint_fast16_t,
|
||||
uint_fast32_t;
|
||||
|
||||
typedef unsigned __int64
|
||||
uint64_t,
|
||||
uintmax_t,
|
||||
uint_least64_t,
|
||||
uint_fast64_t;
|
||||
|
||||
#ifndef _INTPTR_T_DEFINED
|
||||
#define _INTPTR_T_DEFINED
|
||||
typedef __int32 intptr_t;
|
||||
#endif
|
||||
|
||||
#ifndef _UINTPTR_T_DEFINED
|
||||
#define _UINTPTR_T_DEFINED
|
||||
typedef unsigned __int32 uintptr_t;
|
||||
#endif
|
||||
|
||||
#define INT8_MIN (-127i8 - 1)
|
||||
#define INT16_MIN (-32767i16 - 1)
|
||||
#define INT32_MIN (-2147483647i32 - 1)
|
||||
#define INT64_MIN (-9223372036854775807i64 - 1)
|
||||
#define INT8_MAX 127i8
|
||||
#define INT16_MAX 32767i16
|
||||
#define INT32_MAX 2147483647i32
|
||||
#define INT64_MAX 9223372036854775807i64
|
||||
#define UINT8_MAX 0xffui8
|
||||
#define UINT16_MAX 0xffffui16
|
||||
#define UINT32_MAX 0xffffffffui32
|
||||
#define UINT64_MAX 0xffffffffffffffffui64
|
||||
|
||||
#define INT_LEAST8_MIN INT8_MIN
|
||||
#define INT_LEAST16_MIN INT16_MIN
|
||||
#define INT_LEAST32_MIN INT32_MIN
|
||||
#define INT_LEAST64_MIN INT64_MIN
|
||||
#define INT_LEAST8_MAX INT8_MAX
|
||||
#define INT_LEAST16_MAX INT16_MAX
|
||||
#define INT_LEAST32_MAX INT32_MAX
|
||||
#define INT_LEAST64_MAX INT64_MAX
|
||||
#define UINT_LEAST8_MAX UINT8_MAX
|
||||
#define UINT_LEAST16_MAX UINT16_MAX
|
||||
#define UINT_LEAST32_MAX UINT32_MAX
|
||||
#define UINT_LEAST64_MAX UINT64_MAX
|
||||
|
||||
#define INT_FAST8_MIN INT8_MIN
|
||||
#define INT_FAST16_MIN INT32_MIN
|
||||
#define INT_FAST32_MIN INT32_MIN
|
||||
#define INT_FAST64_MIN INT64_MIN
|
||||
#define INT_FAST8_MAX INT8_MAX
|
||||
#define INT_FAST16_MAX INT32_MAX
|
||||
#define INT_FAST32_MAX INT32_MAX
|
||||
#define INT_FAST64_MAX INT64_MAX
|
||||
#define UINT_FAST8_MAX UINT8_MAX
|
||||
#define UINT_FAST16_MAX UINT32_MAX
|
||||
#define UINT_FAST32_MAX UINT32_MAX
|
||||
#define UINT_FAST64_MAX UINT64_MAX
|
||||
|
||||
#define INTPTR_MIN INT32_MIN
|
||||
#define INTPTR_MAX INT32_MAX
|
||||
#define UINTPTR_MAX UINT32_MAX
|
||||
|
||||
#define INTMAX_MIN INT64_MIN
|
||||
#define INTMAX_MAX INT64_MAX
|
||||
#define UINTMAX_MAX UINT64_MAX
|
||||
|
||||
#define PTRDIFF_MIN INTPTR_MIN
|
||||
#define PTRDIFF_MAX INTPTR_MAX
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX UINTPTR_MAX
|
||||
#endif
|
||||
|
||||
#define SIG_ATOMIC_MIN INT32_MIN
|
||||
#define SIG_ATOMIC_MAX INT32_MAX
|
||||
|
||||
#define WCHAR_MIN 0x0000
|
||||
#define WCHAR_MAX 0xffff
|
||||
|
||||
#define WINT_MIN 0x0000
|
||||
#define WINT_MAX 0xffff
|
||||
|
||||
#define INT8_C(x) (x)
|
||||
#define INT16_C(x) (x)
|
||||
#define INT32_C(x) (x)
|
||||
#define INT64_C(x) (x ## LL)
|
||||
|
||||
#define UINT8_C(x) (x)
|
||||
#define UINT16_C(x) (x)
|
||||
#define UINT32_C(x) (x ## U)
|
||||
#define UINT64_C(x) (x ## ULL)
|
||||
|
||||
#define INTMAX_C(x) INT64_C(x)
|
||||
#define UINTMAX_C(x) UINT64_C(x)
|
||||
|
||||
#endif
|
||||
31
ai_anti_malware/head.h
Normal file
31
ai_anti_malware/head.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#include <iostream>
|
||||
#include <iostream>
|
||||
#include <winternl.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <ntstatus.h>
|
||||
#include <ctime>
|
||||
|
||||
|
||||
#include "unicorn/include/unicorn/unicorn.h"
|
||||
#include "capstone/include/capstone/capstone.h"
|
||||
#pragma comment(lib, "unicorn/unicorn.lib")
|
||||
#pragma comment(lib, "capstone/capstone.lib")
|
||||
#include "libpeconv/include/peconv.h"
|
||||
#include "native_struct.h"
|
||||
struct BasicPeInfo {
|
||||
std::string inputFilePath;
|
||||
bool isX64;
|
||||
uint64_t RecImageBase;
|
||||
uint64_t entryPoint;
|
||||
uint64_t imageEnd;
|
||||
bool isRelocated;
|
||||
uint8_t* peBuffer;
|
||||
size_t peSize;
|
||||
PIMAGE_NT_HEADERS ntHead64;
|
||||
PIMAGE_NT_HEADERS32 ntHead32;
|
||||
};
|
||||
#include "sandbox.h"
|
||||
83
ai_anti_malware/libpeconv/libpeconv/CMakeLists.txt
Normal file
83
ai_anti_malware/libpeconv/libpeconv/CMakeLists.txt
Normal file
@@ -0,0 +1,83 @@
|
||||
cmake_minimum_required ( VERSION 2.8 )
|
||||
project ( libpeconv )
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
|
||||
|
||||
include_directories (
|
||||
include
|
||||
)
|
||||
|
||||
set (srcs
|
||||
src/pe_hdrs_helper.cpp
|
||||
src/pe_mode_detector.cpp
|
||||
src/pe_raw_to_virtual.cpp
|
||||
src/pe_virtual_to_raw.cpp
|
||||
src/relocate.cpp
|
||||
src/buffer_util.cpp
|
||||
src/remote_pe_reader.cpp
|
||||
src/imports_loader.cpp
|
||||
src/delayed_imports_loader.cpp
|
||||
src/fix_imports.cpp
|
||||
src/pe_loader.cpp
|
||||
src/pe_dumper.cpp
|
||||
src/exports_lookup.cpp
|
||||
src/function_resolver.cpp
|
||||
src/hooks.cpp
|
||||
src/exported_func.cpp
|
||||
src/exports_mapper.cpp
|
||||
src/resource_parser.cpp
|
||||
src/file_util.cpp
|
||||
src/resource_util.cpp
|
||||
src/imports_uneraser.cpp
|
||||
src/load_config_util.cpp
|
||||
src/caves.cpp
|
||||
src/util.cpp
|
||||
src/fix_dot_net_ep.cpp
|
||||
src/find_base.cpp
|
||||
src/peb_lookup.cpp
|
||||
)
|
||||
|
||||
set (hdrs
|
||||
include/peconv.h
|
||||
include/peconv/pe_hdrs_helper.h
|
||||
include/peconv/pe_mode_detector.h
|
||||
include/peconv/pe_raw_to_virtual.h
|
||||
include/peconv/pe_virtual_to_raw.h
|
||||
include/peconv/relocate.h
|
||||
include/peconv/util.h
|
||||
include/peconv/buffer_util.h
|
||||
include/peconv/remote_pe_reader.h
|
||||
include/peconv/imports_loader.h
|
||||
include/peconv/delayed_imports_loader.h
|
||||
include/peconv/fix_imports.h
|
||||
include/peconv/pe_loader.h
|
||||
include/peconv/pe_dumper.h
|
||||
include/peconv/exports_lookup.h
|
||||
include/peconv/function_resolver.h
|
||||
include/peconv/hooks.h
|
||||
include/peconv/exported_func.h
|
||||
include/peconv/exports_mapper.h
|
||||
include/peconv/resource_parser.h
|
||||
include/peconv/file_util.h
|
||||
include/peconv/resource_util.h
|
||||
include/peconv/imports_uneraser.h
|
||||
include/peconv/load_config_util.h
|
||||
include/peconv/load_config_defs.h
|
||||
include/peconv/caves.h
|
||||
include/peconv/find_base.h
|
||||
include/peconv/peb_lookup.h
|
||||
src/fix_dot_net_ep.h #not in API
|
||||
)
|
||||
|
||||
add_library ( ${PROJECT_NAME} STATIC ${hdrs} ${srcs} )
|
||||
|
||||
if(PECONV_LIB_INSTALL)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
install(TARGETS ${PROJECT_NAME}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
|
||||
install(DIRECTORY "include/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
endif()
|
||||
30
ai_anti_malware/libpeconv/libpeconv/include/peconv.h
Normal file
30
ai_anti_malware/libpeconv/libpeconv/include/peconv.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Master include file, including everything else.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "peconv/buffer_util.h"
|
||||
#include "peconv/util.h"
|
||||
#include "peconv/pe_hdrs_helper.h"
|
||||
#include "peconv/pe_mode_detector.h"
|
||||
#include "peconv/pe_raw_to_virtual.h"
|
||||
#include "peconv/pe_virtual_to_raw.h"
|
||||
#include "peconv/relocate.h"
|
||||
#include "peconv/remote_pe_reader.h"
|
||||
#include "peconv/imports_loader.h"
|
||||
#include "peconv/pe_loader.h"
|
||||
#include "peconv/pe_dumper.h"
|
||||
#include "peconv/exports_lookup.h"
|
||||
#include "peconv/function_resolver.h"
|
||||
#include "peconv/hooks.h"
|
||||
#include "peconv/exports_mapper.h"
|
||||
#include "peconv/caves.h"
|
||||
#include "peconv/fix_imports.h"
|
||||
#include "peconv/delayed_imports_loader.h"
|
||||
#include "peconv/resource_parser.h"
|
||||
#include "peconv/load_config_util.h"
|
||||
#include "peconv/peb_lookup.h"
|
||||
#include "peconv/find_base.h"
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Definitions of the used buffer types. Functions for their allocation and deallocation.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
Validates pointers, checks if the particular field is inside the given buffer. Sizes must be given in bytes.
|
||||
*/
|
||||
bool validate_ptr(
|
||||
IN const void* buffer_bgn,
|
||||
IN SIZE_T buffer_size,
|
||||
IN const void* field_bgn,
|
||||
IN SIZE_T field_size
|
||||
);
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// supported buffers:
|
||||
//
|
||||
/**
|
||||
A buffer allocated on the heap of a process, not aligned to the beginning of a memory page.
|
||||
*/
|
||||
typedef PBYTE UNALIGNED_BUF;
|
||||
|
||||
/**
|
||||
A buffer allocated in a virtual space of a process, aligned to the beginning of a memory page.
|
||||
*/
|
||||
typedef PBYTE ALIGNED_BUF;
|
||||
|
||||
//
|
||||
// alloc/free unaligned buffers:
|
||||
//
|
||||
/**
|
||||
Allocates a buffer on the heap. Can be used in the cases when the buffer does not have to start at the beginning of a page.
|
||||
*/
|
||||
UNALIGNED_BUF alloc_unaligned(size_t buf_size);
|
||||
|
||||
//
|
||||
/**
|
||||
Frees buffer allocated by alloc_unaligned.
|
||||
*/
|
||||
void free_unaligned(UNALIGNED_BUF section_buffer);
|
||||
|
||||
//
|
||||
// alloc/free aligned buffers:
|
||||
//
|
||||
|
||||
/**
|
||||
Allocates a buffer of a virtual memory (using VirtualAlloc). Can be used in the cases when the buffer have to be aligned to the beginning of a page.
|
||||
*/
|
||||
ALIGNED_BUF alloc_aligned(size_t buffer_size, DWORD protect, ULONGLONG desired_base=NULL, bool is_x64 = false);
|
||||
|
||||
/**
|
||||
Frees buffer allocated by alloc_aligned.
|
||||
*/
|
||||
bool free_aligned(ALIGNED_BUF buffer, size_t buffer_size=0);
|
||||
|
||||
//PE buffers (wrappers)
|
||||
|
||||
/**
|
||||
Allocates an aligned buffer for a PE file.
|
||||
*/
|
||||
ALIGNED_BUF alloc_pe_buffer(size_t buffer_size, DWORD protect, ULONGLONG desired_base=NULL);
|
||||
|
||||
/**
|
||||
Free the memory allocated with alloc_pe_buffer.
|
||||
*/
|
||||
bool free_pe_buffer(ALIGNED_BUF buffer, size_t buffer_size=0);
|
||||
|
||||
}; //namespace peconv
|
||||
27
ai_anti_malware/libpeconv/libpeconv/include/peconv/caves.h
Normal file
27
ai_anti_malware/libpeconv/libpeconv/include/peconv/caves.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Functions related to finding caves in the loaded PE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
Finds cave at the end of the image (extend last section's raw size without extending the full image size)
|
||||
*/
|
||||
PBYTE find_ending_cave(BYTE* module_ptr, size_t module_size, const DWORD cave_size, const DWORD cave_charact=IMAGE_SCN_MEM_READ);
|
||||
|
||||
/**
|
||||
Finds cave in the difference between the original raw size, and the raw size rounded to the aligmnent
|
||||
*/
|
||||
PBYTE find_alignment_cave(BYTE* modulePtr, size_t moduleSize, const DWORD cave_size, const DWORD req_charact = IMAGE_SCN_MEM_READ);
|
||||
|
||||
/**
|
||||
Finds cave at the end of the section, that comes from a NULL padding or INT3 padding
|
||||
*/
|
||||
PBYTE find_padding_cave(BYTE* modulePtr, size_t moduleSize, const size_t minimal_size, const DWORD req_charact = IMAGE_SCN_MEM_READ);
|
||||
|
||||
};//namespace peconv
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Parsing and filling the Delayload Import Table.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "pe_hdrs_helper.h"
|
||||
#include "function_resolver.h"
|
||||
|
||||
#if (defined(_WIN32_WINNT) && _WIN32_WINNT > 0x0601) || __MINGW32__ //Windows SDK version 6.1 (Windows 7)
|
||||
#define DELAYLOAD_IMPORTS_DEFINED
|
||||
#endif
|
||||
|
||||
#ifndef DELAYLOAD_IMPORTS_DEFINED
|
||||
#include "pshpack4.h"
|
||||
|
||||
typedef struct _IMAGE_DELAYLOAD_DESCRIPTOR {
|
||||
union {
|
||||
DWORD AllAttributes;
|
||||
struct {
|
||||
DWORD RvaBased : 1; // Delay load version 2
|
||||
DWORD ReservedAttributes : 31;
|
||||
} DUMMYSTRUCTNAME;
|
||||
} Attributes;
|
||||
|
||||
DWORD DllNameRVA; // RVA to the name of the target library (NULL-terminate ASCII string)
|
||||
DWORD ModuleHandleRVA; // RVA to the HMODULE caching location (PHMODULE)
|
||||
DWORD ImportAddressTableRVA; // RVA to the start of the IAT (PIMAGE_THUNK_DATA)
|
||||
DWORD ImportNameTableRVA; // RVA to the start of the name table (PIMAGE_THUNK_DATA::AddressOfData)
|
||||
DWORD BoundImportAddressTableRVA; // RVA to an optional bound IAT
|
||||
DWORD UnloadInformationTableRVA; // RVA to an optional unload info table
|
||||
DWORD TimeDateStamp; // 0 if not bound,
|
||||
// Otherwise, date/time of the target DLL
|
||||
|
||||
} IMAGE_DELAYLOAD_DESCRIPTOR, *PIMAGE_DELAYLOAD_DESCRIPTOR;
|
||||
|
||||
typedef const IMAGE_DELAYLOAD_DESCRIPTOR *PCIMAGE_DELAYLOAD_DESCRIPTOR;
|
||||
|
||||
#include "poppack.h"
|
||||
#endif
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
Get the Delayload Imports directory. Returns the pointer to the first descriptor. The size of the directory is passed via variable dir_size.
|
||||
*/
|
||||
IMAGE_DELAYLOAD_DESCRIPTOR* get_delayed_imps(IN const BYTE* modulePtr, IN const size_t moduleSize, OUT size_t &dir_size);
|
||||
|
||||
/**
|
||||
Fill the Delayload Imports in the given module.
|
||||
\param modulePtr : the pointer to the module where the imports needs to be filled.
|
||||
\param moduleBase : the base to which the module was relocated, it may (or not) be the same as modulePtr
|
||||
\param func_resolver : the resolver that will be used for loading the imports
|
||||
\return : true if resolving all succeeded, false otherwise
|
||||
*/
|
||||
bool load_delayed_imports(BYTE* modulePtr, const ULONGLONG moduleBase, t_function_resolver* func_resolver = nullptr);
|
||||
|
||||
}; // namespace peconv
|
||||
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief A definition of ExportedFunc class - used for storing the details of the exported function. Helper functions related to the export parsing.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
Check if the pointer redirects to a forwarder - if so, return the length, otherwise return 0.
|
||||
*/
|
||||
size_t forwarder_name_len(BYTE* fPtr);
|
||||
|
||||
/**
|
||||
get the DLL name without the extension
|
||||
*/
|
||||
std::string get_dll_shortname(const std::string& str);
|
||||
|
||||
/**
|
||||
Get the function name from the string in a format: DLL_name.function_name
|
||||
*/
|
||||
std::string get_func_name(const std::string& str);
|
||||
|
||||
/**
|
||||
Convert ordinal value to the ordinal string (in a format #[ordinal])
|
||||
*/
|
||||
std::string ordinal_to_string(DWORD func_ordinal);
|
||||
|
||||
/**
|
||||
Check if the given string is in a format typical for storing ordinals (#[ordinal])
|
||||
*/
|
||||
bool is_ordinal_string(const std::string& str);
|
||||
|
||||
/**
|
||||
Get the ordinal value from the ordinal string (in a format #[ordinal])
|
||||
*/
|
||||
DWORD ordinal_string_to_val(const std::string& str);
|
||||
|
||||
/**
|
||||
Convert the function in a format: DLL_name.function_name into a normalized form (DLL name in lowercase).
|
||||
*/
|
||||
std::string format_dll_func(const std::string& str);
|
||||
|
||||
/**
|
||||
A class storing the information about the exported function.
|
||||
*/
|
||||
class ExportedFunc
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Converts the name to the normalized format.
|
||||
*/
|
||||
static std::string formatName(std::string name);
|
||||
|
||||
std::string libName;
|
||||
std::string funcName;
|
||||
DWORD funcOrdinal;
|
||||
bool isByOrdinal;
|
||||
|
||||
//default constructor:
|
||||
ExportedFunc() : funcOrdinal(0), isByOrdinal(false) {}
|
||||
|
||||
ExportedFunc(const ExportedFunc& other);
|
||||
ExportedFunc(std::string libName, std::string funcName, DWORD funcOrdinal);
|
||||
ExportedFunc(std::string libName, DWORD funcOrdinal);
|
||||
ExportedFunc(const std::string &forwarderName);
|
||||
|
||||
/**
|
||||
Compare two functions with each other.
|
||||
Gives the priority to the named functions: if one of the compared functions is unnamed, the named one is treated as smaller.
|
||||
If both functions are unnamed, the function with the smaller ordinal is treated as smaller.
|
||||
Otherwise, the function with the shorter name is treated as smaller.
|
||||
*/
|
||||
bool operator < (const ExportedFunc& other) const
|
||||
{
|
||||
//if only one function is named, give the preference to the named one:
|
||||
const size_t thisNameLen = this->funcName.length();
|
||||
const size_t otherNameLen = other.funcName.length();
|
||||
if (thisNameLen == 0 && otherNameLen > 0) {
|
||||
return false;
|
||||
}
|
||||
if (thisNameLen > 0 && otherNameLen == 0) {
|
||||
return true;
|
||||
}
|
||||
//select by shorter lib name:
|
||||
int cmp = libName.compare(other.libName);
|
||||
if (cmp != 0) {
|
||||
return cmp < 0;
|
||||
}
|
||||
if (thisNameLen == 0 || otherNameLen == 0) {
|
||||
return this->funcOrdinal < other.funcOrdinal;
|
||||
}
|
||||
if (thisNameLen != otherNameLen) {
|
||||
return thisNameLen < otherNameLen;
|
||||
}
|
||||
cmp = funcName.compare(other.funcName);
|
||||
return cmp < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Gets a string representation of the variable. Full info about the function: library, name, ordinal.
|
||||
*/
|
||||
std::string toString() const;
|
||||
|
||||
/**
|
||||
Gets a string representation of the variable. Short info about the function: only function name or ordinal (if the name is missing).
|
||||
*/
|
||||
std::string nameToString() const;
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return (funcName != "" || funcOrdinal != -1);
|
||||
}
|
||||
};
|
||||
|
||||
}; //namespace peconv
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Searching specific functions in PE's Exports Table.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
|
||||
#include "pe_hdrs_helper.h"
|
||||
#include "function_resolver.h"
|
||||
#include "exports_mapper.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
Gets the function address by the name. Uses Export Table lookup.
|
||||
WARNING: doesn't work for the forwarded functions.
|
||||
*/
|
||||
FARPROC get_exported_func(PVOID modulePtr, LPSTR wanted_name);
|
||||
|
||||
/**
|
||||
Gets list of all the functions from a given module that are exported by names.
|
||||
*/
|
||||
size_t get_exported_names(PVOID modulePtr, std::vector<std::string> &names_list);
|
||||
|
||||
/**
|
||||
Function resolver using Export Table lookup.
|
||||
*/
|
||||
class export_based_resolver : default_func_resolver {
|
||||
public:
|
||||
/**
|
||||
Get the address (VA) of the function with the given name, from the given DLL.
|
||||
Uses Export Table lookup as a primary method of finding the import. On failure it falls back to the default Functions Resolver.
|
||||
\param func_name : the name of the function
|
||||
\param lib_name : the name of the DLL
|
||||
\return Virtual Address of the exported function
|
||||
*/
|
||||
virtual FARPROC resolve_func(LPSTR lib_name, LPSTR func_name);
|
||||
};
|
||||
|
||||
/**
|
||||
Read the DLL name from the Export Table.
|
||||
*/
|
||||
LPSTR read_dll_name(HMODULE modulePtr);
|
||||
|
||||
}; //namespace peconv
|
||||
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief A definition of ExportsMapper class. Creates a lookup of all the exported functions from the supplied DLLs. Allows to associate an address with a corresponding function.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
|
||||
#include "pe_hdrs_helper.h"
|
||||
#include "pe_raw_to_virtual.h"
|
||||
#include "peconv/exported_func.h"
|
||||
#include "peconv/file_util.h"
|
||||
|
||||
namespace peconv {
|
||||
|
||||
class ExportsMapper {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
Appends the given DLL to the lookup table of exported functions. Returns the number of functions exported from this DLL (not forwarded).
|
||||
\param moduleName : name of the DLL
|
||||
\param modulePtr : buffer containing the DLL in a Virtual format
|
||||
\param moduleBase : a base address to which the given DLL was relocated
|
||||
*/
|
||||
size_t add_to_lookup(std::string moduleName, HMODULE modulePtr, ULONGLONG moduleBase);
|
||||
|
||||
/**
|
||||
Appends the given DLL to the lookup table of exported functions. Returns the number of functions exported from this DLL (not forwarded).
|
||||
Assumes that the module was relocated to the same address as is the address of the given buffer (modulePtr).
|
||||
(A wrapper for the case if we are adding a DLL that was loaded within the current process.)
|
||||
\param moduleName : name of the DLL
|
||||
\param modulePtr : buffer containing the DLL in a Virtual format.
|
||||
*/
|
||||
size_t add_to_lookup(std::string moduleName, HMODULE modulePtr)
|
||||
{
|
||||
return add_to_lookup(moduleName, modulePtr, reinterpret_cast<ULONGLONG>(modulePtr));
|
||||
}
|
||||
|
||||
/**
|
||||
Find the set of Exported Functions that can be mapped to the given VA. Includes forwarders, and function aliases.
|
||||
*/
|
||||
const std::set<ExportedFunc>* find_exports_by_va(ULONGLONG va) const
|
||||
{
|
||||
std::map<ULONGLONG, std::set<ExportedFunc>>::const_iterator itr = va_to_func.find(va);
|
||||
if (itr != va_to_func.end()) {
|
||||
const std::set<ExportedFunc> &fSet = itr->second;
|
||||
return &fSet;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieve the full path of the DLL with the given short name.
|
||||
*/
|
||||
std::string get_dll_path(std::string short_name) const
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator found = this->dll_shortname_to_path.find(short_name);
|
||||
if (found == dll_shortname_to_path.end()) {
|
||||
return "";
|
||||
}
|
||||
return found->second;
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieve the full name of the DLL (including the extension) using its short name (without the extension).
|
||||
*/
|
||||
std::string get_dll_fullname(std::string short_name) const
|
||||
{
|
||||
std::string dll_path = get_dll_path(short_name);
|
||||
if (dll_path.length() == 0) return "";
|
||||
|
||||
return get_file_name(dll_path);
|
||||
}
|
||||
|
||||
/**
|
||||
Find an Exported Function that can be mapped to the given VA,
|
||||
*/
|
||||
const ExportedFunc* find_export_by_va(ULONGLONG va) const
|
||||
{
|
||||
const std::set<ExportedFunc>* exp_set = find_exports_by_va(va);
|
||||
if (exp_set == NULL) return NULL;
|
||||
|
||||
std::set<ExportedFunc>::iterator fItr = exp_set->begin();
|
||||
const ExportedFunc* func = &(*fItr);
|
||||
return func;
|
||||
}
|
||||
|
||||
void print_va_to_func(std::stringstream &stream) const;
|
||||
void print_func_to_va(std::stringstream &stream) const;
|
||||
|
||||
|
||||
private:
|
||||
enum ADD_FUNC_RES { RES_INVALID = 0, RES_MAPPED = 1, RES_FORWARDED = 2 };
|
||||
ADD_FUNC_RES add_function_to_lookup(HMODULE modulePtr, ULONGLONG moduleBase, size_t moduleSize, ExportedFunc &currFunc, DWORD callRVA);
|
||||
|
||||
bool add_forwarded(ExportedFunc &currFunc, DWORD callRVA, PBYTE modulePtr, size_t moduleSize);
|
||||
bool add_to_maps(ULONGLONG va, ExportedFunc &currFunc);
|
||||
|
||||
size_t resolve_forwarders(const ULONGLONG va, ExportedFunc &currFunc);
|
||||
size_t make_ord_lookup_tables(PVOID modulePtr, size_t moduleSize, std::map<PDWORD, DWORD> &va_to_ord);
|
||||
|
||||
protected:
|
||||
/**
|
||||
Add a function and a VA into a mutual mapping.
|
||||
*/
|
||||
void associateVaAndFunc(ULONGLONG va, const ExportedFunc& func)
|
||||
{
|
||||
va_to_func[va].insert(func);
|
||||
func_to_va[func] = va;
|
||||
}
|
||||
|
||||
/**
|
||||
A map associating VA of the function with the related exports.
|
||||
*/
|
||||
std::map<ULONGLONG, std::set<ExportedFunc>> va_to_func;
|
||||
|
||||
/**
|
||||
A map associating an exported functions with its forwarders.
|
||||
*/
|
||||
std::map<ExportedFunc, std::set<ExportedFunc>> forwarders_lookup;
|
||||
|
||||
/**
|
||||
A map associating an exported functions with its VA.
|
||||
*/
|
||||
std::map<ExportedFunc, ULONGLONG> func_to_va;
|
||||
|
||||
/**
|
||||
A map associating DLL shortname with the full path to the DLL.
|
||||
*/
|
||||
std::map<std::string, std::string> dll_shortname_to_path;
|
||||
};
|
||||
|
||||
}; //namespace peconv
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Functions related to operations on files. Wrappers for read/write.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "buffer_util.h"
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
Maps a file with the given path and copies its raw content into the output buffer.
|
||||
If read_size is not zero, it reads maximum read_size of bytes. If read_size is zero, it reads the full file.
|
||||
The actual read size is returned back in read_size.
|
||||
Automatically allocates a buffer of the required size.
|
||||
*/
|
||||
peconv::ALIGNED_BUF load_file(IN const char *filename, OUT size_t &r_size);
|
||||
|
||||
/**
|
||||
Reads a raw content of the file with the given path.
|
||||
If read_size is not zero, it reads maximum read_size of bytes. If read_size is zero, it reads the full file.
|
||||
The actual read size is returned back in read_size.
|
||||
Automatically allocates a buffer of the required size.
|
||||
*/
|
||||
peconv::ALIGNED_BUF read_from_file(IN const char *path, IN OUT size_t &read_size);
|
||||
|
||||
/**
|
||||
Writes a buffer of bytes into a file of given path.
|
||||
\param path : the path to the output file
|
||||
\param dump_data : the buffer to be dumped
|
||||
\param dump_size : the size of data to be dumped (in bytes)
|
||||
\return true if succeeded, false if failed
|
||||
*/
|
||||
bool dump_to_file(IN const char *path, IN PBYTE dump_data, IN size_t dump_size);
|
||||
|
||||
/**
|
||||
Free the buffer allocated by load_file/read_from_file
|
||||
*/
|
||||
void free_file(IN peconv::ALIGNED_BUF buffer);
|
||||
|
||||
/**
|
||||
Get the file name from the given path.
|
||||
*/
|
||||
std::string get_file_name(IN const std::string full_path);
|
||||
|
||||
/**
|
||||
Get the directory name from the given path. It assumes that a directory name always ends with a separator ("/" or "\")
|
||||
*/
|
||||
std::string get_directory_name(IN const std::string full_path);
|
||||
|
||||
}; //namespace peconv
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Functions related to finding a base to which the module was relocated.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
Try to find a base to which the PE file was relocated, basing on the filled relocations.
|
||||
WARNING: the found base is an estimate, and sometimes may not be fully accurate.
|
||||
\param module_ptr : the module which's base is being searched
|
||||
\param module_size : the size of the given module
|
||||
\return the base to which the module was relocated
|
||||
*/
|
||||
ULONGLONG find_base_candidate(IN BYTE *module_ptr, IN size_t module_size);
|
||||
};
|
||||
119
ai_anti_malware/libpeconv/libpeconv/include/peconv/fix_imports.h
Normal file
119
ai_anti_malware/libpeconv/libpeconv/include/peconv/fix_imports.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Functions and classes responsible for fixing Import Table. A definition of ImportedDllCoverage class.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include "pe_hdrs_helper.h"
|
||||
#include "exports_lookup.h"
|
||||
#include "exports_mapper.h"
|
||||
|
||||
#define MIN_DLL_LEN 5
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
a helper class that allows to store information about functions that could not be covered by the given mapping
|
||||
*/
|
||||
class ImpsNotCovered
|
||||
{
|
||||
public:
|
||||
ImpsNotCovered() {}
|
||||
~ImpsNotCovered() {}
|
||||
|
||||
/*
|
||||
Number of stored records
|
||||
*/
|
||||
size_t count() { return thunkToAddr.size(); }
|
||||
|
||||
void insert(ULONGLONG thunk, ULONGLONG searchedAddr);
|
||||
|
||||
std::map<ULONGLONG, ULONGLONG> thunkToAddr; //addresses of not recovered functions with their thunks (call_via)
|
||||
};
|
||||
|
||||
/**
|
||||
fix imports in the given module, using the given map of all available exports
|
||||
*/
|
||||
bool fix_imports(IN OUT PVOID modulePtr, IN size_t moduleSize, IN const peconv::ExportsMapper& exportsMap, OUT OPTIONAL peconv::ImpsNotCovered* notCovered);
|
||||
|
||||
/**
|
||||
a helper class that allows to find out where the functions are imported from
|
||||
*/
|
||||
class ImportedDllCoverage
|
||||
{
|
||||
public:
|
||||
/**
|
||||
A constructor of an object of ImportedDllCoverage class.
|
||||
\param _addresses : the list of filled imports (VAs): the addresses to be covered
|
||||
\param _exportsMap : the map of the exports of all the loaded DLLs (the space in which we will be searching)
|
||||
*/
|
||||
ImportedDllCoverage(std::set<ULONGLONG>& _addresses, const peconv::ExportsMapper& _exportsMap)
|
||||
: addresses(_addresses), exportsMap(_exportsMap)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
Checks if all the addresses can be covered by one DLL. If yes, this dll will be saved into: dllName.
|
||||
\return true if the covering DLL for the addresses was found. false otherwise.
|
||||
*/
|
||||
bool findCoveringDll();
|
||||
|
||||
/**
|
||||
Maps the addresses from the set to functions from the given DLL.
|
||||
Results are saved into: addrToFunc.
|
||||
Addresses that could not be covered by the given DLL are saved into notFound.
|
||||
Before each execution, the content of involved variables is erased.
|
||||
\param _mappedDllName : the name of the DLL that we will be used to mapping. This DLL is saved into mappedDllName.
|
||||
\return a number of covered functions
|
||||
*/
|
||||
size_t mapAddressesToFunctions(const std::string &_mappedDllName);
|
||||
|
||||
/**
|
||||
Check if the functions mapping is complete.
|
||||
\return the status: true if all the addresses are mapped to specific exports, false if not
|
||||
*/
|
||||
bool isMappingComplete() { return (addresses.size() == addrToFunc.size()) ? true : false; }
|
||||
|
||||
/**
|
||||
A mapping associating each of the covered function addresses with the set of exports (from mapped DLL) that cover this address
|
||||
*/
|
||||
std::map<ULONGLONG, std::set<ExportedFunc>> addrToFunc;
|
||||
|
||||
/**
|
||||
Addresses of the functions not found in the mapped DLL
|
||||
*/
|
||||
std::set<ULONGLONG> notFound;
|
||||
|
||||
/**
|
||||
Name of the covering DLL
|
||||
*/
|
||||
std::string dllName;
|
||||
|
||||
protected:
|
||||
/**
|
||||
A name of the DLL that was used for mapping. In a typical scenario it will be the same as covering DLL, but may be set different.
|
||||
*/
|
||||
std::string mappedDllName;
|
||||
|
||||
/**
|
||||
A supplied set of the addresses of imported functions.
|
||||
Those addressed will be covered (associated with the corresponding exports from available DLLs, defined by exportsMap).
|
||||
*/
|
||||
std::set<ULONGLONG> &addresses;
|
||||
|
||||
/**
|
||||
A supplied exportsMap. Only used as a lookup, no changes applied.
|
||||
*/
|
||||
const peconv::ExportsMapper& exportsMap;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Definitions of basic Imports Resolver classes. They can be used for filling imports when the PE is loaded.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace peconv {
|
||||
/**
|
||||
A base class for functions resolver.
|
||||
*/
|
||||
class t_function_resolver {
|
||||
public:
|
||||
/**
|
||||
Get the address (VA) of the function with the given name, from the given DLL.
|
||||
\param func_name : the name of the function
|
||||
\param lib_name : the name of the DLL
|
||||
\return Virtual Address of the exported function
|
||||
*/
|
||||
virtual FARPROC resolve_func(LPSTR lib_name, LPSTR func_name) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
A default functions resolver, using LoadLibraryA and GetProcAddress.
|
||||
*/
|
||||
class default_func_resolver : t_function_resolver {
|
||||
public:
|
||||
/**
|
||||
Get the address (VA) of the function with the given name, from the given DLL, using LoadLibraryA and GetProcAddress.
|
||||
\param func_name : the name of the function
|
||||
\param lib_name : the name of the DLL
|
||||
\return Virtual Address of the exported function
|
||||
*/
|
||||
virtual FARPROC resolve_func(LPSTR lib_name, LPSTR func_name);
|
||||
};
|
||||
|
||||
}; //namespace peconv
|
||||
135
ai_anti_malware/libpeconv/libpeconv/include/peconv/hooks.h
Normal file
135
ai_anti_malware/libpeconv/libpeconv/include/peconv/hooks.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Functions related to hooking the loaded PE. Reditecting/replacing a functions with another.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include "function_resolver.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "peconv/buffer_util.h"
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
A buffer storing a binary patch, that can be applied on a module. Used as a restorable backup in case of function patching.
|
||||
*/
|
||||
class PatchBackup {
|
||||
public:
|
||||
/**
|
||||
Creates an empty backup.
|
||||
*/
|
||||
PatchBackup()
|
||||
: buffer(nullptr), bufferSize(0), sourcePtr(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
~PatchBackup() {
|
||||
deleteBackup();
|
||||
}
|
||||
|
||||
/**
|
||||
Destroys the backup and resets internal fields.
|
||||
*/
|
||||
void deleteBackup()
|
||||
{
|
||||
if (buffer) {
|
||||
delete[] buffer;
|
||||
bufferSize = 0;
|
||||
sourcePtr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Reads bytes from the binary to the backup. The source buffer must be within the current process.
|
||||
*/
|
||||
bool makeBackup(BYTE *patch_ptr, size_t patch_size);
|
||||
|
||||
/**
|
||||
Applies the backup back to the pointer from which it was read.
|
||||
*/
|
||||
bool applyBackup();
|
||||
|
||||
/**
|
||||
Checks if the buffer was filled.
|
||||
*/
|
||||
bool isBackup()
|
||||
{
|
||||
return buffer != nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
BYTE *buffer;
|
||||
size_t bufferSize;
|
||||
|
||||
BYTE *sourcePtr;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
A functions resolver that can be used for hooking IAT. Allows for defining functions that are supposed to be replaced.
|
||||
*/
|
||||
class hooking_func_resolver : peconv::default_func_resolver {
|
||||
public:
|
||||
/**
|
||||
Define a function that will be replaced.
|
||||
\param name : a name of the function that will be replaced
|
||||
\param function : an address of the replacement function
|
||||
*/
|
||||
void add_hook(std::string name, FARPROC function)
|
||||
{
|
||||
hooks_map[name] = function;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the address (VA) of the function with the given name, from the given DLL. If the function was hooked, it retrieves the address of the replacement function instead.
|
||||
\param func_name : the name of the function
|
||||
\param lib_name : the name of the DLL
|
||||
\return Virtual Address of the exported function, or the address of the replacement function.
|
||||
*/
|
||||
virtual FARPROC resolve_func(LPSTR lib_name, LPSTR func_name);
|
||||
|
||||
private:
|
||||
std::map<std::string, FARPROC> hooks_map;
|
||||
};
|
||||
|
||||
/**
|
||||
Installs inline hook at the given ptr. Returns the number of bytes overwriten.
|
||||
64 bit version.
|
||||
\param ptr : pointer to the function to be replaced
|
||||
\param new_offset : VA of the new function
|
||||
\param backup : (optional) backup that can be used to reverse the changes
|
||||
\return size of the applied patch
|
||||
*/
|
||||
size_t redirect_to_local64(void *ptr, ULONGLONG new_offset, PatchBackup* backup = nullptr);
|
||||
|
||||
/**
|
||||
Installs inline hook at the given ptr. Returns the number of bytes overwriten.
|
||||
32 bit version.
|
||||
\param ptr : pointer to the function to be replaced
|
||||
\param new_offset : VA of the new function
|
||||
\param backup : (optional) backup that can be used to reverse the changes
|
||||
\return size of the applied patch
|
||||
*/
|
||||
size_t redirect_to_local32(void *ptr, DWORD new_offset, PatchBackup* backup = nullptr);
|
||||
|
||||
/**
|
||||
Installs inline hook at the given ptr. Returns the number of bytes overwriten.
|
||||
Uses bitness of the current applications for the bitness of the intalled hook.
|
||||
\param ptr : pointer to the function to be replaced
|
||||
\param new_function_ptr : pointer to the new function
|
||||
\param backup : (optional) backup that can be used to reverse the changes
|
||||
\return size of the applied patch
|
||||
*/
|
||||
size_t redirect_to_local(void *ptr, void* new_function_ptr, PatchBackup* backup = nullptr);
|
||||
|
||||
/**
|
||||
Replaces a target address of JMP [DWORD] or CALL [DWORD]
|
||||
*/
|
||||
bool replace_target(BYTE *ptr, ULONGLONG dest_addr);
|
||||
|
||||
};//namespace peconv
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Parsing and filling the Import Table.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "pe_hdrs_helper.h"
|
||||
#include "function_resolver.h"
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
A class defining a callback that will be executed when the next imported function was found
|
||||
*/
|
||||
class ImportThunksCallback
|
||||
{
|
||||
public:
|
||||
ImportThunksCallback(BYTE* _modulePtr, size_t _moduleSize)
|
||||
: modulePtr(_modulePtr), moduleSize(_moduleSize)
|
||||
{
|
||||
this->is64b = is64bit((BYTE*)modulePtr);
|
||||
}
|
||||
|
||||
/**
|
||||
A callback that will be executed by process_import_table when the next imported function was found
|
||||
\param libName : the pointer to the DLL name
|
||||
\param origFirstThunkPtr : the pointer to the Original First Thunk
|
||||
\param firstThunkPtr : the pointer to the First Thunk
|
||||
\return : true if processing succeeded, false otherwise
|
||||
*/
|
||||
virtual bool processThunks(LPSTR libName, ULONG_PTR origFirstThunkPtr, ULONG_PTR firstThunkPtr) = 0;
|
||||
|
||||
protected:
|
||||
BYTE* modulePtr;
|
||||
size_t moduleSize;
|
||||
bool is64b;
|
||||
};
|
||||
|
||||
/**
|
||||
Process the given PE's import table and execute the callback each time when the new imported function was found
|
||||
\param modulePtr : a pointer to the loded PE (in virtual format)
|
||||
\param moduleSize : a size of the supplied PE
|
||||
\param callback : a callback that will be executed to process each imported function
|
||||
\return : true if processing succeeded, false otherwise
|
||||
*/
|
||||
bool process_import_table(IN BYTE* modulePtr, IN SIZE_T moduleSize, IN ImportThunksCallback *callback);
|
||||
|
||||
/**
|
||||
Fills imports of the given PE with the help of the defined functions resolver.
|
||||
\param modulePtr : a pointer to the loded PE (in virtual format)
|
||||
\param func_resolver : a resolver that will be used to fill the thunk of the import
|
||||
\return : true if loading all functions succeeded, false otherwise
|
||||
*/
|
||||
bool load_imports(BYTE* modulePtr, t_function_resolver* func_resolver=nullptr);
|
||||
|
||||
/**
|
||||
Checks if the given PE has a valid import table.
|
||||
*/
|
||||
bool has_valid_import_table(const PBYTE modulePtr, size_t moduleSize);
|
||||
|
||||
/**
|
||||
Checks if the given lib_name is a valid DLL name.
|
||||
A valid name must contain printable characters. Empty name is also acceptable (may have been erased).
|
||||
*/
|
||||
bool is_valid_import_name(const PBYTE modulePtr, const size_t moduleSize, LPSTR lib_name);
|
||||
|
||||
}; // namespace peconv
|
||||
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief A definition of ImportsUneraser class - for recovery of a partialy erased Import Table.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#include <iterator>
|
||||
#include "fix_imports.h"
|
||||
#include "caves.h"
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
A class responsible for recovering the partially erased Import Table from the PE.
|
||||
*/
|
||||
class ImportsUneraser
|
||||
{
|
||||
public:
|
||||
ImportsUneraser(PVOID _modulePtr, size_t _moduleSize)
|
||||
: modulePtr((PBYTE)_modulePtr), moduleSize(_moduleSize)
|
||||
{
|
||||
is64 = peconv::is64bit((BYTE*)modulePtr);
|
||||
}
|
||||
|
||||
/**
|
||||
Fill the imported functions' names in the given Import Descriptor, using the given coverage.
|
||||
Collect addressees of functions that couldn't be filled with the given mapping.
|
||||
\param lib_desc : the IMAGE_IMPORT_DESCRIPTOR where the functions' names should be set
|
||||
\param dllCoverage : a mapping associating addresses with the corresponding exports from available DLLs
|
||||
\param not_covered : a set of addresses that could not be found in the supplied mapping
|
||||
\return true if succeeded
|
||||
*/
|
||||
bool uneraseDllImports(IN OUT IMAGE_IMPORT_DESCRIPTOR* lib_desc, IN ImportedDllCoverage &dllCoverage, OUT OPTIONAL ImpsNotCovered* not_covered);
|
||||
|
||||
/**
|
||||
Recover the imported DLL name in the given Import Descriptor, filling it with the given dll_name.
|
||||
*/
|
||||
bool uneraseDllName(IMAGE_IMPORT_DESCRIPTOR* lib_desc, const std::string &dll_name);
|
||||
|
||||
protected:
|
||||
/**
|
||||
Copy the given DLL name into the given IMAGE_IMPORT_DESCRIPTOR. Validates the data correctness before writing.
|
||||
\param lib_desc : the IMAGE_IMPORT_DESCRIPTOR where the DLL name should be set
|
||||
\param dll_name : the DLL name that needs to be written into the lib_desc
|
||||
\return true if succeeded
|
||||
*/
|
||||
bool writeFoundDllName(IMAGE_IMPORT_DESCRIPTOR* lib_desc, const std::string &dll_name);
|
||||
|
||||
/**
|
||||
Fill the names of imported functions with names of the prepared mapping.
|
||||
Collect addressees of functions that couldn't be filled with the given mapping.
|
||||
\param lib_desc : the IMAGE_IMPORT_DESCRIPTOR where the functions' names should be set
|
||||
\param ordinal_flag : the flag that is used to recognize import by ordinal (32 or 64 bit)
|
||||
\param addr_to_func : a mapping assigning functions' addresses to their definitions (names etc.)
|
||||
\param not_covered : a set of addresses that could not be found in the supplied mapping
|
||||
\return true if succeeded
|
||||
*/
|
||||
template <typename FIELD_T, typename IMAGE_THUNK_DATA_T>
|
||||
bool fillImportNames(IN OUT IMAGE_IMPORT_DESCRIPTOR* lib_desc,
|
||||
IN const FIELD_T ordinal_flag,
|
||||
IN std::map<ULONGLONG, std::set<ExportedFunc>> &addr_to_func,
|
||||
OUT OPTIONAL ImpsNotCovered* not_covered
|
||||
);
|
||||
|
||||
template <typename FIELD_T>
|
||||
bool findNameInBinaryAndFill(IMAGE_IMPORT_DESCRIPTOR* lib_desc,
|
||||
LPVOID call_via_ptr,
|
||||
LPVOID thunk_ptr,
|
||||
const FIELD_T ordinal_flag,
|
||||
std::map<ULONGLONG, std::set<ExportedFunc>> &addr_to_func
|
||||
);
|
||||
|
||||
/**
|
||||
Fill the function data into the given IMAGE_THUNK_DATA.
|
||||
\param desc : the poiner to IMAGE_THUNK_DATA that will be filled
|
||||
\param ordinal_flag : an ordinal flag: 32 or 64 bit
|
||||
\param foundFunc : the ExportedFunc that will be used for filling the desc
|
||||
*/
|
||||
template <typename FIELD_T, typename IMAGE_THUNK_DATA_T>
|
||||
bool writeFoundFunction(IMAGE_THUNK_DATA_T* desc, const FIELD_T ordinal_flag, const ExportedFunc &foundFunc);
|
||||
|
||||
PBYTE modulePtr;
|
||||
size_t moduleSize;
|
||||
bool is64;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
|
||||
#include <pshpack4.h>
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_CODE_INTEGRITY: a structure used by IMAGE_LOAD_CONFIG_DIR - the Windows 10 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_CODE_INTEGRITY_W10 {
|
||||
WORD Flags; // Flags to indicate if CI information is available, etc.
|
||||
WORD Catalog; // 0xFFFF means not available
|
||||
DWORD CatalogOffset;
|
||||
DWORD Reserved; // Additional bitmask to be defined later
|
||||
} IMAGE_LOAD_CONFIG_CODE_INTEGRITY_W10;
|
||||
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR32: the Windows 10 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR32_W10 {
|
||||
DWORD Size;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
DWORD GlobalFlagsClear;
|
||||
DWORD GlobalFlagsSet;
|
||||
DWORD CriticalSectionDefaultTimeout;
|
||||
DWORD DeCommitFreeBlockThreshold;
|
||||
DWORD DeCommitTotalFreeThreshold;
|
||||
DWORD LockPrefixTable; // VA
|
||||
DWORD MaximumAllocationSize;
|
||||
DWORD VirtualMemoryThreshold;
|
||||
DWORD ProcessHeapFlags;
|
||||
DWORD ProcessAffinityMask;
|
||||
WORD CSDVersion;
|
||||
WORD DependentLoadFlags;
|
||||
DWORD EditList; // VA
|
||||
DWORD SecurityCookie; // VA
|
||||
DWORD SEHandlerTable; // VA
|
||||
DWORD SEHandlerCount;
|
||||
DWORD GuardCFCheckFunctionPointer; // VA
|
||||
DWORD GuardCFDispatchFunctionPointer; // VA
|
||||
DWORD GuardCFFunctionTable; // VA
|
||||
DWORD GuardCFFunctionCount;
|
||||
DWORD GuardFlags;
|
||||
IMAGE_LOAD_CONFIG_CODE_INTEGRITY_W10 CodeIntegrity;
|
||||
DWORD GuardAddressTakenIatEntryTable; // VA
|
||||
DWORD GuardAddressTakenIatEntryCount;
|
||||
DWORD GuardLongJumpTargetTable; // VA
|
||||
DWORD GuardLongJumpTargetCount;
|
||||
DWORD DynamicValueRelocTable; // VA
|
||||
DWORD CHPEMetadataPointer;
|
||||
DWORD GuardRFFailureRoutine; // VA
|
||||
DWORD GuardRFFailureRoutineFunctionPointer; // VA
|
||||
DWORD DynamicValueRelocTableOffset;
|
||||
WORD DynamicValueRelocTableSection;
|
||||
WORD Reserved2;
|
||||
DWORD GuardRFVerifyStackPointerFunctionPointer; // VA
|
||||
DWORD HotPatchTableOffset;
|
||||
DWORD Reserved3;
|
||||
DWORD EnclaveConfigurationPointer; // VA
|
||||
} IMAGE_LOAD_CONFIG_DIR32_W10;
|
||||
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR64: the Windows 10 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR64_W10 {
|
||||
DWORD Size;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
DWORD GlobalFlagsClear;
|
||||
DWORD GlobalFlagsSet;
|
||||
DWORD CriticalSectionDefaultTimeout;
|
||||
ULONGLONG DeCommitFreeBlockThreshold;
|
||||
ULONGLONG DeCommitTotalFreeThreshold;
|
||||
ULONGLONG LockPrefixTable; // VA
|
||||
ULONGLONG MaximumAllocationSize;
|
||||
ULONGLONG VirtualMemoryThreshold;
|
||||
ULONGLONG ProcessAffinityMask;
|
||||
DWORD ProcessHeapFlags;
|
||||
WORD CSDVersion;
|
||||
WORD DependentLoadFlags;
|
||||
ULONGLONG EditList; // VA
|
||||
ULONGLONG SecurityCookie; // VA
|
||||
ULONGLONG SEHandlerTable; // VA
|
||||
ULONGLONG SEHandlerCount;
|
||||
ULONGLONG GuardCFCheckFunctionPointer; // VA
|
||||
ULONGLONG GuardCFDispatchFunctionPointer; // VA
|
||||
ULONGLONG GuardCFFunctionTable; // VA
|
||||
ULONGLONG GuardCFFunctionCount;
|
||||
DWORD GuardFlags;
|
||||
IMAGE_LOAD_CONFIG_CODE_INTEGRITY_W10 CodeIntegrity;
|
||||
ULONGLONG GuardAddressTakenIatEntryTable; // VA
|
||||
ULONGLONG GuardAddressTakenIatEntryCount;
|
||||
ULONGLONG GuardLongJumpTargetTable; // VA
|
||||
ULONGLONG GuardLongJumpTargetCount;
|
||||
ULONGLONG DynamicValueRelocTable; // VA
|
||||
ULONGLONG CHPEMetadataPointer; // VA
|
||||
ULONGLONG GuardRFFailureRoutine; // VA
|
||||
ULONGLONG GuardRFFailureRoutineFunctionPointer; // VA
|
||||
DWORD DynamicValueRelocTableOffset;
|
||||
WORD DynamicValueRelocTableSection;
|
||||
WORD Reserved2;
|
||||
ULONGLONG GuardRFVerifyStackPointerFunctionPointer; // VA
|
||||
DWORD HotPatchTableOffset;
|
||||
DWORD Reserved3;
|
||||
ULONGLONG EnclaveConfigurationPointer; // VA
|
||||
} IMAGE_LOAD_CONFIG_DIR64_W10;
|
||||
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR32: the Windows 8 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR32_W8 {
|
||||
DWORD Size;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
DWORD GlobalFlagsClear;
|
||||
DWORD GlobalFlagsSet;
|
||||
DWORD CriticalSectionDefaultTimeout;
|
||||
DWORD DeCommitFreeBlockThreshold;
|
||||
DWORD DeCommitTotalFreeThreshold;
|
||||
DWORD LockPrefixTable; // VA
|
||||
DWORD MaximumAllocationSize;
|
||||
DWORD VirtualMemoryThreshold;
|
||||
DWORD ProcessHeapFlags;
|
||||
DWORD ProcessAffinityMask;
|
||||
WORD CSDVersion;
|
||||
WORD DependentLoadFlags;
|
||||
DWORD EditList; // VA
|
||||
DWORD SecurityCookie; // VA
|
||||
DWORD SEHandlerTable; // VA
|
||||
DWORD SEHandlerCount;
|
||||
DWORD GuardCFCheckFunctionPointer; // VA
|
||||
DWORD GuardCFDispatchFunctionPointer; // VA
|
||||
DWORD GuardCFFunctionTable; // VA
|
||||
DWORD GuardCFFunctionCount;
|
||||
DWORD GuardFlags;
|
||||
} IMAGE_LOAD_CONFIG_DIR32_W8;
|
||||
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR64: the Windows 8 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR64_W8 {
|
||||
DWORD Size;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
DWORD GlobalFlagsClear;
|
||||
DWORD GlobalFlagsSet;
|
||||
DWORD CriticalSectionDefaultTimeout;
|
||||
ULONGLONG DeCommitFreeBlockThreshold;
|
||||
ULONGLONG DeCommitTotalFreeThreshold;
|
||||
ULONGLONG LockPrefixTable; // VA
|
||||
ULONGLONG MaximumAllocationSize;
|
||||
ULONGLONG VirtualMemoryThreshold;
|
||||
ULONGLONG ProcessAffinityMask;
|
||||
DWORD ProcessHeapFlags;
|
||||
WORD CSDVersion;
|
||||
WORD DependentLoadFlags;
|
||||
ULONGLONG EditList; // VA
|
||||
ULONGLONG SecurityCookie; // VA
|
||||
ULONGLONG SEHandlerTable; // VA
|
||||
ULONGLONG SEHandlerCount;
|
||||
ULONGLONG GuardCFCheckFunctionPointer; // VA
|
||||
ULONGLONG GuardCFDispatchFunctionPointer; // VA
|
||||
ULONGLONG GuardCFFunctionTable; // VA
|
||||
ULONGLONG GuardCFFunctionCount;
|
||||
DWORD GuardFlags;
|
||||
} IMAGE_LOAD_CONFIG_DIR64_W8;
|
||||
|
||||
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR32: the Windows 7 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR32_W7 {
|
||||
DWORD Size;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
DWORD GlobalFlagsClear;
|
||||
DWORD GlobalFlagsSet;
|
||||
DWORD CriticalSectionDefaultTimeout;
|
||||
DWORD DeCommitFreeBlockThreshold;
|
||||
DWORD DeCommitTotalFreeThreshold;
|
||||
DWORD LockPrefixTable; // VA
|
||||
DWORD MaximumAllocationSize;
|
||||
DWORD VirtualMemoryThreshold;
|
||||
DWORD ProcessHeapFlags;
|
||||
DWORD ProcessAffinityMask;
|
||||
WORD CSDVersion;
|
||||
WORD DependentLoadFlags;
|
||||
DWORD EditList; // VA
|
||||
DWORD SecurityCookie; // VA
|
||||
DWORD SEHandlerTable; // VA
|
||||
DWORD SEHandlerCount;
|
||||
} IMAGE_LOAD_CONFIG_DIR32_W7;
|
||||
|
||||
/**
|
||||
IMAGE_LOAD_CONFIG_DIR64: the Windows 7 version.
|
||||
*/
|
||||
typedef struct _IMAGE_LOAD_CONFIG_DIR64_W7 {
|
||||
DWORD Size;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
DWORD GlobalFlagsClear;
|
||||
DWORD GlobalFlagsSet;
|
||||
DWORD CriticalSectionDefaultTimeout;
|
||||
ULONGLONG DeCommitFreeBlockThreshold;
|
||||
ULONGLONG DeCommitTotalFreeThreshold;
|
||||
ULONGLONG LockPrefixTable; // VA
|
||||
ULONGLONG MaximumAllocationSize;
|
||||
ULONGLONG VirtualMemoryThreshold;
|
||||
ULONGLONG ProcessAffinityMask;
|
||||
DWORD ProcessHeapFlags;
|
||||
WORD CSDVersion;
|
||||
WORD DependentLoadFlags;
|
||||
ULONGLONG EditList; // VA
|
||||
ULONGLONG SecurityCookie; // VA
|
||||
ULONGLONG SEHandlerTable; // VA
|
||||
ULONGLONG SEHandlerCount;
|
||||
} IMAGE_LOAD_CONFIG_DIR64_W7;
|
||||
}; //namespace peconv
|
||||
|
||||
#include <poppack.h>
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Fetching Load Config Directory and recognizing its version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
|
||||
#include "buffer_util.h"
|
||||
#include "load_config_defs.h"
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
A version of Load Config Directory.
|
||||
*/
|
||||
typedef enum {
|
||||
LOAD_CONFIG_NONE = 0, /**< Load Config Directory not found */
|
||||
LOAD_CONFIG_W7_VER = 7, /**< Load Config Directory in the Windows 7 version */
|
||||
LOAD_CONFIG_W8_VER = 8, /**< Load Config Directory in the Windows 8 version */
|
||||
LOAD_CONFIG_W10_VER = 10, /**< Load Config Directory in the Windows 10 version */
|
||||
LOAD_CONFIG_UNK_VER = -1 /**< Load Config Directory in an unknown version */
|
||||
} t_load_config_ver;
|
||||
|
||||
/**
|
||||
Get a pointer to the Load Config Directory within the given PE.
|
||||
\param buffer : a buffer containing the PE file in a Virtual format
|
||||
\param buf_size : size of the buffer
|
||||
\return a pointer to the Load Config Directory, NULL if the given PE does not have this directory
|
||||
*/
|
||||
BYTE* get_load_config_ptr(BYTE* buffer, size_t buf_size);
|
||||
|
||||
/**
|
||||
Detect which version of Load Config Directory was used in the given PE.
|
||||
\param buffer : a buffer containing the PE file in a Virtual format
|
||||
\param buf_size : size of the buffer
|
||||
\param ld_config_ptr : pointer to the Load Config Directory within the given PE
|
||||
\return detected version of Load Config Directory
|
||||
*/
|
||||
t_load_config_ver get_load_config_version(BYTE* buffer, size_t buf_size, BYTE* ld_config_ptr);
|
||||
|
||||
}; // namespace peconv
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Dumping PE from the memory buffer into a file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include "exports_mapper.h"
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
A mode in which the PE fille be dumped.
|
||||
*/
|
||||
typedef enum {
|
||||
PE_DUMP_AUTO = 0, /**< autodetect which dump mode is the most suitable for the given input */
|
||||
PE_DUMP_VIRTUAL,/**< dump as it is in the memory (virtual) */
|
||||
PE_DUMP_UNMAP, /**< convert to the raw format: using raw sections' headers */
|
||||
PE_DUMP_REALIGN, /**< convert to the raw format: by realigning raw sections' headers to be the same as virtual (useful if the PE was unpacked in memory) */
|
||||
PE_DUMP_MODES_COUNT /**< total number of the dump modes */
|
||||
} t_pe_dump_mode;
|
||||
|
||||
/**
|
||||
Detect dump mode that is the most suitable for the given input.
|
||||
\param buffer : the buffer containing the PE to be dumped.
|
||||
\param buffer_size : the size of the given buffer
|
||||
*/
|
||||
t_pe_dump_mode detect_dump_mode(IN const BYTE* buffer, IN size_t buffer_size);
|
||||
|
||||
/**
|
||||
Dumps PE from the fiven buffer into a file. It expects the module base and size to be given.
|
||||
\param outputFilePath : name of the file where the dump should be saved
|
||||
\param buffer : the buffer containing the PE to be dumped. WARNING: the buffer may be preprocessed before dumping.
|
||||
\param buffer_size : the size of the given buffer
|
||||
\param module_base : the base to which the PE buffer was relocated
|
||||
\param dump_mode : specifies in which format the PE should be dumped. If the mode was set to PE_DUMP_AUTO, it autodetects mode and returns the detected one.
|
||||
\param exportsMap : optional. If exportsMap is supplied, it will try to recover destroyed import table of the PE, basing on the supplied map of exported functions.
|
||||
*/
|
||||
bool dump_pe(IN const char *outputFilePath,
|
||||
IN OUT BYTE* buffer,
|
||||
IN size_t buffer_size,
|
||||
IN const ULONGLONG module_base,
|
||||
IN OUT t_pe_dump_mode &dump_mode,
|
||||
IN OPTIONAL const peconv::ExportsMapper* exportsMap = nullptr
|
||||
);
|
||||
|
||||
};// namespace peconv
|
||||
@@ -0,0 +1,232 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Wrappers over various fields in the PE header. Read, write, parse PE headers.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include "buffer_util.h"
|
||||
|
||||
#ifndef PAGE_SIZE
|
||||
#define PAGE_SIZE 0x1000
|
||||
#endif
|
||||
|
||||
#define MASK_TO_DWORD(val) (val & 0xffffffff)
|
||||
#define MASK_TO_WORD(val) (val & 0xffff)
|
||||
|
||||
namespace peconv {
|
||||
/**
|
||||
Maximal size of the PE header.
|
||||
*/
|
||||
const ULONGLONG MAX_HEADER_SIZE = PAGE_SIZE;
|
||||
|
||||
/**
|
||||
Fetch image size from headers.
|
||||
*/
|
||||
DWORD get_image_size(IN const BYTE *payload);
|
||||
|
||||
/**
|
||||
Change the Image Size in Optional Header to the given one.
|
||||
*/
|
||||
bool update_image_size(IN OUT BYTE* payload, IN DWORD new_img_size);
|
||||
|
||||
/**
|
||||
Fetch architecture from the NT headers. Checks for bad pointers.
|
||||
*/
|
||||
WORD get_nt_hdr_architecture(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
Wrapper for get_nt_hdr_architecture. Returns true if the PE file is 64 bit.
|
||||
*/
|
||||
bool is64bit(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
Fetch pointer to the NT headers of the PE file.
|
||||
Checks for bad pointers. If buffer_size is set, validates pointers against the buffer size.
|
||||
*/
|
||||
BYTE* get_nt_hdrs(
|
||||
IN const BYTE *pe_buffer,
|
||||
IN OPTIONAL size_t buffer_size=0 //if buffer_size=0 means size unknown
|
||||
);
|
||||
|
||||
/**
|
||||
Wrapper for get_nt_headers. Automatically detects if the PE is 32 bit - if not, returns null pointer.
|
||||
*/
|
||||
IMAGE_NT_HEADERS32* get_nt_hdrs32(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
Wrapper for get_nt_headers. Automatically detects if the PE is 64 bit - if not, returns null pointer.
|
||||
*/
|
||||
IMAGE_NT_HEADERS64* get_nt_hdrs64(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
Fetches optional header of the PE. Validates pointers against buffer size.
|
||||
*/
|
||||
LPVOID get_optional_hdr(IN const BYTE* payload, IN const size_t buffer_size);
|
||||
|
||||
/**
|
||||
Fetches file header of the PE. Validates pointers against buffer size.
|
||||
*/
|
||||
const IMAGE_FILE_HEADER* get_file_hdr(
|
||||
IN const BYTE* payload,
|
||||
IN const size_t buffer_size
|
||||
);
|
||||
|
||||
/**
|
||||
Fetch the size of headers (from Optional Header).
|
||||
*/
|
||||
DWORD get_hdrs_size(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
get Data Directory entry of the given number. If the entry is not filled and allow_empty is not set, it returns null pointer.
|
||||
*/
|
||||
IMAGE_DATA_DIRECTORY* get_directory_entry(IN const BYTE* pe_buffer, IN DWORD dir_id, IN bool allow_empty = false);
|
||||
|
||||
/**
|
||||
Get pointer to the Data Directory content of the given number. Automatically cast to the chosen type.
|
||||
*/
|
||||
template <typename IMAGE_TYPE_DIRECTORY>
|
||||
IMAGE_TYPE_DIRECTORY* get_type_directory(IN HMODULE modulePtr, IN DWORD dir_id)
|
||||
{
|
||||
IMAGE_DATA_DIRECTORY *my_dir = peconv::get_directory_entry((const BYTE*)modulePtr, dir_id);
|
||||
if (!my_dir) return nullptr;
|
||||
|
||||
DWORD dir_addr = my_dir->VirtualAddress;
|
||||
if (dir_addr == 0) return nullptr;
|
||||
|
||||
return (IMAGE_TYPE_DIRECTORY*)(dir_addr + (ULONG_PTR)modulePtr);
|
||||
}
|
||||
|
||||
/**
|
||||
Get pointer to the Export Directory.
|
||||
*/
|
||||
IMAGE_EXPORT_DIRECTORY* get_export_directory(IN HMODULE modulePtr);
|
||||
|
||||
// Fetch Image Base from Optional Header.
|
||||
ULONGLONG get_image_base(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
Change the Image Base in Optional Header to the given one.
|
||||
*/
|
||||
bool update_image_base(IN OUT BYTE* payload, IN ULONGLONG destImageBase);
|
||||
|
||||
/**
|
||||
Get RVA of the Entry Point from the Optional Header.
|
||||
*/
|
||||
DWORD get_entry_point_rva(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
Change the Entry Point RVA in the Optional Header to the given one.
|
||||
*/
|
||||
bool update_entry_point_rva(IN OUT BYTE *pe_buffer, IN DWORD ep);
|
||||
|
||||
/**
|
||||
Get number of sections from the File Header. It does not validate if this the actual number.
|
||||
*/
|
||||
size_t get_sections_count(
|
||||
IN const BYTE* buffer,
|
||||
IN const size_t buffer_size
|
||||
);
|
||||
|
||||
/**
|
||||
Checks if the section headers are reachable. It does not validate sections alignment.
|
||||
*/
|
||||
bool is_valid_sections_hdr_offset(IN const BYTE* buffer, IN const size_t buffer_size);
|
||||
|
||||
/**
|
||||
Gets pointer to the section header of the given number.
|
||||
*/
|
||||
PIMAGE_SECTION_HEADER get_section_hdr(
|
||||
IN const BYTE* pe_buffer,
|
||||
IN const size_t buffer_size,
|
||||
IN size_t section_num
|
||||
);
|
||||
|
||||
/**
|
||||
Fetch the PE Characteristics from the File Header.
|
||||
*/
|
||||
WORD get_file_characteristics(IN const BYTE* payload);
|
||||
|
||||
/**
|
||||
Check if the module is a DLL (basing on the Characteristcs in the header).
|
||||
*/
|
||||
bool is_module_dll(IN const BYTE* payload);
|
||||
|
||||
/**
|
||||
Fetch the DLL Characteristics from the Optional Header.
|
||||
*/
|
||||
WORD get_dll_characteristics(IN const BYTE* payload);
|
||||
|
||||
/**
|
||||
Set the PE subsystem in the header.
|
||||
*/
|
||||
bool set_subsystem(IN OUT BYTE* payload, IN WORD subsystem);
|
||||
|
||||
/**
|
||||
Get the PE subsystem from the header.
|
||||
*/
|
||||
WORD get_subsystem(IN const BYTE* payload);
|
||||
|
||||
/**
|
||||
Check if the PE has relocations Data Directory.
|
||||
*/
|
||||
bool has_relocations(IN const BYTE *pe_buffer);
|
||||
|
||||
/**
|
||||
Fetch the pointer to the .NET header (if exist).
|
||||
*/
|
||||
IMAGE_COR20_HEADER* get_dotnet_hdr(
|
||||
IN const BYTE* pe_buffer,
|
||||
IN size_t const buffer_size,
|
||||
IN const IMAGE_DATA_DIRECTORY* dotNetDir
|
||||
);
|
||||
|
||||
/**
|
||||
Fetch section aligmenent from headers. Depending on the flag, it fetches either Raw Alignment or Virtual Alignment.
|
||||
*/
|
||||
DWORD get_sec_alignment(IN const BYTE* modulePtr, IN bool is_raw);
|
||||
|
||||
/**
|
||||
Change section aligmenent in headers. Depending on the flag, it sets either Raw Alignment or Virtual Alignment.
|
||||
*/
|
||||
bool set_sec_alignment(IN OUT BYTE* pe_buffer, IN bool is_raw, IN DWORD new_alignment);
|
||||
|
||||
/**
|
||||
Get size of virtual section from the headers (optionaly rounds it up to the Virtual Alignment)
|
||||
*/
|
||||
DWORD get_virtual_sec_size(
|
||||
IN const BYTE* pe_hdr,
|
||||
IN const PIMAGE_SECTION_HEADER sec_hdr,
|
||||
IN bool rounded //if set, it rounds it up to the Virtual Alignment
|
||||
);
|
||||
|
||||
/**
|
||||
Get the last section (in a raw or virtual alignment)
|
||||
\param pe_buffer : buffer with a PE
|
||||
\param pe_size : size of the given PE
|
||||
\param is_raw : If true, give the section with the highest Raw offset. If false, give the section with the highest Virtual offset.
|
||||
*/
|
||||
PIMAGE_SECTION_HEADER get_last_section(IN const PBYTE pe_buffer, IN size_t pe_size, IN bool is_raw);
|
||||
|
||||
/**
|
||||
Calculate full PE size (raw or virtual) using information from sections' headers. WARNING: it drops an overlay.
|
||||
\param pe_buffer : a buffer containing a PE
|
||||
\param pe_size : the size of the given buffer
|
||||
\param is_raw : If true, the Raw alignment is used. If false, the Virtual alignment is used.
|
||||
*/
|
||||
DWORD calc_pe_size(
|
||||
IN const PBYTE pe_buffer,
|
||||
IN size_t pe_size,
|
||||
IN bool is_raw
|
||||
);
|
||||
|
||||
/**
|
||||
Walk through sections headers checking if the sections beginnings and sizes are fitting the alignment (Virtual or Raw)
|
||||
\param buffer : a buffer containing a PE
|
||||
\param buffer_size : the size of the given buffer
|
||||
\param is_raw : If true, the Raw alignment is checked. If false, the Virtual alignment is checked.
|
||||
*/
|
||||
bool is_valid_sectons_alignment(IN const BYTE* buffer, IN const SIZE_T buffer_size, IN bool is_raw);
|
||||
|
||||
}; // namespace peconv
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Loading PE from a file with the help of the custom loader.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pe_raw_to_virtual.h"
|
||||
#include "function_resolver.h"
|
||||
|
||||
namespace peconv {
|
||||
/**
|
||||
Reads PE from the given buffer into memory and maps it into vitual format.
|
||||
(Automatic raw to virtual conversion).
|
||||
If the executable flag is true, the PE file is loaded into executable memory.
|
||||
If the relocate flag is true, applies relocations. Does not load imports.
|
||||
Automatically allocates buffer of the needed size (the size is returned in outputSize). The buffer can be freed by the function free_pe_buffer.
|
||||
*/
|
||||
BYTE* load_pe_module(BYTE* dllRawData, size_t r_size, OUT size_t &v_size, bool executable, bool relocate);
|
||||
|
||||
/**
|
||||
Reads PE from the given file into memory and maps it into vitual format.
|
||||
(Automatic raw to virtual conversion).
|
||||
If the executable flag is true, the PE file is loaded into executable memory.
|
||||
If the relocate flag is true, applies relocations. Does not load imports.
|
||||
Automatically allocates buffer of the needed size (the size is returned in outputSize). The buffer can be freed by the function free_pe_buffer.
|
||||
*/
|
||||
BYTE* load_pe_module(const char *filename, OUT size_t &v_size, bool executable, bool relocate);
|
||||
|
||||
/**
|
||||
Loads full PE from the raw buffer in a way in which it can be directly executed: remaps to virual format, applies relocations, loads imports.
|
||||
Allows for supplying custom function resolver.
|
||||
*/
|
||||
BYTE* load_pe_executable(BYTE* dllRawData, size_t r_size, OUT size_t &v_size, t_function_resolver* import_resolver=NULL);
|
||||
|
||||
/**
|
||||
Loads full PE from file in a way in which it can be directly executed: remaps to virual format, applies relocations, loads imports.
|
||||
Allows for supplying custom function resolver.
|
||||
*/
|
||||
BYTE* load_pe_executable(const char *filename, OUT size_t &v_size, t_function_resolver* import_resolver=NULL);
|
||||
|
||||
};// namespace peconv
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Detecting in which mode is the PE in the supplied buffer (i.e. raw, virtual). Analyzes PE features typical for particular modes.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "pe_hdrs_helper.h"
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
check if the PE in the memory is in raw format
|
||||
*/
|
||||
bool is_pe_raw(
|
||||
IN const BYTE* pe_buffer,
|
||||
IN size_t pe_size
|
||||
);
|
||||
|
||||
/**
|
||||
check if Virtual section addresses are identical to Raw addresses (i.e. if the PE was realigned)
|
||||
*/
|
||||
bool is_pe_raw_eq_virtual(
|
||||
IN const BYTE* pe_buffer,
|
||||
IN size_t pe_size
|
||||
);
|
||||
|
||||
/**
|
||||
checks if the PE has sections that were unpacked/expanded in the memory
|
||||
*/
|
||||
bool is_pe_expanded(
|
||||
IN const BYTE* pe_buffer,
|
||||
IN size_t pe_size
|
||||
);
|
||||
|
||||
/**
|
||||
checks if the given section was unpacked in the memory
|
||||
*/
|
||||
bool is_section_expanded(IN const BYTE* pe_buffer,
|
||||
IN size_t pe_size,
|
||||
IN const PIMAGE_SECTION_HEADER sec
|
||||
);
|
||||
|
||||
};// namespace peconv
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Converting PE from raw to virtual format.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "buffer_util.h"
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
Converts a raw PE supplied in a buffer to a virtual format.
|
||||
If the executable flag is true (default), the PE file is loaded into executable memory.
|
||||
Does not apply relocations. Does not load imports.
|
||||
Automatically allocates buffer of the needed size (the size is returned in outputSize). The buffer can be freed by the function free_pe_module.
|
||||
If the desired_base is defined (0 by default), it enforces allocation at the particular base.
|
||||
*/
|
||||
BYTE* pe_raw_to_virtual(
|
||||
IN const BYTE* rawPeBuffer,
|
||||
IN size_t rawPeSize,
|
||||
OUT size_t &outputSize,
|
||||
IN OPTIONAL bool executable = true,
|
||||
IN OPTIONAL ULONGLONG desired_base = 0
|
||||
);
|
||||
|
||||
}; // namespace peconv
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Converting PE from virtual to raw format.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "buffer_util.h"
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
Maps virtual image of PE to into raw. Automaticaly applies relocations.
|
||||
Automatically allocates buffer of the needed size (the size is returned in outputSize).
|
||||
\param payload : the PE in the Virtual format that needs to be converted into the Raw format
|
||||
\param in_size : size of the input buffer (the PE in the Virtual format)
|
||||
\param loadBase : the base to which the given PE was relocated
|
||||
\param outputSize : the size of the output buffer (the PE in the Raw format)
|
||||
\param rebuffer : if set (default), the input buffer is rebuffered and the original buffer is not modified.
|
||||
\return a buffer of the outputSize, containing the Raw PE. The buffer can be freed by the function free_pe_module.
|
||||
*/
|
||||
BYTE* pe_virtual_to_raw(
|
||||
IN BYTE* payload,
|
||||
IN size_t in_size,
|
||||
IN ULONGLONG loadBase,
|
||||
OUT size_t &outputSize,
|
||||
IN OPTIONAL bool rebuffer=true
|
||||
);
|
||||
|
||||
/*
|
||||
Modifies raw alignment of the PE to be the same as virtual alignment.
|
||||
\param payload : the PE in the Virtual format that needs to be realigned
|
||||
\param in_size : size of the input buffer
|
||||
\param loadBase : the base to which the given PE was relocated
|
||||
\param outputSize : the size of the output buffer (the PE in the Raw format)
|
||||
\return a buffer of the outputSize, containing the realigned PE. The buffer can be freed by the function free_pe_module.
|
||||
*/
|
||||
BYTE* pe_realign_raw_to_virtual(
|
||||
IN const BYTE* payload,
|
||||
IN size_t in_size,
|
||||
IN ULONGLONG loadBase,
|
||||
OUT size_t &outputSize
|
||||
);
|
||||
|
||||
};//namespace peconv
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Functions for retrieving process information from PEB.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace peconv {
|
||||
|
||||
/**
|
||||
Gets handle to the given module via PEB. A low-level equivalent of `GetModuleHandleW`.
|
||||
\param module_name : (optional) the name of the DLL loaded within the current process. If not set, the main module of the current process is used.
|
||||
\return the handle of the DLL with given name, or, if the name was not given, the handle of the main module of the current process.
|
||||
*/
|
||||
HMODULE get_module_via_peb(IN OPTIONAL LPWSTR module_name = nullptr);
|
||||
|
||||
|
||||
/**
|
||||
Gets size of the given module via PEB.
|
||||
\param hModule : (optional) the base of the module which's size we want to retrieve. If not set, the main module of the current process is used.
|
||||
\return the size of the given module.
|
||||
*/
|
||||
size_t get_module_size_via_peb(IN OPTIONAL HMODULE hModule = nullptr);
|
||||
|
||||
/**
|
||||
Sets the given module as the main module in the current PEB.
|
||||
\param hModule : the module to be connected to the current PEB.
|
||||
\return true if succeeded, false if failed
|
||||
*/
|
||||
bool set_main_module_in_peb(HMODULE hModule);
|
||||
|
||||
/**
|
||||
Gets the main module from the current PEB.
|
||||
\return the main module connected to the current PEB.
|
||||
*/
|
||||
HMODULE get_main_module_via_peb();
|
||||
};
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Operating on PE file's relocations table.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace peconv {
|
||||
|
||||
typedef struct _BASE_RELOCATION_ENTRY {
|
||||
WORD Offset : 12;
|
||||
WORD Type : 4;
|
||||
} BASE_RELOCATION_ENTRY;
|
||||
|
||||
class RelocBlockCallback
|
||||
{
|
||||
public:
|
||||
RelocBlockCallback(bool _is64bit)
|
||||
: is64bit(_is64bit)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool processRelocField(ULONG_PTR relocField) = 0;
|
||||
|
||||
protected:
|
||||
bool is64bit;
|
||||
};
|
||||
|
||||
// Processs the relocation table and make your own callback on each relocation field
|
||||
bool process_relocation_table(IN PVOID modulePtr, IN SIZE_T moduleSize, IN RelocBlockCallback *callback);
|
||||
|
||||
/**
|
||||
Applies relocations on the PE in virtual format. Relocates it from the old base given to the new base given.
|
||||
If 0 was supplied as the old base, it assumes that the old base is the ImageBase given in the header.
|
||||
\param modulePtr : a buffer containing the PE to be relocated
|
||||
\param moduleSize : the size of the given PE buffer
|
||||
\param newBase : a base to which the PE should be relocated
|
||||
\param oldBase : a base to which the PE is currently relocated (if not set, the imageBase from the header will be used)
|
||||
*/
|
||||
bool relocate_module(IN BYTE* modulePtr, IN SIZE_T moduleSize, IN ULONGLONG newBase, IN ULONGLONG oldBase = 0);
|
||||
|
||||
/**
|
||||
Checks if the given PE has a valid relocations table.
|
||||
\param modulePtr : a buffer containing the PE to be checked
|
||||
\param moduleSize : the size of the given PE buffer
|
||||
*/
|
||||
bool has_valid_relocation_table(IN const PBYTE modulePtr, IN const size_t moduleSize);
|
||||
|
||||
};//namespace peconv
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Reading from a PE module that is loaded within a remote process.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "pe_hdrs_helper.h"
|
||||
#include "pe_virtual_to_raw.h"
|
||||
#include "exports_mapper.h"
|
||||
#include "pe_dumper.h"
|
||||
|
||||
namespace peconv {
|
||||
|
||||
bool fetch_region_info(HANDLE processHandle, BYTE* start_addr, MEMORY_BASIC_INFORMATION &page_info);
|
||||
|
||||
/**
|
||||
Fetch size of the memory region starting from the given address.
|
||||
*/
|
||||
size_t fetch_region_size(HANDLE processHandle, BYTE* start_addr);
|
||||
|
||||
/**
|
||||
Fetch the allocation base of the memory region with the supplied start address.
|
||||
\param processHandle : handle of the process where the region of interest belongs
|
||||
\param start_addr : the address inside the region of interest
|
||||
\return the allocation base address of the memory region, or 0 if not found
|
||||
*/
|
||||
ULONGLONG fetch_alloc_base(HANDLE processHandle, BYTE* start_addr);
|
||||
|
||||
/**
|
||||
Wrapper over ReadProcessMemory. Requires a handle with privilege PROCESS_VM_READ.
|
||||
If reading full buffer_size was not possible, it will keep trying to read smaller chunk,
|
||||
decreasing requested size by step_size in each iteration. Returns how many bytes were successfuly read.
|
||||
It is a workaround for errors such as FAULTY_HARDWARE_CORRUPTED_PAGE.
|
||||
*/
|
||||
size_t read_remote_memory(HANDLE processHandle, BYTE *start_addr, OUT BYTE* buffer, const size_t buffer_size, const SIZE_T step_size = 0x100);
|
||||
|
||||
/**
|
||||
Reads the full memory area of a given size within a given process, skipping inaccessible pages.
|
||||
Requires a handle with privilege PROCESS_QUERY_INFORMATION.
|
||||
step_size is passed to the underlying read_remote_memory.
|
||||
*/
|
||||
size_t read_remote_area(HANDLE processHandle, BYTE *start_addr, OUT BYTE* buffer, const size_t buffer_size, const SIZE_T step_size = 0x100);
|
||||
|
||||
/**
|
||||
Reads a PE header of the remote module within the given process. Requires a valid output buffer to be supplied (buffer).
|
||||
*/
|
||||
bool read_remote_pe_header(HANDLE processHandle, BYTE *moduleBase, OUT BYTE* buffer, const size_t bufferSize);
|
||||
|
||||
/**
|
||||
Reads a PE section with a given number (sectionNum) from the remote module within the given process.
|
||||
The buffer of appropriate size is automatically allocated. After use, it should be freed by the function free_unaligned.
|
||||
The size of the buffer is writen into sectionSize.
|
||||
\param processHandle : the handle to the remote process
|
||||
\param moduleBase : the base address of the module
|
||||
\param sectionNum : number of the section to be read
|
||||
\param sectionSize : the size of the read section (output)
|
||||
\param roundup : if set, the section size is roundup to the alignment unit
|
||||
\return a buffer containing a copy of the section.
|
||||
*/
|
||||
peconv::UNALIGNED_BUF get_remote_pe_section(HANDLE processHandle, BYTE *moduleBase, const size_t sectionNum, OUT size_t §ionSize, bool roundup = false);
|
||||
|
||||
/**
|
||||
Reads PE file from the remote process into the supplied buffer. It expects the module base and size to be given.
|
||||
*/
|
||||
size_t read_remote_pe(const HANDLE processHandle, BYTE *moduleBase, const size_t moduleSize, OUT BYTE* buffer, const size_t bufferSize);
|
||||
|
||||
/**
|
||||
Dumps PE from the remote process into a file. It expects the module base and size to be given.
|
||||
\param outputFilePath : the path where the dump will be saved
|
||||
\param processHandle : the handle to the remote process
|
||||
\param moduleBase : the base address of the module that needs to be dumped
|
||||
\param dump_mode : specifies in which format the PE should be dumped. If the mode was set to PE_DUMP_AUTO, it autodetects mode and returns the detected one.
|
||||
\param exportsMap : optional. If exportsMap is supplied, it will try to recover destroyed import table of the PE, basing on the supplied map of exported functions.
|
||||
*/
|
||||
bool dump_remote_pe(
|
||||
IN const char *outputFilePath,
|
||||
IN const HANDLE processHandle,
|
||||
IN BYTE *moduleBase,
|
||||
IN OUT t_pe_dump_mode &dump_mode,
|
||||
IN OPTIONAL peconv::ExportsMapper* exportsMap = nullptr
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieve the Image Size saved in the header of the remote PE.
|
||||
\param processHandle : process from where we are reading
|
||||
\param start_addr : a base address of the PE within the given process
|
||||
*/
|
||||
DWORD get_remote_image_size(IN const HANDLE processHandle, IN BYTE *start_addr);
|
||||
|
||||
}; //namespace peconv
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Parsing PE's resource directory.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
|
||||
namespace peconv {
|
||||
/**
|
||||
A callback that will be executed by the function parse_resources when the Resource Entry was found.
|
||||
*/
|
||||
typedef bool(*t_on_res_entry_found) (
|
||||
BYTE* modulePtr,
|
||||
IMAGE_RESOURCE_DIRECTORY_ENTRY *root_dir,
|
||||
IMAGE_RESOURCE_DATA_ENTRY *curr_entry
|
||||
);
|
||||
|
||||
/**
|
||||
A function walking through the Resource Tree of the given PE. On each Resource Entry found, the callback is executed.
|
||||
\param modulePtr : pointer to the buffer with the PE in a Virtual format
|
||||
\param on_entry : a callback function executed on each Resource Entry
|
||||
*/
|
||||
bool parse_resources(BYTE* modulePtr, t_on_res_entry_found on_entry);
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Functions related to manual retrieving of PE resources.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include "buffer_util.h"
|
||||
|
||||
namespace peconv {
|
||||
|
||||
const LPSTR RT_RCDATA_A = MAKEINTRESOURCEA(10);
|
||||
|
||||
/**
|
||||
Maps a resource with the given id + type and copies its raw content into the output buffer.
|
||||
If out_size is not zero, it reads maximum out_size of bytes. If out_size is zero, it reads the full resource.
|
||||
The actual read size is returned back in out_size.
|
||||
Automatically allocates a buffer of the required size.
|
||||
If hInstance is NULL, it search the resource in the current module. Otherwise, it search in the given module.
|
||||
*/
|
||||
peconv::ALIGNED_BUF load_resource_data(OUT size_t &out_size, const int res_id, const LPSTR res_type = RT_RCDATA_A, HMODULE hInstance = nullptr);
|
||||
|
||||
/**
|
||||
Free the buffer with PE Resources, mapped by the function load_resource_data.
|
||||
*/
|
||||
void free_resource_data(peconv::ALIGNED_BUF buffer);
|
||||
|
||||
/**
|
||||
a helper function to get the module handle of the current DLL
|
||||
*/
|
||||
HMODULE get_current_module_handle();
|
||||
|
||||
}; //namespace peconv
|
||||
25
ai_anti_malware/libpeconv/libpeconv/include/peconv/util.h
Normal file
25
ai_anti_malware/libpeconv/libpeconv/include/peconv/util.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Miscellaneous utility functions.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "file_util.h"
|
||||
#include "resource_util.h"
|
||||
|
||||
namespace peconv {
|
||||
/**
|
||||
Checks if the given buffer is fully filled with the specified character.
|
||||
\param cave_ptr : pointer to the buffer to be checked
|
||||
\param cave_size : size of the buffer to be checked
|
||||
\param padding_char : the required character
|
||||
*/
|
||||
bool is_padding(const BYTE *cave_ptr, size_t cave_size, const BYTE padding_char);
|
||||
|
||||
/**
|
||||
Wrapper for GetProcessId - for a backward compatibility with old versions of Windows
|
||||
*/
|
||||
DWORD get_process_id(HANDLE hProcess);
|
||||
};
|
||||
|
||||
87
ai_anti_malware/libpeconv/libpeconv/src/buffer_util.cpp
Normal file
87
ai_anti_malware/libpeconv/libpeconv/src/buffer_util.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "peconv/buffer_util.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
//
|
||||
// validate pointer:
|
||||
//
|
||||
|
||||
bool peconv::validate_ptr(IN const void* buffer_bgn, IN SIZE_T buffer_size, IN const void* field_bgn, IN SIZE_T field_size)
|
||||
{
|
||||
if (buffer_bgn == nullptr || field_bgn == nullptr) {
|
||||
return false;
|
||||
}
|
||||
BYTE* _start = (BYTE*)buffer_bgn;
|
||||
BYTE* _end = _start + buffer_size;
|
||||
|
||||
BYTE* _field_start = (BYTE*)field_bgn;
|
||||
BYTE* _field_end = (BYTE*)field_bgn + field_size;
|
||||
|
||||
if (_field_start < _start) {
|
||||
return false;
|
||||
}
|
||||
if (_field_end > _end) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// alloc/free unaligned buffers:
|
||||
//
|
||||
|
||||
//allocates a buffer that does not have to start from the beginning of the section
|
||||
peconv::UNALIGNED_BUF peconv::alloc_unaligned(size_t buf_size)
|
||||
{
|
||||
if (!buf_size) return NULL;
|
||||
|
||||
UNALIGNED_BUF buf = (UNALIGNED_BUF) calloc(buf_size, sizeof(BYTE));
|
||||
return buf;
|
||||
}
|
||||
|
||||
void peconv::free_unaligned(peconv::UNALIGNED_BUF section_buffer)
|
||||
{
|
||||
free(section_buffer);
|
||||
}
|
||||
|
||||
//
|
||||
// alloc/free aligned buffers:
|
||||
//
|
||||
|
||||
peconv::ALIGNED_BUF peconv::alloc_aligned(size_t buffer_size, DWORD protect, ULONGLONG desired_base, bool is_x64)
|
||||
{
|
||||
if (!buffer_size) return NULL;
|
||||
ALIGNED_BUF buf = (ALIGNED_BUF)VirtualAlloc((LPVOID)desired_base, buffer_size, MEM_COMMIT | MEM_RESERVE, protect);
|
||||
return buf;
|
||||
}
|
||||
|
||||
bool peconv::free_aligned(peconv::ALIGNED_BUF buffer, size_t buffer_size)
|
||||
{
|
||||
if (buffer == nullptr) return true;
|
||||
if (!VirtualFree(buffer, 0, MEM_RELEASE)) {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Releasing failed" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// wrappers using appropriate buffer type according to the purpose:
|
||||
//
|
||||
|
||||
// allocate a buffer for PE module:
|
||||
peconv::ALIGNED_BUF peconv::alloc_pe_buffer(size_t buffer_size, DWORD protect, ULONGLONG desired_base)
|
||||
{
|
||||
return alloc_aligned(buffer_size, protect, desired_base);
|
||||
}
|
||||
|
||||
// Free loaded PE module
|
||||
bool peconv::free_pe_buffer(peconv::ALIGNED_BUF buffer, size_t buffer_size)
|
||||
{
|
||||
return peconv::free_aligned(buffer, buffer_size);
|
||||
}
|
||||
|
||||
139
ai_anti_malware/libpeconv/libpeconv/src/caves.cpp
Normal file
139
ai_anti_malware/libpeconv/libpeconv/src/caves.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
#include "peconv/caves.h"
|
||||
#include "peconv/pe_hdrs_helper.h"
|
||||
#include "peconv/util.h"
|
||||
|
||||
using namespace peconv;
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
PBYTE peconv::find_ending_cave(BYTE*modulePtr, size_t moduleSize, const DWORD minimal_size, const DWORD req_charact)
|
||||
{
|
||||
size_t sec_count = peconv::get_sections_count(modulePtr, moduleSize);
|
||||
if (sec_count == 0) return nullptr;
|
||||
|
||||
size_t last_sec = sec_count - 1;
|
||||
PIMAGE_SECTION_HEADER section_hdr = peconv::get_section_hdr(modulePtr, moduleSize, last_sec);
|
||||
if (section_hdr == nullptr) return nullptr;
|
||||
if (!(section_hdr->Characteristics & req_charact)) return nullptr;
|
||||
|
||||
DWORD raw_size = section_hdr->SizeOfRawData;
|
||||
DWORD virtual_size = (DWORD)moduleSize - section_hdr->VirtualAddress;
|
||||
|
||||
if (raw_size >= virtual_size) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Last section's raw_size: " << std::hex << raw_size << " >= virtual_size: " << virtual_size << std::endl;
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
DWORD cave_size = virtual_size - raw_size;
|
||||
if (cave_size < minimal_size) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Cave is too small" << std::endl;
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
PBYTE cave_ptr = modulePtr + section_hdr->VirtualAddress + section_hdr->SizeOfRawData;
|
||||
if (!validate_ptr(modulePtr, moduleSize, cave_ptr, minimal_size)) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Invalid cave pointer" << std::endl;
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
section_hdr->SizeOfRawData += minimal_size; //book this cave
|
||||
return cave_ptr;
|
||||
}
|
||||
|
||||
PBYTE peconv::find_alignment_cave(BYTE* modulePtr, size_t moduleSize, const DWORD minimal_size, const DWORD req_charact)
|
||||
{
|
||||
DWORD alignment = peconv::get_sec_alignment(modulePtr, true);
|
||||
if (alignment == 0) return nullptr;
|
||||
|
||||
size_t sec_count = peconv::get_sections_count(modulePtr, moduleSize);
|
||||
for (size_t i = 0; i < sec_count; i++) {
|
||||
PIMAGE_SECTION_HEADER section_hdr = peconv::get_section_hdr(modulePtr, moduleSize, i);
|
||||
if (section_hdr == nullptr) continue;
|
||||
if (!(section_hdr->Characteristics & req_charact)) continue;
|
||||
|
||||
DWORD rem = section_hdr->SizeOfRawData % alignment;
|
||||
if (rem == 0) continue;
|
||||
|
||||
DWORD div = (section_hdr->SizeOfRawData / alignment) + 1;
|
||||
DWORD new_size = div * alignment;
|
||||
DWORD cave_size = new_size - section_hdr->SizeOfRawData;
|
||||
if (cave_size < minimal_size) {
|
||||
#ifdef __DEBUG
|
||||
std::cout << "Cave is too small" << std::endl;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
DWORD sec_start = section_hdr->PointerToRawData;
|
||||
if (sec_start == 0) continue;
|
||||
|
||||
DWORD sec_end = sec_start + section_hdr->SizeOfRawData;
|
||||
#ifdef _DEBUG
|
||||
std::cout << "section: " << std::hex << sec_start << " : " << sec_end << std::endl;
|
||||
#endif
|
||||
PBYTE cave_ptr = modulePtr + sec_end;
|
||||
if (!validate_ptr(modulePtr, moduleSize, cave_ptr, minimal_size)) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Invalid cave pointer" << std::endl;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
section_hdr->SizeOfRawData += minimal_size; //book this cave
|
||||
return cave_ptr;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Cave not found" << std::endl;
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PBYTE peconv::find_padding_cave(BYTE* modulePtr, size_t moduleSize, const size_t minimal_size, const DWORD req_charact)
|
||||
{
|
||||
size_t sec_count = peconv::get_sections_count(modulePtr, moduleSize);
|
||||
for (size_t i = 0; i < sec_count; i++) {
|
||||
PIMAGE_SECTION_HEADER section_hdr = peconv::get_section_hdr(modulePtr, moduleSize, i);
|
||||
if (section_hdr == nullptr) continue;
|
||||
if (!(section_hdr->Characteristics & req_charact)) continue;
|
||||
|
||||
if (section_hdr->SizeOfRawData < minimal_size) continue;
|
||||
|
||||
// we will be searching in the loaded, virtual image:
|
||||
DWORD sec_start = section_hdr->VirtualAddress;
|
||||
if (sec_start == 0) continue;
|
||||
|
||||
DWORD sec_end = sec_start + section_hdr->SizeOfRawData;
|
||||
#ifdef _DEBUG
|
||||
std::cout << "section: " << std::hex << sec_start << " : " << sec_end << std::endl;
|
||||
#endif
|
||||
//offset from the end of the section:
|
||||
size_t cave_offset = section_hdr->SizeOfRawData - minimal_size;
|
||||
PBYTE cave_ptr = modulePtr + sec_start + cave_offset;
|
||||
if (!validate_ptr(modulePtr, moduleSize, cave_ptr, minimal_size)) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Invalid cave pointer" << std::endl;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
bool found = false;
|
||||
if (is_padding(cave_ptr, minimal_size, 0)) {
|
||||
found = true;
|
||||
}
|
||||
//if the section is code, check also code padding:
|
||||
if (section_hdr->Characteristics & IMAGE_SCN_MEM_EXECUTE) {
|
||||
if (is_padding(cave_ptr, minimal_size, 0xCC)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
return cave_ptr;
|
||||
}
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Cave not found" << std::endl;
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
#include "peconv/delayed_imports_loader.h"
|
||||
#include "peconv/imports_loader.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
IMAGE_DELAYLOAD_DESCRIPTOR* peconv::get_delayed_imps(IN const BYTE* modulePtr, IN const size_t moduleSize, OUT size_t &dir_size)
|
||||
{
|
||||
dir_size = 0;
|
||||
IMAGE_DATA_DIRECTORY *d_imps_dir = peconv::get_directory_entry(modulePtr, IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT);
|
||||
if (!d_imps_dir) {
|
||||
return nullptr;
|
||||
}
|
||||
BYTE* dimps_table = (BYTE*)((ULONGLONG) modulePtr + d_imps_dir->VirtualAddress);
|
||||
const size_t min_size = sizeof(IMAGE_DELAYLOAD_DESCRIPTOR);
|
||||
if (d_imps_dir->Size < min_size) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!peconv::validate_ptr((LPVOID)modulePtr, moduleSize, dimps_table, min_size)) {
|
||||
return nullptr;
|
||||
}
|
||||
dir_size = d_imps_dir->Size;
|
||||
return reinterpret_cast<IMAGE_DELAYLOAD_DESCRIPTOR*> (dimps_table);
|
||||
}
|
||||
|
||||
template <typename T_FIELD, typename T_IMAGE_THUNK_DATA>
|
||||
bool parse_delayed_desc(BYTE* modulePtr, const size_t moduleSize,
|
||||
const ULONGLONG img_base,
|
||||
LPSTR lib_name,
|
||||
const T_FIELD ordinal_flag,
|
||||
IMAGE_DELAYLOAD_DESCRIPTOR *desc,
|
||||
peconv::t_function_resolver* func_resolver
|
||||
)
|
||||
{
|
||||
ULONGLONG iat_addr = desc->ImportAddressTableRVA;
|
||||
|
||||
if (iat_addr > img_base) iat_addr -= img_base; // it may be either RVA or VA
|
||||
|
||||
ULONGLONG thunk_addr = desc->ImportNameTableRVA;
|
||||
if (thunk_addr > img_base) thunk_addr -= img_base; // it may be either RVA or VA
|
||||
|
||||
T_FIELD* record_va = (T_FIELD*)((ULONGLONG)modulePtr + iat_addr);
|
||||
T_IMAGE_THUNK_DATA* thunk_va = (T_IMAGE_THUNK_DATA*)((ULONGLONG)modulePtr + thunk_addr);
|
||||
|
||||
for (; *record_va != NULL && thunk_va != NULL; record_va++, thunk_va++) {
|
||||
if (!peconv::validate_ptr(modulePtr, moduleSize, record_va, sizeof(T_FIELD))) {
|
||||
return false;
|
||||
}
|
||||
if (!peconv::validate_ptr(modulePtr, moduleSize, thunk_va, sizeof(T_FIELD))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
T_FIELD iat_va = *record_va;
|
||||
ULONGLONG iat_rva = (ULONGLONG)iat_va;
|
||||
if (iat_va > img_base) iat_rva -= img_base; // it may be either RVA or VA
|
||||
#ifdef _DEBUG
|
||||
std::cout << std::hex << iat_rva << " : ";
|
||||
#endif
|
||||
T_FIELD* iat_record_ptr = (T_FIELD*)((ULONGLONG)modulePtr + iat_rva);
|
||||
if (!peconv::validate_ptr(modulePtr, moduleSize, iat_record_ptr, sizeof(T_FIELD))) {
|
||||
return false;
|
||||
}
|
||||
FARPROC hProc = nullptr;
|
||||
if (thunk_va->u1.Ordinal & ordinal_flag) {
|
||||
T_FIELD raw_ordinal = thunk_va->u1.Ordinal & (~ordinal_flag);
|
||||
#ifdef _DEBUG
|
||||
std::cout << std::hex << "ord: " << raw_ordinal << " ";
|
||||
#endif
|
||||
hProc = func_resolver->resolve_func(lib_name, MAKEINTRESOURCEA(raw_ordinal));
|
||||
}
|
||||
else {
|
||||
ULONGLONG name_rva = thunk_va->u1.AddressOfData;
|
||||
if (name_rva > img_base) {
|
||||
name_rva -= img_base;
|
||||
}
|
||||
PIMAGE_IMPORT_BY_NAME by_name = (PIMAGE_IMPORT_BY_NAME)((ULONGLONG)modulePtr + name_rva);
|
||||
LPSTR func_name = reinterpret_cast<LPSTR>(by_name->Name);
|
||||
if (!peconv::is_valid_import_name(modulePtr, moduleSize, func_name)) {
|
||||
continue;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << func_name << " ";
|
||||
#endif
|
||||
hProc = func_resolver->resolve_func(lib_name, func_name);
|
||||
}
|
||||
if (hProc) {
|
||||
//rather than loading it via proxy function, we just overwrite the thunk like normal IAT:
|
||||
*record_va = (T_FIELD) hProc;
|
||||
#ifdef _DEBUG
|
||||
std::cout << "[OK]\n";
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "[NOPE]\n";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool peconv::load_delayed_imports(BYTE* modulePtr, ULONGLONG moduleBase, t_function_resolver* func_resolver)
|
||||
{
|
||||
const bool is_64bit = peconv::is64bit(modulePtr);
|
||||
const size_t module_size = peconv::get_image_size(modulePtr);
|
||||
default_func_resolver default_res;
|
||||
if (!func_resolver) {
|
||||
func_resolver = (t_function_resolver*)&default_res;
|
||||
}
|
||||
size_t table_size = 0;
|
||||
IMAGE_DELAYLOAD_DESCRIPTOR* first_desc = get_delayed_imps(modulePtr, module_size, table_size);
|
||||
if (!first_desc) {
|
||||
return false;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << "OK, table_size = " << table_size << std::endl;
|
||||
#endif
|
||||
size_t max_count = table_size / sizeof(IMAGE_DELAYLOAD_DESCRIPTOR);
|
||||
for (size_t i = 0; i < max_count; i++) {
|
||||
IMAGE_DELAYLOAD_DESCRIPTOR* desc = &first_desc[i];
|
||||
if (!validate_ptr(modulePtr, module_size, desc, sizeof(IMAGE_DELAYLOAD_DESCRIPTOR))) break;
|
||||
if (desc->DllNameRVA == NULL) {
|
||||
break;
|
||||
}
|
||||
ULONGLONG dll_name_rva = desc->DllNameRVA;
|
||||
if (dll_name_rva > moduleBase) {
|
||||
dll_name_rva -= moduleBase;
|
||||
}
|
||||
char* dll_name = (char*)((ULONGLONG)modulePtr + dll_name_rva);
|
||||
if (!validate_ptr(modulePtr, module_size, dll_name, sizeof(char))) continue;
|
||||
#ifdef _DEBUG
|
||||
std::cout << dll_name << std::endl;
|
||||
#endif
|
||||
if (is_64bit) {
|
||||
return parse_delayed_desc<ULONGLONG, IMAGE_THUNK_DATA64>(modulePtr, module_size, moduleBase, dll_name, IMAGE_ORDINAL_FLAG64, desc, func_resolver);
|
||||
}
|
||||
else {
|
||||
return parse_delayed_desc<DWORD, IMAGE_THUNK_DATA32>(modulePtr, module_size, moduleBase, dll_name, IMAGE_ORDINAL_FLAG32, desc, func_resolver);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
bool peconv::load_delayed_imports(BYTE* modulePtr, ULONGLONG moduleBase, t_function_resolver* func_resolver)
|
||||
{
|
||||
const bool is_64bit = peconv::is64bit(modulePtr);
|
||||
bool is_loader64 = false;
|
||||
#ifdef _WIN64
|
||||
is_loader64 = true;
|
||||
#endif
|
||||
if (is_64bit != is_loader64) {
|
||||
std::cerr << "[ERROR] Loader/Payload bitness mismatch.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t module_size = peconv::get_image_size(modulePtr);
|
||||
default_func_resolver default_res;
|
||||
if (!func_resolver) {
|
||||
func_resolver = (t_function_resolver*)&default_res;
|
||||
}
|
||||
size_t table_size = 0;
|
||||
IMAGE_DELAYLOAD_DESCRIPTOR *first_desc = get_delayed_imps(modulePtr, module_size, table_size);
|
||||
if (!first_desc) {
|
||||
return false;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << "OK, table_size = " << table_size << std::endl;
|
||||
#endif
|
||||
size_t max_count = table_size / sizeof(IMAGE_DELAYLOAD_DESCRIPTOR);
|
||||
for (size_t i = 0; i < max_count; i++) {
|
||||
IMAGE_DELAYLOAD_DESCRIPTOR *desc = &first_desc[i];
|
||||
if (!validate_ptr(modulePtr, module_size, desc, sizeof(IMAGE_DELAYLOAD_DESCRIPTOR))) break;
|
||||
if (desc->DllNameRVA == NULL) {
|
||||
break;
|
||||
}
|
||||
ULONGLONG dll_name_rva = desc->DllNameRVA;
|
||||
if (dll_name_rva > moduleBase) {
|
||||
dll_name_rva -= moduleBase;
|
||||
}
|
||||
char* dll_name = (char*)((ULONGLONG) modulePtr + dll_name_rva);
|
||||
if (!validate_ptr(modulePtr, module_size, dll_name, sizeof(char))) continue;
|
||||
#ifdef _DEBUG
|
||||
std::cout << dll_name << std::endl;
|
||||
#endif
|
||||
if (is_64bit) {
|
||||
#ifdef _WIN64
|
||||
parse_delayed_desc<ULONGLONG,IMAGE_THUNK_DATA64>(modulePtr, module_size, moduleBase, dll_name, IMAGE_ORDINAL_FLAG64, desc, func_resolver);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#ifndef _WIN64
|
||||
parse_delayed_desc<DWORD, IMAGE_THUNK_DATA32>(modulePtr, module_size, moduleBase, dll_name, IMAGE_ORDINAL_FLAG32, desc, func_resolver);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
176
ai_anti_malware/libpeconv/libpeconv/src/exported_func.cpp
Normal file
176
ai_anti_malware/libpeconv/libpeconv/src/exported_func.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
#include "peconv/exported_func.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
using namespace peconv;
|
||||
|
||||
std::string peconv::get_dll_shortname(const std::string& str)
|
||||
{
|
||||
std::size_t len = str.length();
|
||||
std::size_t found = str.find_last_of("/\\");
|
||||
std::size_t ext = str.find_last_of('.');
|
||||
if (ext >= len) return "";
|
||||
|
||||
std::string name = str.substr(found+1, ext - (found+1));
|
||||
std::transform(name.begin(), name.end(), name.begin(), tolower);
|
||||
return name;
|
||||
}
|
||||
|
||||
size_t peconv::forwarder_name_len(BYTE* fPtr)
|
||||
{
|
||||
// names can be also mangled, i.e. MSVCRT.??0__non_rtti_object@std@@QAE@ABV01@@Z
|
||||
bool has_dot = false;
|
||||
size_t len = 0;
|
||||
while ((*fPtr >= 'a' && *fPtr <= 'z')
|
||||
|| (*fPtr >= 'A' && *fPtr <= 'Z')
|
||||
|| (*fPtr >= '0' && *fPtr <= '9')
|
||||
|| (*fPtr == '.')
|
||||
|| (*fPtr == '_')
|
||||
|| (*fPtr == '#')
|
||||
|| (*fPtr == '@')
|
||||
|| (*fPtr == '?')
|
||||
|| (*fPtr == '-'))
|
||||
{
|
||||
if (*fPtr == '.') has_dot = true;
|
||||
len++;
|
||||
fPtr++;
|
||||
}
|
||||
if (*fPtr == '\0') {
|
||||
if (!has_dot) {
|
||||
return 0; //this is not a valid forwarder
|
||||
}
|
||||
return len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string peconv::get_func_name(const std::string& str)
|
||||
{
|
||||
std::size_t len = str.length();
|
||||
std::size_t ext = str.find_last_of(".");
|
||||
if (ext >= len) return "";
|
||||
|
||||
std::string name = str.substr(ext+1, len - (ext+1));
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string peconv::ordinal_to_string(DWORD func_ordinal)
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << "#";
|
||||
stream << std::dec << func_ordinal;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
bool peconv::is_ordinal_string(const std::string& func_name_str)
|
||||
{
|
||||
if (func_name_str.length() < 2) return false;
|
||||
return (func_name_str[0] == '#');
|
||||
}
|
||||
|
||||
DWORD peconv::ordinal_string_to_val(const std::string& func_name_str)
|
||||
{
|
||||
if (!is_ordinal_string(func_name_str)) return 0;
|
||||
const char* func_name = func_name_str.c_str();
|
||||
return atoi(func_name + 1);
|
||||
}
|
||||
|
||||
std::string peconv::format_dll_func(const std::string& str)
|
||||
{
|
||||
std::string dllName = get_dll_shortname(str);
|
||||
std::string funcName = get_func_name(str);
|
||||
if (dllName.length() == 0 || funcName.length() == 0) {
|
||||
return "";
|
||||
}
|
||||
std::transform(dllName.begin(), dllName.end(), dllName.begin(), tolower);
|
||||
return dllName + "." + funcName;
|
||||
}
|
||||
|
||||
ExportedFunc::ExportedFunc(std::string libName, std::string funcName, DWORD funcOrdinal)
|
||||
{
|
||||
this->libName = ExportedFunc::formatName(libName);
|
||||
this->funcName = funcName;
|
||||
this->funcOrdinal = funcOrdinal;
|
||||
this->isByOrdinal = false;
|
||||
}
|
||||
|
||||
ExportedFunc::ExportedFunc(std::string libName, DWORD funcOrdinal)
|
||||
{
|
||||
this->libName = ExportedFunc::formatName(libName);
|
||||
this->funcOrdinal = funcOrdinal;
|
||||
this->isByOrdinal = true;
|
||||
}
|
||||
|
||||
ExportedFunc::ExportedFunc(const ExportedFunc& other)
|
||||
{
|
||||
this->libName = other.libName;
|
||||
this->funcName = other.funcName;
|
||||
this->funcOrdinal = other.funcOrdinal;
|
||||
this->isByOrdinal = other.isByOrdinal;
|
||||
}
|
||||
|
||||
ExportedFunc::ExportedFunc(const std::string &forwarderName)
|
||||
{
|
||||
this->libName = get_dll_shortname(forwarderName);
|
||||
std::string func_name_str = get_func_name(forwarderName);
|
||||
if (func_name_str.length() < 2) {
|
||||
this->funcOrdinal = -1;
|
||||
this->funcName = "";
|
||||
this->isByOrdinal = false;
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Invalid function data" << std::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (is_ordinal_string(func_name_str)) {
|
||||
// it is an ordinal in a string form, i.e.: "COMBASE.#110"
|
||||
this->funcOrdinal = peconv::ordinal_string_to_val(func_name_str);
|
||||
this->isByOrdinal = true;
|
||||
this->funcName = "";
|
||||
//std::cout << "[O] Adding forwarded func: " << forwarderName << " parsed: " << this->toString() << std::endl;
|
||||
} else {
|
||||
this->funcName = func_name_str;
|
||||
this->isByOrdinal = false;
|
||||
this->funcOrdinal = 0;
|
||||
//std::cout << "[N] Adding forwarded func:" << this->toString() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string ExportedFunc::formatName(std::string name)
|
||||
{
|
||||
if (name.length() == 0 || name.length() == 0) {
|
||||
return "";
|
||||
}
|
||||
std::transform(name.begin(), name.end(), name.begin(), tolower);
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string ExportedFunc::toString() const
|
||||
{
|
||||
if (!isValid()) {
|
||||
return "[Invalid func]";
|
||||
}
|
||||
std::stringstream stream;
|
||||
stream << this->libName;
|
||||
stream << ".";
|
||||
if (!this->isByOrdinal) {
|
||||
stream << this->funcName;
|
||||
stream << " ";
|
||||
}
|
||||
stream << ordinal_to_string(this->funcOrdinal);
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
std::string ExportedFunc::nameToString() const
|
||||
{
|
||||
if (!isValid()) {
|
||||
return "";
|
||||
}
|
||||
if (this->isByOrdinal) {
|
||||
return ordinal_to_string(this->funcOrdinal);
|
||||
}
|
||||
return this->funcName;
|
||||
}
|
||||
193
ai_anti_malware/libpeconv/libpeconv/src/exports_lookup.cpp
Normal file
193
ai_anti_malware/libpeconv/libpeconv/src/exports_lookup.cpp
Normal file
@@ -0,0 +1,193 @@
|
||||
#include "peconv/exports_lookup.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/*
|
||||
typedef struct _IMAGE_EXPORT_DIRECTORY {
|
||||
DWORD Characteristics;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
DWORD Name;
|
||||
DWORD Base;
|
||||
DWORD NumberOfFunctions;
|
||||
DWORD NumberOfNames;
|
||||
DWORD AddressOfFunctions; // RVA from base of image
|
||||
DWORD AddressOfNames; // RVA from base of image
|
||||
DWORD AddressOfNameOrdinals; // RVA from base of image
|
||||
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
|
||||
*/
|
||||
|
||||
#ifndef TO_LOWERCASE
|
||||
#define TO_LOWERCASE(c1) c1 = (c1 <= 'Z' && c1 >= 'A') ? c1 = (c1 - 'A') + 'a': c1;
|
||||
#endif
|
||||
|
||||
bool is_wanted_func(LPSTR curr_name, LPSTR wanted_name)
|
||||
{
|
||||
if (curr_name == NULL || wanted_name == NULL) return false;
|
||||
|
||||
size_t wanted_name_len = strlen(wanted_name);
|
||||
size_t curr_name_len = strlen(curr_name);
|
||||
|
||||
if (curr_name_len != wanted_name_len) return false;
|
||||
|
||||
for (size_t i = 0; i < wanted_name_len; i++) {
|
||||
char c1 = curr_name[i];
|
||||
char c2 = wanted_name[i];
|
||||
TO_LOWERCASE(c1);
|
||||
TO_LOWERCASE(c2);
|
||||
if (c1 != c2) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_ordinal(IMAGE_EXPORT_DIRECTORY *exp, LPSTR func_name)
|
||||
{
|
||||
ULONGLONG base = exp->Base;
|
||||
ULONGLONG max_ord = base + exp->NumberOfFunctions;
|
||||
ULONGLONG name_ptr_val = (ULONGLONG)func_name;
|
||||
if (name_ptr_val >= base && name_ptr_val < max_ord) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FARPROC get_export_by_ord(PVOID modulePtr, IMAGE_EXPORT_DIRECTORY* exp, DWORD wanted_ordinal)
|
||||
{
|
||||
SIZE_T functCount = exp->NumberOfFunctions;
|
||||
DWORD funcsListRVA = exp->AddressOfFunctions;
|
||||
DWORD ordBase = exp->Base;
|
||||
|
||||
//go through names:
|
||||
for (DWORD i = 0; i < functCount; i++) {
|
||||
DWORD* funcRVA = (DWORD*)(funcsListRVA + (BYTE*) modulePtr + i * sizeof(DWORD));
|
||||
BYTE* fPtr = (BYTE*) modulePtr + (*funcRVA); //pointer to the function
|
||||
DWORD ordinal = ordBase + i;
|
||||
if (ordinal == wanted_ordinal) {
|
||||
if (peconv::forwarder_name_len(fPtr) > 1) {
|
||||
std::cerr << "[!] Forwarded function: ["<< wanted_ordinal << " -> "<< fPtr << "] cannot be resolved!" << std::endl;
|
||||
return NULL; // this function is forwarded, cannot be resolved
|
||||
}
|
||||
return (FARPROC) fPtr; //return the pointer to the found function
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t peconv::get_exported_names(PVOID modulePtr, std::vector<std::string> &names_list)
|
||||
{
|
||||
IMAGE_EXPORT_DIRECTORY* exp = peconv::get_export_directory((HMODULE) modulePtr);
|
||||
if (exp == 0) return 0;
|
||||
|
||||
SIZE_T namesCount = exp->NumberOfNames;
|
||||
DWORD funcNamesListRVA = exp->AddressOfNames;
|
||||
|
||||
//go through names:
|
||||
SIZE_T i = 0;
|
||||
for (i = 0; i < namesCount; i++) {
|
||||
DWORD* nameRVA = (DWORD*)(funcNamesListRVA + (BYTE*) modulePtr + i * sizeof(DWORD));
|
||||
|
||||
LPSTR name = (LPSTR)(*nameRVA + (BYTE*) modulePtr);
|
||||
if (IsBadReadPtr(name, 1)) break; // this shoudld not happen. maybe the PE file is corrupt?
|
||||
|
||||
names_list.push_back(name);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
//WARNING: doesn't work for the forwarded functions.
|
||||
FARPROC peconv::get_exported_func(PVOID modulePtr, LPSTR wanted_name)
|
||||
{
|
||||
IMAGE_EXPORT_DIRECTORY* exp = peconv::get_export_directory((HMODULE) modulePtr);
|
||||
if (exp == NULL) return NULL;
|
||||
|
||||
SIZE_T namesCount = exp->NumberOfNames;
|
||||
|
||||
DWORD funcsListRVA = exp->AddressOfFunctions;
|
||||
DWORD funcNamesListRVA = exp->AddressOfNames;
|
||||
DWORD namesOrdsListRVA = exp->AddressOfNameOrdinals;
|
||||
|
||||
if (is_ordinal(exp, wanted_name)) {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "[*] Getting function by ordinal" << std::endl;
|
||||
#endif
|
||||
const DWORD ordinal = MASK_TO_DWORD((ULONG_PTR)wanted_name);
|
||||
return get_export_by_ord(modulePtr, exp, ordinal);
|
||||
}
|
||||
if (IsBadReadPtr(wanted_name, 1)) {
|
||||
std::cerr << "[-] Invalid pointer to the name" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//go through names:
|
||||
for (SIZE_T i = 0; i < namesCount; i++) {
|
||||
DWORD* nameRVA = (DWORD*)(funcNamesListRVA + (BYTE*) modulePtr + i * sizeof(DWORD));
|
||||
WORD* nameIndex = (WORD*)(namesOrdsListRVA + (BYTE*) modulePtr + i * sizeof(WORD));
|
||||
DWORD* funcRVA = (DWORD*)(funcsListRVA + (BYTE*) modulePtr + (*nameIndex) * sizeof(DWORD));
|
||||
|
||||
LPSTR name = (LPSTR)(*nameRVA + (BYTE*) modulePtr);
|
||||
BYTE* fPtr = (BYTE*) modulePtr + (*funcRVA); //pointer to the function
|
||||
|
||||
if (!is_wanted_func(name, wanted_name)) {
|
||||
continue; //this is not the function we are looking for
|
||||
}
|
||||
if (forwarder_name_len(fPtr) > 1) {
|
||||
std::cerr << "[!] Forwarded function: ["<< name << " -> "<< fPtr << "] cannot be resolved!" << std::endl;
|
||||
return NULL; // this function is forwarded, cannot be resolved
|
||||
}
|
||||
return (FARPROC) fPtr; //return the pointer to the found function
|
||||
}
|
||||
//function not found
|
||||
std::cerr << "Function not found!" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FARPROC peconv::export_based_resolver::resolve_func(LPSTR lib_name, LPSTR func_name)
|
||||
{
|
||||
HMODULE libBasePtr = LoadLibraryA(lib_name);
|
||||
if (libBasePtr == NULL) {
|
||||
std::cerr << "Could not load the library!" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FARPROC hProc = get_exported_func(libBasePtr, func_name);
|
||||
|
||||
if (hProc == NULL) {
|
||||
#ifdef _DEBUG
|
||||
if (!IsBadReadPtr(func_name, 1)) {
|
||||
std::cerr << "[!] Cound not get the function: "<< func_name <<" from exports!" << std::endl;
|
||||
} else {
|
||||
std::cerr << "[!] Cound not get the function: "<< MASK_TO_DWORD((ULONG_PTR)func_name) <<" from exports!" << std::endl;
|
||||
}
|
||||
std::cerr << "[!] Falling back to the default resolver..." <<std::endl;
|
||||
#endif
|
||||
hProc = default_func_resolver::resolve_func(lib_name, func_name);
|
||||
if (hProc == NULL) {
|
||||
std::cerr << "[-] Loading function from " << lib_name << " failed!" << std::endl;
|
||||
}
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
FARPROC defaultProc = default_func_resolver::resolve_func(lib_name, func_name);
|
||||
if (hProc != defaultProc) {
|
||||
std::cerr << "[-] Loaded proc is not matching the default one!" << std::endl;
|
||||
}
|
||||
#endif
|
||||
return hProc;
|
||||
}
|
||||
|
||||
LPSTR peconv::read_dll_name(HMODULE modulePtr)
|
||||
{
|
||||
IMAGE_EXPORT_DIRECTORY* exp = get_export_directory(modulePtr);
|
||||
if (exp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
LPSTR module_name = (char*)((ULONGLONG)modulePtr + exp->Name);
|
||||
if (IsBadReadPtr(module_name, 1)) {
|
||||
return NULL;
|
||||
}
|
||||
size_t len = peconv::forwarder_name_len((BYTE*) module_name);
|
||||
if (len > 1) {
|
||||
return module_name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
269
ai_anti_malware/libpeconv/libpeconv/src/exports_mapper.cpp
Normal file
269
ai_anti_malware/libpeconv/libpeconv/src/exports_mapper.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
#include "peconv/exports_mapper.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using namespace peconv;
|
||||
|
||||
void ExportsMapper::print_va_to_func(std::stringstream &stream) const
|
||||
{
|
||||
std::map<ULONGLONG, std::set<ExportedFunc>>::const_iterator itr;
|
||||
|
||||
for (itr = va_to_func.begin(); itr != va_to_func.end(); ++itr) {
|
||||
|
||||
stream << std::hex << itr->first << " :\n";
|
||||
|
||||
std::set<ExportedFunc>::const_iterator itr2;
|
||||
const std::set<ExportedFunc> &funcs = itr->second;
|
||||
|
||||
for (itr2 = funcs.begin(); itr2 != funcs.end(); ++itr2) {
|
||||
stream << "\t" << itr2->toString() << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExportsMapper::print_func_to_va(std::stringstream &stream) const
|
||||
{
|
||||
std::map<ExportedFunc, ULONGLONG>::const_iterator itr;
|
||||
for (itr = func_to_va.begin(); itr != func_to_va.end(); ++itr) {
|
||||
stream << itr->first.toString() << " : "
|
||||
<< std::hex << itr->second << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
ULONGLONG rebase_va(ULONGLONG va, ULONGLONG currBase, ULONGLONG targetBase)
|
||||
{
|
||||
if (currBase == targetBase) {
|
||||
return va;
|
||||
}
|
||||
ULONGLONG rva = va - (ULONGLONG) currBase;
|
||||
return rva + targetBase;
|
||||
}
|
||||
|
||||
size_t ExportsMapper::make_ord_lookup_tables(
|
||||
PVOID modulePtr,
|
||||
size_t moduleSize,
|
||||
std::map<PDWORD, DWORD> &va_to_ord
|
||||
)
|
||||
{
|
||||
IMAGE_EXPORT_DIRECTORY* exp = peconv::get_export_directory((HMODULE) modulePtr);
|
||||
if (exp == NULL) return 0;
|
||||
|
||||
SIZE_T functCount = exp->NumberOfFunctions;
|
||||
DWORD funcsListRVA = exp->AddressOfFunctions;
|
||||
DWORD ordBase = exp->Base;
|
||||
|
||||
//go through names:
|
||||
for (DWORD i = 0; i < functCount; i++) {
|
||||
DWORD* recordRVA = (DWORD*)(funcsListRVA + (BYTE*) modulePtr + i * sizeof(DWORD));
|
||||
if (*recordRVA == 0) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << ">>> Skipping 0 function address at RVA:" << std::hex << (BYTE*)recordRVA - (BYTE*)modulePtr<< "(ord)\n";
|
||||
#endif
|
||||
//skip if the function RVA is 0 (empty export)
|
||||
continue;
|
||||
}
|
||||
if (!peconv::validate_ptr(modulePtr, moduleSize, recordRVA, sizeof(DWORD))) {
|
||||
break;
|
||||
}
|
||||
DWORD ordinal = ordBase + i;
|
||||
va_to_ord[recordRVA] = ordinal;
|
||||
}
|
||||
return functCount;
|
||||
}
|
||||
|
||||
size_t ExportsMapper::resolve_forwarders(const ULONGLONG va, ExportedFunc &currFunc)
|
||||
{
|
||||
size_t resolved = 0;
|
||||
//resolve forwarders of this function (if any):
|
||||
std::map<ExportedFunc, std::set<ExportedFunc>>::iterator fItr = forwarders_lookup.find(currFunc);
|
||||
if (fItr != forwarders_lookup.end()) {
|
||||
//printf("[+] Forwarders (%d):\n", fItr->second.size());
|
||||
std::set<ExportedFunc>::iterator sItr;
|
||||
for (sItr = fItr->second.begin(); sItr != fItr->second.end(); ++sItr) {
|
||||
//printf("-> %s\n", sItr->c_str());
|
||||
associateVaAndFunc(va, *sItr);
|
||||
resolved++;
|
||||
}
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
bool ExportsMapper::add_forwarded(ExportedFunc &currFunc, DWORD callRVA, PBYTE modulePtr, size_t moduleSize)
|
||||
{
|
||||
PBYTE fPtr = modulePtr + callRVA;
|
||||
if (!peconv::validate_ptr(modulePtr, moduleSize, fPtr, 1)) {
|
||||
return false;
|
||||
}
|
||||
if (peconv::forwarder_name_len(fPtr) < 1) {
|
||||
return false; //not forwarded
|
||||
}
|
||||
std::string forwardedFunc = format_dll_func((char*)fPtr);
|
||||
if (forwardedFunc.length() == 0) {
|
||||
return false; //not forwarded
|
||||
}
|
||||
|
||||
ExportedFunc forwarder(forwardedFunc);
|
||||
if (!forwarder.isValid()) {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Skipped invalid forwarder" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
forwarders_lookup[forwarder].insert(currFunc);
|
||||
|
||||
if (func_to_va[forwarder] != 0) {
|
||||
ULONGLONG va = func_to_va[forwarder];
|
||||
associateVaAndFunc(va, currFunc);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD get_ordinal(PDWORD recordPtr, std::map<PDWORD, DWORD> &va_to_ord)
|
||||
{
|
||||
std::map<PDWORD, DWORD>::iterator ord_itr = va_to_ord.find(recordPtr);
|
||||
if (ord_itr == va_to_ord.end()) {
|
||||
//ordinal not found
|
||||
return -1;
|
||||
}
|
||||
DWORD ordinal = ord_itr->second;
|
||||
va_to_ord.erase(ord_itr);
|
||||
return ordinal;
|
||||
}
|
||||
|
||||
bool ExportsMapper::add_to_maps(ULONGLONG va, ExportedFunc &currFunc)
|
||||
{
|
||||
associateVaAndFunc(va, currFunc);
|
||||
resolve_forwarders(va, currFunc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_valid_export_table(IMAGE_EXPORT_DIRECTORY* exp, HMODULE modulePtr, const size_t module_size)
|
||||
{
|
||||
if (exp == nullptr) return false;
|
||||
|
||||
const SIZE_T namesCount = exp->NumberOfNames;
|
||||
const SIZE_T funcCount = exp->NumberOfFunctions;
|
||||
|
||||
const DWORD funcsListRVA = exp->AddressOfFunctions;
|
||||
const DWORD funcNamesListRVA = exp->AddressOfNames;
|
||||
const DWORD namesOrdsListRVA = exp->AddressOfNameOrdinals;
|
||||
|
||||
for (DWORD i = 0; i < funcCount; i++) {
|
||||
DWORD* recordRVA = (DWORD*)(funcsListRVA + (BYTE*)modulePtr + i * sizeof(DWORD));
|
||||
if (*recordRVA == 0) {
|
||||
//skip if the function RVA is 0 (empty export)
|
||||
continue;
|
||||
}
|
||||
if (!peconv::validate_ptr(modulePtr, module_size, recordRVA, sizeof(DWORD))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (SIZE_T i = 0; i < namesCount; i++) {
|
||||
DWORD* nameRVA = (DWORD*)(funcNamesListRVA + (BYTE*)modulePtr + i * sizeof(DWORD));
|
||||
WORD* nameIndex = (WORD*)(namesOrdsListRVA + (BYTE*)modulePtr + i * sizeof(WORD));
|
||||
if ((!peconv::validate_ptr(modulePtr, module_size, nameRVA, sizeof(DWORD)))
|
||||
|| (!peconv::validate_ptr(modulePtr, module_size, nameIndex, sizeof(WORD))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
DWORD* funcRVA = (DWORD*)(funcsListRVA + (BYTE*)modulePtr + (*nameIndex) * sizeof(DWORD));
|
||||
if (!peconv::validate_ptr(modulePtr, module_size, funcRVA, sizeof(DWORD)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ExportsMapper::ADD_FUNC_RES ExportsMapper::add_function_to_lookup(HMODULE modulePtr, ULONGLONG moduleBase, size_t moduleSize, ExportedFunc &currFunc, DWORD callRVA)
|
||||
{
|
||||
if (add_forwarded(currFunc, callRVA, (BYTE*)modulePtr, moduleSize)) {
|
||||
#ifdef _DEBUG
|
||||
char* fPtr = (char*)modulePtr + callRVA;
|
||||
std::cout << "FWD " << currFunc.toString() << " -> " << fPtr << "\n";
|
||||
#endif
|
||||
return ExportsMapper::RES_FORWARDED;
|
||||
}
|
||||
|
||||
ULONGLONG callVa = callRVA + moduleBase;
|
||||
if (!peconv::validate_ptr((BYTE*)moduleBase, moduleSize, (BYTE*)callVa, sizeof(ULONGLONG))) {
|
||||
// this may happen when the function was forwarded and it is already filled
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Validation failed: " << currFunc.toString() << "\n";
|
||||
#endif
|
||||
return ExportsMapper::RES_INVALID;
|
||||
}
|
||||
//not forwarded, simple case:
|
||||
add_to_maps(callVa, currFunc);
|
||||
return ExportsMapper::RES_MAPPED;
|
||||
}
|
||||
|
||||
size_t ExportsMapper::add_to_lookup(std::string moduleName, HMODULE modulePtr, ULONGLONG moduleBase)
|
||||
{
|
||||
IMAGE_EXPORT_DIRECTORY* exp = get_export_directory(modulePtr);
|
||||
if (exp == NULL) {
|
||||
return 0;
|
||||
}
|
||||
size_t module_size = peconv::get_image_size(reinterpret_cast<const PBYTE>(modulePtr));
|
||||
if (!is_valid_export_table(exp, modulePtr, module_size)) {
|
||||
return 0;
|
||||
}
|
||||
std::string dllName = get_dll_shortname(moduleName);
|
||||
this->dll_shortname_to_path[dllName] = moduleName;
|
||||
|
||||
std::map<PDWORD, DWORD> va_to_ord;
|
||||
size_t functCount = make_ord_lookup_tables(modulePtr, module_size, va_to_ord);
|
||||
|
||||
//go through names:
|
||||
|
||||
size_t forwarded_ctr = 0;
|
||||
SIZE_T namesCount = exp->NumberOfNames;
|
||||
|
||||
DWORD funcsListRVA = exp->AddressOfFunctions;
|
||||
DWORD funcNamesListRVA = exp->AddressOfNames;
|
||||
DWORD namesOrdsListRVA = exp->AddressOfNameOrdinals;
|
||||
|
||||
size_t mapped_ctr = 0;
|
||||
|
||||
for (SIZE_T i = 0; i < namesCount; i++) {
|
||||
DWORD* nameRVA = (DWORD*)(funcNamesListRVA + (BYTE*) modulePtr + i * sizeof(DWORD));
|
||||
WORD* nameIndex = (WORD*)(namesOrdsListRVA + (BYTE*) modulePtr + i * sizeof(WORD));
|
||||
DWORD* funcRVA = (DWORD*)(funcsListRVA + (BYTE*) modulePtr + (*nameIndex) * sizeof(DWORD));
|
||||
if (*funcRVA == 0) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << ">>> Skipping 0 function address at RVA:" << std::hex << (BYTE*)funcRVA - (BYTE*)modulePtr << "(name)\n";
|
||||
#endif
|
||||
//skip if the function RVA is 0 (empty export)
|
||||
continue;
|
||||
}
|
||||
|
||||
LPSTR name = (LPSTR)(*nameRVA + (BYTE*) modulePtr);
|
||||
if (!peconv::validate_ptr(modulePtr, module_size, name, sizeof(char))) break;
|
||||
|
||||
DWORD funcOrd = get_ordinal(funcRVA, va_to_ord);
|
||||
DWORD callRVA = *funcRVA;
|
||||
ExportedFunc currFunc(dllName, name, funcOrd);
|
||||
|
||||
int res = add_function_to_lookup(modulePtr, moduleBase, module_size, currFunc, callRVA);
|
||||
if (res == ExportsMapper::RES_FORWARDED) forwarded_ctr++;
|
||||
if (res == ExportsMapper::RES_MAPPED) mapped_ctr++;
|
||||
}
|
||||
//go through unnamed functions exported by ordinals:
|
||||
std::map<PDWORD, DWORD>::iterator ord_itr = va_to_ord.begin();
|
||||
for (;ord_itr != va_to_ord.end(); ++ord_itr) {
|
||||
|
||||
DWORD* funcRVA = ord_itr->first;
|
||||
DWORD callRVA = *funcRVA;
|
||||
ExportedFunc currFunc(dllName, ord_itr->second);
|
||||
|
||||
int res = add_function_to_lookup(modulePtr, moduleBase, module_size, currFunc, callRVA);
|
||||
if (res == ExportsMapper::RES_FORWARDED) forwarded_ctr++;
|
||||
if (res == ExportsMapper::RES_MAPPED) mapped_ctr++;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Finished exports parsing, mapped: "<< mapped_ctr << " forwarded: " << forwarded_ctr << std::endl;
|
||||
#endif
|
||||
return mapped_ctr;
|
||||
}
|
||||
147
ai_anti_malware/libpeconv/libpeconv/src/file_util.cpp
Normal file
147
ai_anti_malware/libpeconv/libpeconv/src/file_util.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
#include "peconv/file_util.h"
|
||||
#include "peconv/buffer_util.h"
|
||||
|
||||
#include <fstream>
|
||||
#ifdef _DEBUG
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
//load file content using MapViewOfFile
|
||||
peconv::ALIGNED_BUF peconv::load_file(IN const char *filename, OUT size_t &read_size)
|
||||
{
|
||||
HANDLE file = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if(file == INVALID_HANDLE_VALUE) {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Could not open file!" << std::endl;
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
HANDLE mapping = CreateFileMapping(file, 0, PAGE_READONLY, 0, 0, 0);
|
||||
if (!mapping) {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Could not create mapping!" << std::endl;
|
||||
#endif
|
||||
CloseHandle(file);
|
||||
return nullptr;
|
||||
}
|
||||
BYTE *dllRawData = (BYTE*) MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
|
||||
if (!dllRawData) {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Could not map view of file" << std::endl;
|
||||
#endif
|
||||
CloseHandle(mapping);
|
||||
CloseHandle(file);
|
||||
return nullptr;
|
||||
}
|
||||
size_t r_size = GetFileSize(file, 0);
|
||||
if (read_size != 0 && read_size <= r_size) {
|
||||
r_size = read_size;
|
||||
}
|
||||
if (IsBadReadPtr(dllRawData, r_size)) {
|
||||
std::cerr << "[-] Mapping of " << filename << " is invalid!" << std::endl;
|
||||
UnmapViewOfFile(dllRawData);
|
||||
CloseHandle(mapping);
|
||||
CloseHandle(file);
|
||||
return nullptr;
|
||||
}
|
||||
peconv::ALIGNED_BUF localCopyAddress = peconv::alloc_aligned(r_size, PAGE_READWRITE);
|
||||
if (localCopyAddress != nullptr) {
|
||||
memcpy(localCopyAddress, dllRawData, r_size);
|
||||
read_size = r_size;
|
||||
} else {
|
||||
read_size = 0;
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Could not allocate memory in the current process" << std::endl;
|
||||
#endif
|
||||
}
|
||||
UnmapViewOfFile(dllRawData);
|
||||
CloseHandle(mapping);
|
||||
CloseHandle(file);
|
||||
return localCopyAddress;
|
||||
}
|
||||
|
||||
//load file content using ReadFile
|
||||
peconv::ALIGNED_BUF peconv::read_from_file(IN const char *in_path, IN OUT size_t &read_size)
|
||||
{
|
||||
HANDLE file = CreateFileA(in_path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Cannot open the file for reading!" << std::endl;
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
size_t r_size = static_cast<size_t>(GetFileSize(file, 0));
|
||||
if (read_size != 0 && read_size <= r_size) {
|
||||
r_size = read_size;
|
||||
}
|
||||
PBYTE buffer = peconv::alloc_pe_buffer(r_size, PAGE_READWRITE);
|
||||
if (buffer == nullptr) {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Allocation has failed!" << std::endl;
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
DWORD out_size = 0;
|
||||
if (!ReadFile(file, buffer, r_size, &out_size, nullptr)) {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Reading failed!" << std::endl;
|
||||
#endif
|
||||
peconv::free_pe_buffer(buffer, r_size);
|
||||
buffer = nullptr;
|
||||
read_size = 0;
|
||||
} else {
|
||||
read_size = r_size;
|
||||
}
|
||||
CloseHandle(file);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//save the given buffer into a file
|
||||
bool peconv::dump_to_file(IN const char *out_path, IN PBYTE dump_data, IN size_t dump_size)
|
||||
{
|
||||
if (!out_path || !dump_data || !dump_size) return false;
|
||||
|
||||
HANDLE file = CreateFileA(out_path, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Cannot open the file for writing!" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
DWORD written_size = 0;
|
||||
bool is_dumped = false;
|
||||
if (WriteFile(file, dump_data, (DWORD) dump_size, &written_size, nullptr)) {
|
||||
is_dumped = true;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
else {
|
||||
std::cerr << "Failed to write to the file : " << out_path << std::endl;
|
||||
}
|
||||
#endif
|
||||
CloseHandle(file);
|
||||
return is_dumped;
|
||||
}
|
||||
|
||||
//free the buffer allocated by load_file/read_from_file
|
||||
void peconv::free_file(IN peconv::ALIGNED_BUF buffer)
|
||||
{
|
||||
peconv::free_aligned(buffer);
|
||||
}
|
||||
|
||||
std::string peconv::get_file_name(IN const std::string str)
|
||||
{
|
||||
size_t found = str.find_last_of("/\\");
|
||||
if (found == std::string::npos) {
|
||||
return str;
|
||||
}
|
||||
return str.substr(found + 1);
|
||||
}
|
||||
|
||||
std::string peconv::get_directory_name(IN const std::string str)
|
||||
{
|
||||
size_t found = str.find_last_of("/\\");
|
||||
if (found == std::string::npos) {
|
||||
return "";
|
||||
}
|
||||
return str.substr(0, found);
|
||||
}
|
||||
125
ai_anti_malware/libpeconv/libpeconv/src/find_base.cpp
Normal file
125
ai_anti_malware/libpeconv/libpeconv/src/find_base.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
#include <peconv/find_base.h>
|
||||
#include <peconv/pe_hdrs_helper.h>
|
||||
#include <peconv/relocate.h>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
namespace peconv {
|
||||
|
||||
class CollectCodeRelocs : public RelocBlockCallback
|
||||
{
|
||||
public:
|
||||
CollectCodeRelocs(BYTE *pe_buffer, size_t buffer_size, IN bool _is64bit, OUT std::set<ULONGLONG> &_relocs)
|
||||
: RelocBlockCallback(_is64bit), relocs(_relocs),
|
||||
peBuffer(pe_buffer), bufferSize(buffer_size)
|
||||
{
|
||||
codeSec = getCodeSection(peBuffer, bufferSize);
|
||||
}
|
||||
|
||||
virtual bool processRelocField(ULONG_PTR relocField)
|
||||
{
|
||||
if (!codeSec) return false;
|
||||
|
||||
ULONGLONG reloc_addr = (relocField - (ULONGLONG)peBuffer);
|
||||
const bool is_in_code = (reloc_addr >= codeSec->VirtualAddress) && (reloc_addr < codeSec->Misc.VirtualSize);
|
||||
if (!is64bit && !is_in_code) {
|
||||
// in case of 32 bit PEs process only the relocations form the code section
|
||||
return true;
|
||||
}
|
||||
ULONGLONG rva = 0;
|
||||
if (is64bit) {
|
||||
ULONGLONG* relocateAddr = (ULONGLONG*)((ULONG_PTR)relocField);
|
||||
rva = (*relocateAddr);
|
||||
//std::cout << std::hex << (relocField - (ULONGLONG)peBuffer) << " : " << rva << std::endl;
|
||||
}
|
||||
else {
|
||||
DWORD* relocateAddr = (DWORD*)((ULONG_PTR)relocField);
|
||||
rva = ULONGLONG(*relocateAddr);
|
||||
//std::cout << std::hex << (relocField - (ULONGLONG)peBuffer) << " : " << rva << std::endl;
|
||||
}
|
||||
relocs.insert(rva);
|
||||
return true;
|
||||
}
|
||||
|
||||
static PIMAGE_SECTION_HEADER getCodeSection(BYTE *peBuffer, size_t bufferSize)
|
||||
{
|
||||
size_t sec_count = peconv::get_sections_count(peBuffer, bufferSize);
|
||||
for (size_t i = 0; i < sec_count; i++) {
|
||||
PIMAGE_SECTION_HEADER hdr = peconv::get_section_hdr(peBuffer, bufferSize, i);
|
||||
if (!hdr) break;
|
||||
if (hdr->VirtualAddress == 0 || hdr->SizeOfRawData == 0) {
|
||||
continue;
|
||||
}
|
||||
if (hdr->Characteristics & IMAGE_SCN_MEM_EXECUTE) {
|
||||
return hdr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::set<ULONGLONG> &relocs;
|
||||
PIMAGE_SECTION_HEADER codeSec;
|
||||
|
||||
BYTE *peBuffer;
|
||||
size_t bufferSize;
|
||||
};
|
||||
}
|
||||
|
||||
ULONGLONG peconv::find_base_candidate(IN BYTE* modulePtr, IN size_t moduleSize)
|
||||
{
|
||||
if (moduleSize == 0) {
|
||||
moduleSize = peconv::get_image_size((const BYTE*)modulePtr);
|
||||
}
|
||||
if (moduleSize == 0) return 0;
|
||||
|
||||
bool is64 = peconv::is64bit(modulePtr);
|
||||
std::set<ULONGLONG> relocs;
|
||||
peconv::CollectCodeRelocs callback(modulePtr, moduleSize, is64, relocs);
|
||||
if (!peconv::process_relocation_table(modulePtr, moduleSize, &callback)) {
|
||||
return 0;
|
||||
}
|
||||
if (relocs.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PIMAGE_SECTION_HEADER hdr = peconv::CollectCodeRelocs::getCodeSection(modulePtr, moduleSize);
|
||||
if (!hdr) {
|
||||
return 0;
|
||||
}
|
||||
const ULONGLONG mask = ~ULONGLONG(0xFFFF);
|
||||
std::map<ULONGLONG, size_t>base_candidates;
|
||||
|
||||
std::set<ULONGLONG>::iterator itr = relocs.begin();
|
||||
|
||||
for (itr = relocs.begin(); itr != relocs.end(); ++itr) {
|
||||
const ULONGLONG guessed_base = (*itr) & mask;
|
||||
std::map<ULONGLONG, size_t>::iterator found = base_candidates.find(guessed_base);
|
||||
if (found == base_candidates.end()) {
|
||||
base_candidates[guessed_base] = 0;
|
||||
}
|
||||
base_candidates[guessed_base]++;
|
||||
}
|
||||
ULONGLONG most_freqent = 0;
|
||||
size_t max_freq = 0;
|
||||
std::map<ULONGLONG, size_t>::iterator mapItr;
|
||||
for (mapItr = base_candidates.begin(); mapItr != base_candidates.end(); ++mapItr) {
|
||||
if (mapItr->second >= max_freq) {
|
||||
most_freqent = mapItr->first;
|
||||
max_freq = mapItr->second;
|
||||
}
|
||||
}
|
||||
for (itr = relocs.begin(); itr != relocs.end(); ++itr) {
|
||||
ULONGLONG first = *itr;
|
||||
ULONGLONG first_base = first & mask;
|
||||
if (first_base > most_freqent) {
|
||||
break;
|
||||
}
|
||||
ULONGLONG delta = most_freqent - first_base;
|
||||
if (delta < moduleSize) {
|
||||
return first_base;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
144
ai_anti_malware/libpeconv/libpeconv/src/fix_dot_net_ep.cpp
Normal file
144
ai_anti_malware/libpeconv/libpeconv/src/fix_dot_net_ep.cpp
Normal file
@@ -0,0 +1,144 @@
|
||||
#include "fix_dot_net_ep.h"
|
||||
#include <peconv.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
class ListImportNames : public peconv::ImportThunksCallback
|
||||
{
|
||||
public:
|
||||
ListImportNames(BYTE* _modulePtr, size_t _moduleSize, std::map<std::string, DWORD> &name_to_addr)
|
||||
: ImportThunksCallback(_modulePtr, _moduleSize), nameToAddr(name_to_addr)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool processThunks(LPSTR lib_name, ULONG_PTR origFirstThunkPtr, ULONG_PTR firstThunkPtr)
|
||||
{
|
||||
if (this->is64b) {
|
||||
IMAGE_THUNK_DATA64* desc = reinterpret_cast<IMAGE_THUNK_DATA64*>(origFirstThunkPtr);
|
||||
ULONGLONG* call_via = reinterpret_cast<ULONGLONG*>(firstThunkPtr);
|
||||
return processThunks_tpl<ULONGLONG, IMAGE_THUNK_DATA64>(lib_name, desc, call_via, IMAGE_ORDINAL_FLAG64);
|
||||
}
|
||||
IMAGE_THUNK_DATA32* desc = reinterpret_cast<IMAGE_THUNK_DATA32*>(origFirstThunkPtr);
|
||||
DWORD* call_via = reinterpret_cast<DWORD*>(firstThunkPtr);
|
||||
return processThunks_tpl<DWORD, IMAGE_THUNK_DATA32>(lib_name, desc, call_via, IMAGE_ORDINAL_FLAG32);
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename T_FIELD, typename T_IMAGE_THUNK_DATA>
|
||||
bool processThunks_tpl(LPSTR lib_name, T_IMAGE_THUNK_DATA* desc, T_FIELD* call_via, T_FIELD ordinal_flag)
|
||||
{
|
||||
DWORD call_via_rva = static_cast<DWORD>((ULONG_PTR)call_via - (ULONG_PTR)this->modulePtr);
|
||||
#ifdef _DEBUG
|
||||
std::cout << "via RVA: " << std::hex << call_via_rva << " : ";
|
||||
#endif
|
||||
bool is_by_ord = (desc->u1.Ordinal & ordinal_flag) != 0;
|
||||
if (!is_by_ord) {
|
||||
PIMAGE_IMPORT_BY_NAME by_name = (PIMAGE_IMPORT_BY_NAME)((ULONGLONG)modulePtr + desc->u1.AddressOfData);
|
||||
LPSTR func_name = reinterpret_cast<LPSTR>(by_name->Name);
|
||||
#ifdef _DEBUG
|
||||
std::cout << "name: " << func_name << std::endl;
|
||||
#endif
|
||||
nameToAddr[func_name] = call_via_rva;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::map<std::string, DWORD> &nameToAddr;
|
||||
};
|
||||
|
||||
DWORD find_corexemain(BYTE *buf, size_t buf_size)
|
||||
{
|
||||
std::map<std::string, DWORD> name_to_addr;
|
||||
ListImportNames callback(buf, buf_size, name_to_addr);
|
||||
if (!peconv::process_import_table(buf, buf_size, &callback)) return 0;
|
||||
|
||||
std::map<std::string, DWORD>::iterator found = name_to_addr.find("_CorExeMain");
|
||||
if (found != name_to_addr.end()) return found->second;
|
||||
|
||||
found = name_to_addr.find("_CorDllMain");
|
||||
if (found != name_to_addr.end()) return found->second;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BYTE* search_jump(BYTE *buf, size_t buf_size, const DWORD cor_exe_main_thunk, const ULONGLONG img_base)
|
||||
{
|
||||
// search the jump pattern, i.e.:
|
||||
//JMP DWORD NEAR [0X402000] : FF 25 00204000
|
||||
const size_t jmp_size = 2;
|
||||
const BYTE jmp_pattern[jmp_size] = { 0xFF, 0x25 };
|
||||
|
||||
const size_t arg_size = sizeof(DWORD);
|
||||
if ((jmp_size + arg_size) > buf_size) {
|
||||
return nullptr;
|
||||
}
|
||||
const size_t end_offset = buf_size - (jmp_size + arg_size);
|
||||
|
||||
for (size_t i = end_offset; // search backwards
|
||||
(i + 1) != 0; // this is unsigned comparison, so we cannot do: i >= 0
|
||||
i--) // go back by one BYTE
|
||||
{
|
||||
if (buf[i] == jmp_pattern[0] && buf[i + 1] == jmp_pattern[1]) { // JMP
|
||||
DWORD* addr = (DWORD*)(&buf[i + jmp_size]);
|
||||
DWORD rva = static_cast<DWORD>((*addr) - img_base);
|
||||
if (rva == cor_exe_main_thunk) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Found call to _CorExeMain\n";
|
||||
#endif
|
||||
return buf + i;
|
||||
}
|
||||
else {
|
||||
std::cout << "[!] Mismatch: " << std::hex << rva << " vs _CorExeMain: " << cor_exe_main_thunk << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool fix_dot_net_ep(BYTE *pe_buffer, size_t pe_buffer_size)
|
||||
{
|
||||
if (!pe_buffer) return false;
|
||||
|
||||
if (peconv::is64bit(pe_buffer)) {
|
||||
//64bit .NET files have EP=0
|
||||
peconv::update_entry_point_rva(pe_buffer, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD ep_rva = peconv::get_entry_point_rva(pe_buffer);
|
||||
std::cout << "[*] This is a .NET payload and may require Enty Point corection. Current EP: " << std::hex << ep_rva << "\n";
|
||||
|
||||
PIMAGE_SECTION_HEADER sec_hdr = peconv::get_section_hdr(pe_buffer, pe_buffer_size, 0);
|
||||
if (!sec_hdr) return false;
|
||||
|
||||
BYTE *sec_ptr = pe_buffer + sec_hdr->VirtualAddress;
|
||||
if (!peconv::validate_ptr(pe_buffer, pe_buffer_size, sec_ptr, sec_hdr->SizeOfRawData)) {
|
||||
return false;
|
||||
}
|
||||
ULONGLONG img_base = peconv::get_image_base(pe_buffer);
|
||||
DWORD cor_exe_main_thunk = find_corexemain(pe_buffer, pe_buffer_size);
|
||||
if (!cor_exe_main_thunk) {
|
||||
return false;
|
||||
}
|
||||
BYTE* jump_ptr = search_jump(sec_ptr, sec_hdr->SizeOfRawData, cor_exe_main_thunk, img_base);
|
||||
if (jump_ptr == nullptr) return false;
|
||||
|
||||
size_t offset = jump_ptr - pe_buffer;
|
||||
peconv::update_entry_point_rva(pe_buffer, static_cast<DWORD>(offset));
|
||||
std::cout << "[*] Found possible Entry Point: " << std::hex << offset << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_dot_net(BYTE *pe_buffer, size_t pe_buffer_size)
|
||||
{
|
||||
if (!pe_buffer) return false;
|
||||
|
||||
IMAGE_DATA_DIRECTORY* dotnet_ptr = peconv::get_directory_entry(pe_buffer, IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, false);
|
||||
if (!dotnet_ptr) return false;
|
||||
|
||||
if (peconv::get_dotnet_hdr(pe_buffer, pe_buffer_size, dotnet_ptr)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
8
ai_anti_malware/libpeconv/libpeconv/src/fix_dot_net_ep.h
Normal file
8
ai_anti_malware/libpeconv/libpeconv/src/fix_dot_net_ep.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
bool fix_dot_net_ep(BYTE *pe_buffer, size_t pe_buffer_size);
|
||||
bool is_dot_net(BYTE *pe_buffer, size_t pe_buffer_size);
|
||||
|
||||
BYTE* search_jump(BYTE *buf, size_t buf_size, const DWORD cor_exe_main_thunk, const ULONGLONG img_base);
|
||||
306
ai_anti_malware/libpeconv/libpeconv/src/fix_imports.cpp
Normal file
306
ai_anti_malware/libpeconv/libpeconv/src/fix_imports.cpp
Normal file
@@ -0,0 +1,306 @@
|
||||
#include "peconv/fix_imports.h"
|
||||
#include "peconv/imports_uneraser.h"
|
||||
#include "peconv/file_util.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace peconv;
|
||||
|
||||
template <typename FIELD_T>
|
||||
size_t find_addresses_to_fill(FIELD_T call_via, FIELD_T thunk_addr, LPVOID modulePtr, size_t moduleSize, IN const peconv::ExportsMapper& exportsMap, OUT std::set<ULONGLONG> &addresses)
|
||||
{
|
||||
size_t addrCounter = 0;
|
||||
do {
|
||||
LPVOID call_via_ptr = (LPVOID)((ULONGLONG)modulePtr + call_via);
|
||||
if (call_via_ptr == nullptr) break;
|
||||
|
||||
LPVOID thunk_ptr = (LPVOID)((ULONGLONG)modulePtr + thunk_addr);
|
||||
if (thunk_ptr == nullptr) break;
|
||||
|
||||
if (!validate_ptr(modulePtr, moduleSize, thunk_ptr, sizeof(FIELD_T))) {
|
||||
break;
|
||||
}
|
||||
if (!validate_ptr(modulePtr, moduleSize, call_via_ptr, sizeof(FIELD_T))) {
|
||||
break;
|
||||
}
|
||||
FIELD_T *thunk_val = reinterpret_cast<FIELD_T*>(thunk_ptr);
|
||||
FIELD_T *call_via_val = reinterpret_cast<FIELD_T*>(call_via_ptr);
|
||||
if (*call_via_val == 0) {
|
||||
//nothing to fill, probably the last record
|
||||
break;
|
||||
}
|
||||
|
||||
ULONGLONG searchedAddr = ULONGLONG(*call_via_val);
|
||||
if (exportsMap.find_export_by_va(searchedAddr) != nullptr) {
|
||||
addresses.insert(searchedAddr);
|
||||
addrCounter++;
|
||||
}
|
||||
//---
|
||||
call_via += sizeof(FIELD_T);
|
||||
thunk_addr += sizeof(FIELD_T);
|
||||
} while (true);
|
||||
|
||||
return addrCounter;
|
||||
}
|
||||
|
||||
std::set<std::string> get_all_dlls_exporting_function(ULONGLONG func_addr, const peconv::ExportsMapper& exportsMap)
|
||||
{
|
||||
std::set<std::string> currDllNames;
|
||||
//1. Get all the functions from all accessible DLLs that correspond to this address:
|
||||
const std::set<ExportedFunc>* exports_for_va = exportsMap.find_exports_by_va(func_addr);
|
||||
if (!exports_for_va) {
|
||||
std::cerr << "Cannot find any DLL exporting: " << std::hex << func_addr << std::endl;
|
||||
return currDllNames; //empty
|
||||
}
|
||||
//2. Iterate through their DLL names and add them to a set:
|
||||
for (std::set<ExportedFunc>::iterator strItr = exports_for_va->begin();
|
||||
strItr != exports_for_va->end();
|
||||
++strItr)
|
||||
{
|
||||
currDllNames.insert(strItr->libName);
|
||||
}
|
||||
return currDllNames;
|
||||
}
|
||||
|
||||
std::set<std::string> get_dlls_intersection(const std::set<std::string> &dllNames, const std::set<std::string> &currDllNames)
|
||||
{
|
||||
std::set<std::string> resultSet;
|
||||
std::set_intersection(dllNames.begin(), dllNames.end(),
|
||||
currDllNames.begin(), currDllNames.end(),
|
||||
std::inserter(resultSet, resultSet.begin())
|
||||
);
|
||||
return resultSet;
|
||||
}
|
||||
|
||||
//find the name of the DLL that can cover all the addresses of imported functions
|
||||
std::string find_covering_dll(std::set<ULONGLONG> &addresses, const peconv::ExportsMapper& exportsMap)
|
||||
{
|
||||
std::set<std::string> mainDllsSet;
|
||||
std::set<std::string> reserveDllSet;
|
||||
bool isFresh = true;
|
||||
|
||||
// the earliest addresses are more significant for the final decision on what DLL to choose
|
||||
// so, they should be processed at the end
|
||||
std::set<ULONGLONG>::iterator addrItr;
|
||||
|
||||
for (addrItr = addresses.begin(); addrItr != addresses.end(); ++addrItr) {
|
||||
ULONGLONG searchedAddr = *addrItr;
|
||||
//---
|
||||
// 1. Find all the DLLs exporting this particular function (can be forwarded etc)
|
||||
std::set<std::string> currDllNames = get_all_dlls_exporting_function(searchedAddr, exportsMap);
|
||||
|
||||
//2. Which of those DLLs covers also previous functions from this series?
|
||||
if (isFresh) {
|
||||
//if no other function was processed before, set the current DLL set as the total set
|
||||
mainDllsSet = currDllNames;
|
||||
isFresh = false;
|
||||
continue;
|
||||
}
|
||||
// find the intersection between the total set and the current set
|
||||
std::set<std::string> resultSet = get_dlls_intersection(mainDllsSet, currDllNames);
|
||||
if (resultSet.size() > 0) {
|
||||
//found intersection, overwrite the main set
|
||||
mainDllsSet = resultSet;
|
||||
continue;
|
||||
}
|
||||
// if no intersection found in the main set, check if there is any in the reserved set:
|
||||
resultSet = get_dlls_intersection(reserveDllSet, currDllNames);
|
||||
if (resultSet.size() > 0) {
|
||||
//found intersection, overwrite the main set
|
||||
reserveDllSet = mainDllsSet; // move the current to the reserve
|
||||
mainDllsSet = resultSet;
|
||||
continue;
|
||||
}
|
||||
// no intersection found with any of the sets:
|
||||
reserveDllSet = currDllNames; //set is as a reserved DLL: to be used if it will reoccur
|
||||
}
|
||||
if (mainDllsSet.size() > 0) {
|
||||
const std::string main_dll = *(mainDllsSet.begin());
|
||||
return main_dll;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool ImportedDllCoverage::findCoveringDll()
|
||||
{
|
||||
std::string found_name = find_covering_dll(this->addresses, this->exportsMap);
|
||||
if (found_name.length() == 0) {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Cannot find a covering DLL" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
this->dllName = found_name;
|
||||
#ifdef _DEBUG
|
||||
std::cout << "[+] Found DLL name: " << found_name << std::endl;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t map_addresses_to_functions(std::set<ULONGLONG> &addresses,
|
||||
IN const std::string &chosenDll,
|
||||
IN const peconv::ExportsMapper& exportsMap,
|
||||
OUT std::map<ULONGLONG, std::set<ExportedFunc>> &addr_to_func,
|
||||
OUT std::set<ULONGLONG> ¬_found
|
||||
)
|
||||
{
|
||||
std::set<ULONGLONG> coveredAddresses;
|
||||
std::set<ULONGLONG>::iterator addrItr;
|
||||
for (addrItr = addresses.begin(); addrItr != addresses.end(); ++addrItr) {
|
||||
|
||||
ULONGLONG searchedAddr = *addrItr;
|
||||
|
||||
const std::set<ExportedFunc>* exports_for_va = exportsMap.find_exports_by_va(searchedAddr);
|
||||
if (exports_for_va == nullptr) {
|
||||
not_found.insert(searchedAddr);
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Cannot find any DLL exporting: " << std::hex << searchedAddr << std::endl;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
for (std::set<ExportedFunc>::iterator strItr = exports_for_va->begin();
|
||||
strItr != exports_for_va->end();
|
||||
++strItr)
|
||||
{
|
||||
std::string dll_name = strItr->libName;
|
||||
if (dll_name != chosenDll) {
|
||||
continue;
|
||||
}
|
||||
ExportedFunc func = *strItr;
|
||||
addr_to_func[searchedAddr].insert(func);
|
||||
coveredAddresses.insert(searchedAddr);
|
||||
}
|
||||
if (addr_to_func.find(searchedAddr) == addr_to_func.end()) {
|
||||
const ExportedFunc* func = exportsMap.find_export_by_va(searchedAddr);
|
||||
not_found.insert(searchedAddr);
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "[WARNING] A function: " << func->toString() << " not found in the covering DLL: " << chosenDll << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return coveredAddresses.size();
|
||||
}
|
||||
|
||||
size_t ImportedDllCoverage::mapAddressesToFunctions(const std::string &dll)
|
||||
{
|
||||
//reset all stored info:
|
||||
this->mappedDllName = dll;
|
||||
if (this->addrToFunc.size() > 0) {
|
||||
this->addrToFunc.clear();
|
||||
}
|
||||
this->notFound.clear();
|
||||
|
||||
const size_t coveredCount = map_addresses_to_functions(this->addresses, dll, this->exportsMap, this->addrToFunc, this->notFound);
|
||||
#ifdef _DEBUG
|
||||
if (notFound.size()) {
|
||||
std::cout << "[-] Not all addresses are covered! Not found: " << std::dec << notFound.size() << std::endl;
|
||||
} else {
|
||||
|
||||
std::cout << "All covered!" << std::endl;
|
||||
}
|
||||
#endif
|
||||
return coveredCount;
|
||||
}
|
||||
|
||||
void ImpsNotCovered::insert(ULONGLONG thunk, ULONGLONG searchedAddr)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "[-] Function not recovered: [" << std::hex << searchedAddr << "] " << std::endl;
|
||||
#endif
|
||||
thunkToAddr[thunk] = searchedAddr;
|
||||
}
|
||||
|
||||
|
||||
bool peconv::fix_imports(IN OUT PVOID modulePtr, IN size_t moduleSize, IN const peconv::ExportsMapper& exportsMap, OUT OPTIONAL peconv::ImpsNotCovered* notCovered)
|
||||
{
|
||||
bool skip_bound = false; // skip boud imports?
|
||||
IMAGE_DATA_DIRECTORY *importsDir = peconv::get_directory_entry((const BYTE*) modulePtr, IMAGE_DIRECTORY_ENTRY_IMPORT);
|
||||
if (importsDir == NULL) {
|
||||
return true; // done! no imports -> nothing to fix
|
||||
}
|
||||
bool is64 = peconv::is64bit((BYTE*)modulePtr);
|
||||
DWORD maxSize = importsDir->Size;
|
||||
DWORD impAddr = importsDir->VirtualAddress;
|
||||
|
||||
IMAGE_IMPORT_DESCRIPTOR* lib_desc = NULL;
|
||||
DWORD parsedSize = 0;
|
||||
#ifdef _DEBUG
|
||||
printf("---IMP---\n");
|
||||
#endif
|
||||
|
||||
while (parsedSize < maxSize) {
|
||||
|
||||
lib_desc = (IMAGE_IMPORT_DESCRIPTOR*)(impAddr + parsedSize + (ULONG_PTR) modulePtr);
|
||||
if (!validate_ptr(modulePtr, moduleSize, lib_desc, sizeof(IMAGE_IMPORT_DESCRIPTOR))) {
|
||||
printf("[-] Invalid descriptor pointer!\n");
|
||||
return false;
|
||||
}
|
||||
parsedSize += sizeof(IMAGE_IMPORT_DESCRIPTOR);
|
||||
if (lib_desc->OriginalFirstThunk == NULL && lib_desc->FirstThunk == NULL) {
|
||||
break;
|
||||
}
|
||||
const bool is_bound = (lib_desc->TimeDateStamp == (-1));
|
||||
if (is_bound && skip_bound) {
|
||||
continue;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
printf("Imported Lib: %x : %x : %x\n", lib_desc->FirstThunk, lib_desc->OriginalFirstThunk, lib_desc->Name);
|
||||
#endif
|
||||
|
||||
std::string lib_name = "";
|
||||
if (lib_desc->Name != 0) {
|
||||
LPSTR name_ptr = (LPSTR)((ULONGLONG) modulePtr + lib_desc->Name);
|
||||
if (validate_ptr(modulePtr, moduleSize, name_ptr, sizeof(char) * MIN_DLL_LEN)) {
|
||||
lib_name = (LPSTR)((ULONGLONG) modulePtr + lib_desc->Name);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD call_via = lib_desc->FirstThunk;
|
||||
DWORD thunk_addr = lib_desc->OriginalFirstThunk; // warning: it can be NULL!
|
||||
std::set<ULONGLONG> addresses;
|
||||
if (!is64) {
|
||||
find_addresses_to_fill<DWORD>(call_via, thunk_addr, modulePtr, moduleSize, exportsMap, addresses);
|
||||
} else {
|
||||
find_addresses_to_fill<ULONGLONG>(call_via, thunk_addr, modulePtr, moduleSize, exportsMap, addresses);
|
||||
}
|
||||
ImportedDllCoverage dllCoverage(addresses, exportsMap);
|
||||
bool is_all_covered = dllCoverage.findCoveringDll();
|
||||
bool is_lib_erased = false;
|
||||
|
||||
lib_name = get_dll_shortname(lib_name); //without extension
|
||||
|
||||
if (lib_name.length() == 0) {
|
||||
is_lib_erased = true;
|
||||
if (is_all_covered) {
|
||||
// set a name of the covering DLL:
|
||||
lib_name = dllCoverage.dllName;
|
||||
}
|
||||
}
|
||||
if (lib_name.length() == 0) {
|
||||
//could not find a relevant DLL
|
||||
continue;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << lib_name << std::endl;
|
||||
#endif
|
||||
if (!dllCoverage.mapAddressesToFunctions(lib_name)) {
|
||||
// cannot find any functions imported from this DLL
|
||||
continue;
|
||||
}
|
||||
//everything mapped, now recover it:
|
||||
ImportsUneraser impUneraser(modulePtr, moduleSize);
|
||||
if (!impUneraser.uneraseDllImports(lib_desc, dllCoverage, notCovered)) {
|
||||
return false;
|
||||
}
|
||||
if (is_lib_erased) {
|
||||
const std::string dll_with_ext = exportsMap.get_dll_fullname(dllCoverage.dllName);
|
||||
impUneraser.uneraseDllName(lib_desc, dll_with_ext);
|
||||
}
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << "---------" << std::endl;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "peconv/function_resolver.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
FARPROC peconv::default_func_resolver::resolve_func(LPSTR lib_name, LPSTR func_name)
|
||||
{
|
||||
HMODULE libBasePtr = LoadLibraryA(lib_name);
|
||||
if (libBasePtr == NULL) {
|
||||
std::cerr << "Could not load the library!" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
FARPROC hProc = GetProcAddress(libBasePtr, func_name);
|
||||
if (hProc == NULL) {
|
||||
std::cerr << "Could not load the function!" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
return hProc;
|
||||
}
|
||||
224
ai_anti_malware/libpeconv/libpeconv/src/hooks.cpp
Normal file
224
ai_anti_malware/libpeconv/libpeconv/src/hooks.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
#include "peconv/hooks.h"
|
||||
#include "peconv.h"
|
||||
#include "peconv/peb_lookup.h"
|
||||
|
||||
using namespace peconv;
|
||||
|
||||
namespace peconv {
|
||||
|
||||
bool is_pointer_in_ntdll(LPVOID lpAddress)
|
||||
{
|
||||
HMODULE mod = peconv::get_module_via_peb((LPWSTR)L"ntdll.dll");
|
||||
size_t module_size = peconv::get_module_size_via_peb(mod);
|
||||
if (peconv::validate_ptr(mod, module_size, lpAddress, sizeof(BYTE))) {
|
||||
return true; //this address lies within NTDLL
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL nt_protect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect)
|
||||
{
|
||||
FARPROC proc = peconv::get_exported_func(
|
||||
peconv::get_module_via_peb((LPWSTR)L"ntdll.dll"),
|
||||
(LPSTR)"NtProtectVirtualMemory"
|
||||
);
|
||||
if (!proc) {
|
||||
return FALSE;
|
||||
}
|
||||
NTSTATUS(NTAPI *_NtProtectVirtualMemory)(
|
||||
IN HANDLE,
|
||||
IN OUT PVOID*,
|
||||
IN OUT PSIZE_T,
|
||||
IN DWORD,
|
||||
OUT PDWORD) =
|
||||
(NTSTATUS(NTAPI *)(
|
||||
IN HANDLE,
|
||||
IN OUT PVOID*,
|
||||
IN OUT PSIZE_T,
|
||||
IN DWORD,
|
||||
OUT PDWORD)) proc;
|
||||
|
||||
SIZE_T protect_size = dwSize;
|
||||
NTSTATUS status = _NtProtectVirtualMemory(GetCurrentProcess(), &lpAddress, &protect_size, flNewProtect, lpflOldProtect);
|
||||
if (status != S_OK) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
bool PatchBackup::makeBackup(BYTE *patch_ptr, size_t patch_size)
|
||||
{
|
||||
if (!patch_ptr) {
|
||||
return false;
|
||||
}
|
||||
deleteBackup();
|
||||
this->sourcePtr = patch_ptr;
|
||||
this->buffer = new BYTE[patch_size];
|
||||
this->bufferSize = patch_size;
|
||||
|
||||
memcpy(buffer, patch_ptr, patch_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PatchBackup::applyBackup()
|
||||
{
|
||||
if (!isBackup()) {
|
||||
return false;
|
||||
}
|
||||
DWORD oldProtect = 0;
|
||||
if (!nt_protect((LPVOID)sourcePtr, bufferSize, PAGE_EXECUTE_READWRITE, &oldProtect)) {
|
||||
return false;
|
||||
}
|
||||
memcpy(sourcePtr, buffer, bufferSize);
|
||||
nt_protect((LPVOID)sourcePtr, bufferSize, oldProtect, &oldProtect);
|
||||
|
||||
//flush cache:
|
||||
FlushInstructionCache(GetCurrentProcess(), sourcePtr, bufferSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
FARPROC peconv::hooking_func_resolver::resolve_func(LPSTR lib_name, LPSTR func_name)
|
||||
{
|
||||
//the name may be ordinal rather than string, so check if it is a valid pointer:
|
||||
if (!IsBadReadPtr(func_name, 1)) {
|
||||
std::map<std::string, FARPROC>::iterator itr = hooks_map.find(func_name);
|
||||
if (itr != hooks_map.end()) {
|
||||
FARPROC hook = itr->second;
|
||||
#ifdef _DEBUG
|
||||
std::cout << ">>>>>>Replacing: " << func_name << " by: " << hook << std::endl;
|
||||
#endif
|
||||
return hook;
|
||||
}
|
||||
}
|
||||
return peconv::default_func_resolver::resolve_func(lib_name, func_name);
|
||||
}
|
||||
|
||||
size_t peconv::redirect_to_local64(void *ptr, ULONGLONG new_offset, PatchBackup* backup)
|
||||
{
|
||||
if (!ptr) return 0;
|
||||
|
||||
BYTE hook_64[] = {
|
||||
0x48, 0xB8, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xEE, 0xFF, //movabs rax,FFEE998877665544
|
||||
0xFF, 0xE0 //jmp rax
|
||||
};
|
||||
const size_t hook64_size = sizeof(hook_64);
|
||||
if (is_pointer_in_ntdll(ptr)) {
|
||||
std::cout << "[WARNING] Patching NTDLL is not allowed because of possible stability issues!\n";
|
||||
return 0;
|
||||
}
|
||||
DWORD oldProtect = 0;
|
||||
if (!nt_protect((LPVOID)ptr,
|
||||
hook64_size,
|
||||
PAGE_EXECUTE_READWRITE, //this must be executable if we are hooking kernel32.dll, because we are using VirtualProtect from kernel32 at the same time
|
||||
&oldProtect))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (backup != nullptr) {
|
||||
backup->makeBackup((BYTE*)ptr, hook64_size);
|
||||
}
|
||||
memcpy(hook_64 + 2, &new_offset, sizeof(ULONGLONG));
|
||||
memcpy(ptr, hook_64, hook64_size);
|
||||
|
||||
nt_protect((LPVOID)ptr, hook64_size, oldProtect, &oldProtect);
|
||||
|
||||
//flush cache:
|
||||
FlushInstructionCache(GetCurrentProcess(), ptr, hook64_size);
|
||||
return hook64_size;
|
||||
}
|
||||
|
||||
size_t peconv::redirect_to_local32(void *ptr, DWORD new_offset, PatchBackup* backup)
|
||||
{
|
||||
if (!ptr) return 0;
|
||||
|
||||
BYTE hook_32[] = {
|
||||
0xB8, 0xCC, 0xDD, 0xEE, 0xFF, // mov eax,FFEEDDCC
|
||||
0xFF, 0xE0 //jmp eax
|
||||
};
|
||||
const size_t hook32_size = sizeof(hook_32);
|
||||
if (is_pointer_in_ntdll(ptr)) {
|
||||
std::cout << "[WARNING] Patching NTDLL is not allowed because of possible stability issues!\n";
|
||||
return 0;
|
||||
}
|
||||
DWORD oldProtect = 0;
|
||||
if (!nt_protect((LPVOID)ptr,
|
||||
hook32_size,
|
||||
PAGE_EXECUTE_READWRITE, //this must be executable if we are hooking kernel32.dll, because we are using VirtualProtect from kernel32 at the same time
|
||||
&oldProtect))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (backup != nullptr) {
|
||||
backup->makeBackup((BYTE*)ptr, hook32_size);
|
||||
}
|
||||
memcpy(hook_32 + 1, &new_offset, sizeof(DWORD));
|
||||
memcpy(ptr, hook_32, hook32_size);
|
||||
|
||||
nt_protect((LPVOID)ptr, hook32_size, oldProtect, &oldProtect);
|
||||
|
||||
//flush cache:
|
||||
FlushInstructionCache(GetCurrentProcess(), ptr, hook32_size);
|
||||
return hook32_size;
|
||||
}
|
||||
|
||||
size_t peconv::redirect_to_local(void *ptr, void* new_function_ptr, PatchBackup* backup)
|
||||
{
|
||||
#ifdef _WIN64
|
||||
return peconv::redirect_to_local64(ptr, (ULONGLONG)new_function_ptr, backup);
|
||||
#else
|
||||
return peconv::redirect_to_local32(ptr, (DWORD)new_function_ptr, backup);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline long long int get_jmp_delta(ULONGLONG currVA, int instrLen, ULONGLONG destVA)
|
||||
{
|
||||
long long int diff = destVA - (currVA + instrLen);
|
||||
return diff;
|
||||
}
|
||||
|
||||
inline bool is_valid_delta(long long int delta)
|
||||
{
|
||||
DWORD first_dw = delta >> sizeof(DWORD) * 8;
|
||||
if (first_dw == 0) {
|
||||
return true;
|
||||
}
|
||||
const DWORD max_dword = DWORD(-1);
|
||||
if (first_dw != max_dword) {
|
||||
return false;
|
||||
}
|
||||
DWORD delta_dw = DWORD(delta);
|
||||
if (delta_dw & 0x80000000) {
|
||||
return true;
|
||||
}
|
||||
//invalid, sign bit is missing
|
||||
return false;
|
||||
}
|
||||
|
||||
bool peconv::replace_target(BYTE *patch_ptr, ULONGLONG dest_addr)
|
||||
{
|
||||
typedef enum {
|
||||
OP_JMP = 0xE9,
|
||||
OP_CALL_DWORD = 0xE8
|
||||
} t_opcode;
|
||||
|
||||
if (patch_ptr[0] == OP_JMP || patch_ptr[0] == OP_CALL_DWORD) {
|
||||
ULONGLONG delta = get_jmp_delta(ULONGLONG(patch_ptr), 5, dest_addr);
|
||||
if (!is_valid_delta(delta)) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Cannot replace the target: too big delta: " << std::hex << delta << std::endl;
|
||||
#endif
|
||||
//too big delta, cannot be saved in a DWORD
|
||||
return false;
|
||||
}
|
||||
DWORD delta_dw = DWORD(delta);
|
||||
memcpy(patch_ptr + 1, &delta_dw, sizeof(DWORD));
|
||||
|
||||
//flush cache:
|
||||
FlushInstructionCache(GetCurrentProcess(), patch_ptr + 1, sizeof(DWORD));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
254
ai_anti_malware/libpeconv/libpeconv/src/imports_loader.cpp
Normal file
254
ai_anti_malware/libpeconv/libpeconv/src/imports_loader.cpp
Normal file
@@ -0,0 +1,254 @@
|
||||
#include "peconv/imports_loader.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace peconv;
|
||||
|
||||
class FillImportThunks : public ImportThunksCallback
|
||||
{
|
||||
public:
|
||||
FillImportThunks(BYTE* _modulePtr, size_t _moduleSize, t_function_resolver* func_resolver)
|
||||
: ImportThunksCallback(_modulePtr, _moduleSize), funcResolver(func_resolver)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool processThunks(LPSTR lib_name, ULONG_PTR origFirstThunkPtr, ULONG_PTR firstThunkPtr)
|
||||
{
|
||||
if (this->is64b) {
|
||||
IMAGE_THUNK_DATA64* desc = reinterpret_cast<IMAGE_THUNK_DATA64*>(origFirstThunkPtr);
|
||||
ULONGLONG* call_via = reinterpret_cast<ULONGLONG*>(firstThunkPtr);
|
||||
return processThunks_tpl<ULONGLONG, IMAGE_THUNK_DATA64>(lib_name, desc, call_via, IMAGE_ORDINAL_FLAG64);
|
||||
}
|
||||
else {
|
||||
IMAGE_THUNK_DATA32* desc = reinterpret_cast<IMAGE_THUNK_DATA32*>(origFirstThunkPtr);
|
||||
DWORD* call_via = reinterpret_cast<DWORD*>(firstThunkPtr);
|
||||
return processThunks_tpl<DWORD, IMAGE_THUNK_DATA32>(lib_name, desc, call_via, IMAGE_ORDINAL_FLAG32);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename T_FIELD, typename T_IMAGE_THUNK_DATA>
|
||||
bool processThunks_tpl(LPSTR lib_name, T_IMAGE_THUNK_DATA* desc, T_FIELD* call_via, T_FIELD ordinal_flag)
|
||||
{
|
||||
if (!this->funcResolver) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_by_ord = (desc->u1.Ordinal & ordinal_flag) != 0;
|
||||
|
||||
FARPROC hProc = nullptr;
|
||||
if (is_by_ord) {
|
||||
|
||||
T_FIELD raw_ordinal = desc->u1.Ordinal & (~ordinal_flag);
|
||||
#ifdef _DEBUG
|
||||
std::cout << "raw ordinal: " << std::hex << raw_ordinal << std::endl;
|
||||
#endif
|
||||
|
||||
//hProc = funcResolver->resolve_func(lib_name, MAKEINTRESOURCEA(raw_ordinal));
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
PIMAGE_IMPORT_BY_NAME by_name = (PIMAGE_IMPORT_BY_NAME)((ULONGLONG)modulePtr + desc->u1.AddressOfData);
|
||||
LPSTR func_name = reinterpret_cast<LPSTR>(by_name->Name);
|
||||
#ifdef _DEBUG
|
||||
std::cout << "name: " << func_name << std::endl;
|
||||
#endif
|
||||
hProc = this->funcResolver->resolve_func(lib_name, func_name);
|
||||
}
|
||||
if (!hProc) {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Could not resolve the function!" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
(*call_via) = reinterpret_cast<T_FIELD>(hProc);
|
||||
return true;
|
||||
}
|
||||
|
||||
//fields:
|
||||
t_function_resolver* funcResolver;
|
||||
};
|
||||
|
||||
|
||||
template <typename T_FIELD, typename T_IMAGE_THUNK_DATA>
|
||||
bool process_imp_functions_tpl(BYTE* modulePtr, size_t module_size, LPSTR lib_name, DWORD call_via, DWORD thunk_addr, IN ImportThunksCallback *callback)
|
||||
{
|
||||
bool is_ok = true;
|
||||
|
||||
T_FIELD *thunks = (T_FIELD*)((ULONGLONG)modulePtr + thunk_addr);
|
||||
T_FIELD *callers = (T_FIELD*)((ULONGLONG)modulePtr + call_via);
|
||||
|
||||
for (size_t index = 0; true; index++) {
|
||||
if (!validate_ptr(modulePtr, module_size, &callers[index], sizeof(T_FIELD))) {
|
||||
break;
|
||||
}
|
||||
if (!validate_ptr(modulePtr, module_size, &thunks[index], sizeof(T_FIELD))) {
|
||||
break;
|
||||
}
|
||||
if (callers[index] == 0) {
|
||||
//nothing to fill, probably the last record
|
||||
return true;
|
||||
}
|
||||
LPVOID thunk_ptr = &thunks[index];
|
||||
T_IMAGE_THUNK_DATA* desc = reinterpret_cast<T_IMAGE_THUNK_DATA*>(thunk_ptr);
|
||||
if (!validate_ptr(modulePtr, module_size, desc, sizeof(T_IMAGE_THUNK_DATA))) {
|
||||
break;
|
||||
}
|
||||
if (desc->u1.Function == NULL) {
|
||||
break;
|
||||
}
|
||||
T_FIELD ordinal_flag = (sizeof(T_FIELD) == sizeof(ULONGLONG)) ? IMAGE_ORDINAL_FLAG64 : IMAGE_ORDINAL_FLAG32;
|
||||
bool is_by_ord = (desc->u1.Ordinal & ordinal_flag) != 0;
|
||||
if (!is_by_ord) {
|
||||
PIMAGE_IMPORT_BY_NAME by_name = (PIMAGE_IMPORT_BY_NAME)((ULONGLONG)modulePtr + desc->u1.AddressOfData);
|
||||
if (!validate_ptr(modulePtr, module_size, by_name, sizeof(IMAGE_IMPORT_BY_NAME))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
//when the callback is called, all the pointers should be already verified
|
||||
if (!callback->processThunks(lib_name, (ULONG_PTR)&thunks[index], (ULONG_PTR)&callers[index])) {
|
||||
is_ok = false;
|
||||
}
|
||||
}
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
//Walk through the table of imported DLLs (starting from the given descriptor) and execute the callback each time when the new record was found
|
||||
bool process_dlls(BYTE* modulePtr, size_t module_size, IMAGE_IMPORT_DESCRIPTOR *first_desc, IN ImportThunksCallback *callback)
|
||||
{
|
||||
bool isAllFilled = true;
|
||||
#ifdef _DEBUG
|
||||
std::cout << "---IMP---" << std::endl;
|
||||
#endif
|
||||
const bool is64 = is64bit((BYTE*)modulePtr);
|
||||
IMAGE_IMPORT_DESCRIPTOR* lib_desc = nullptr;
|
||||
|
||||
for (size_t i = 0; true; i++) {
|
||||
lib_desc = &first_desc[i];
|
||||
if (!validate_ptr(modulePtr, module_size, lib_desc, sizeof(IMAGE_IMPORT_DESCRIPTOR))) {
|
||||
break;
|
||||
}
|
||||
if (lib_desc->OriginalFirstThunk == NULL && lib_desc->FirstThunk == NULL) {
|
||||
break;
|
||||
}
|
||||
LPSTR lib_name = (LPSTR)((ULONGLONG)modulePtr + lib_desc->Name);
|
||||
if (!peconv::is_valid_import_name(modulePtr, module_size, lib_name)) {
|
||||
//invalid name
|
||||
return false;
|
||||
}
|
||||
DWORD call_via = lib_desc->FirstThunk;
|
||||
DWORD thunk_addr = lib_desc->OriginalFirstThunk;
|
||||
if (thunk_addr == NULL) {
|
||||
thunk_addr = lib_desc->FirstThunk;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Imported Lib: " << std::hex << lib_desc->FirstThunk << " : " << std::hex << lib_desc->OriginalFirstThunk << " : " << lib_desc->Name << std::endl;
|
||||
#endif
|
||||
size_t all_solved = false;
|
||||
if (is64) {
|
||||
all_solved = process_imp_functions_tpl<ULONGLONG, IMAGE_THUNK_DATA64>(modulePtr, module_size, lib_name, call_via, thunk_addr, callback);
|
||||
}
|
||||
else {
|
||||
all_solved = process_imp_functions_tpl<DWORD, IMAGE_THUNK_DATA32>(modulePtr, module_size, lib_name, call_via, thunk_addr, callback);
|
||||
}
|
||||
if (!all_solved) {
|
||||
isAllFilled = false;
|
||||
}
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
printf("---------\n");
|
||||
#endif
|
||||
return isAllFilled;
|
||||
}
|
||||
|
||||
bool peconv::process_import_table(IN BYTE* modulePtr, IN SIZE_T moduleSize, IN ImportThunksCallback *callback)
|
||||
{
|
||||
if (moduleSize == 0) { //if not given, try to fetch
|
||||
moduleSize = peconv::get_image_size((const BYTE*)modulePtr);
|
||||
}
|
||||
if (moduleSize == 0) return false;
|
||||
|
||||
IMAGE_DATA_DIRECTORY *importsDir = get_directory_entry((BYTE*)modulePtr, IMAGE_DIRECTORY_ENTRY_IMPORT);
|
||||
if (!importsDir) {
|
||||
return true; //no import table
|
||||
}
|
||||
const DWORD impAddr = importsDir->VirtualAddress;
|
||||
IMAGE_IMPORT_DESCRIPTOR *first_desc = (IMAGE_IMPORT_DESCRIPTOR*)(impAddr + (ULONG_PTR)modulePtr);
|
||||
if (!peconv::validate_ptr(modulePtr, moduleSize, first_desc, sizeof(IMAGE_IMPORT_DESCRIPTOR))) {
|
||||
return false;
|
||||
}
|
||||
return process_dlls(modulePtr, moduleSize, first_desc, callback);
|
||||
}
|
||||
|
||||
bool peconv::load_imports(BYTE* modulePtr, t_function_resolver* func_resolver)
|
||||
{
|
||||
size_t moduleSize = peconv::get_image_size((const BYTE*)modulePtr);
|
||||
if (moduleSize == 0) return false;
|
||||
|
||||
bool is64 = is64bit((BYTE*)modulePtr);
|
||||
default_func_resolver default_res;
|
||||
if (!func_resolver) {
|
||||
func_resolver = (t_function_resolver*)&default_res;
|
||||
}
|
||||
|
||||
FillImportThunks callback(modulePtr, moduleSize, func_resolver);
|
||||
return peconv::process_import_table(modulePtr, moduleSize, &callback);
|
||||
}
|
||||
|
||||
// A valid name must contain printable characters. Empty name is also acceptable (may have been erased)
|
||||
bool peconv::is_valid_import_name(const PBYTE modulePtr, const size_t moduleSize, LPSTR lib_name)
|
||||
{
|
||||
while (true) {
|
||||
if (!peconv::validate_ptr(modulePtr, moduleSize, lib_name, sizeof(char))) {
|
||||
return false;
|
||||
}
|
||||
char next_char = *lib_name;
|
||||
if (next_char == '\0') break;
|
||||
|
||||
if (next_char <= 0x20 || next_char >= 0x7E) {
|
||||
return false;
|
||||
}
|
||||
lib_name++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool peconv::has_valid_import_table(const PBYTE modulePtr, size_t moduleSize)
|
||||
{
|
||||
IMAGE_DATA_DIRECTORY *importsDir = get_directory_entry((BYTE*)modulePtr, IMAGE_DIRECTORY_ENTRY_IMPORT);
|
||||
if (importsDir == NULL) return false;
|
||||
|
||||
const DWORD impAddr = importsDir->VirtualAddress;
|
||||
|
||||
IMAGE_IMPORT_DESCRIPTOR* lib_desc = NULL;
|
||||
DWORD parsedSize = 0;
|
||||
size_t valid_records = 0;
|
||||
|
||||
while (true) { //size of the import table doesn't matter
|
||||
lib_desc = (IMAGE_IMPORT_DESCRIPTOR*)(impAddr + parsedSize + (ULONG_PTR)modulePtr);
|
||||
if (!peconv::validate_ptr(modulePtr, moduleSize, lib_desc, sizeof(IMAGE_IMPORT_DESCRIPTOR))) {
|
||||
return false;
|
||||
}
|
||||
parsedSize += sizeof(IMAGE_IMPORT_DESCRIPTOR);
|
||||
|
||||
if (lib_desc->OriginalFirstThunk == NULL && lib_desc->FirstThunk == NULL) {
|
||||
break;
|
||||
}
|
||||
LPSTR lib_name = (LPSTR)((ULONGLONG)modulePtr + lib_desc->Name);
|
||||
if (!is_valid_import_name(modulePtr, moduleSize, lib_name)) return false;
|
||||
|
||||
DWORD call_via = lib_desc->FirstThunk;
|
||||
DWORD thunk_addr = lib_desc->OriginalFirstThunk;
|
||||
if (thunk_addr == NULL) thunk_addr = lib_desc->FirstThunk;
|
||||
|
||||
DWORD *thunks = (DWORD*)((ULONGLONG)modulePtr + thunk_addr);
|
||||
if (!peconv::validate_ptr(modulePtr, moduleSize, thunks, sizeof(DWORD))) return false;
|
||||
|
||||
DWORD *callers = (DWORD*)((ULONGLONG)modulePtr + call_via);
|
||||
if (!peconv::validate_ptr(modulePtr, moduleSize, callers, sizeof(DWORD))) return false;
|
||||
|
||||
valid_records++;
|
||||
}
|
||||
|
||||
return (valid_records > 0);
|
||||
}
|
||||
243
ai_anti_malware/libpeconv/libpeconv/src/imports_uneraser.cpp
Normal file
243
ai_anti_malware/libpeconv/libpeconv/src/imports_uneraser.cpp
Normal file
@@ -0,0 +1,243 @@
|
||||
#include "peconv/imports_uneraser.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace peconv;
|
||||
|
||||
LPVOID search_name(std::string name, const char* modulePtr, size_t moduleSize)
|
||||
{
|
||||
const char* namec = name.c_str();
|
||||
const size_t searched_len = name.length() + 1; // with terminating NULL
|
||||
const char* found_ptr = std::search(modulePtr, modulePtr + moduleSize, namec, namec + searched_len);
|
||||
if (found_ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
size_t o = found_ptr - modulePtr;
|
||||
if (o < moduleSize) {
|
||||
return (LPVOID)(found_ptr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool ImportsUneraser::writeFoundDllName(IMAGE_IMPORT_DESCRIPTOR* lib_desc, const std::string &found_name)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Found name:" << found_name << std::endl;
|
||||
#endif
|
||||
LPSTR name_ptr = (LPSTR)((ULONGLONG) modulePtr + lib_desc->Name);
|
||||
size_t full_name_len = found_name.length() + 1; // with terminating zero
|
||||
if (!validate_ptr(modulePtr, moduleSize, name_ptr, full_name_len)) {
|
||||
//corner case: allow to save the name at the very end of the buffer, without the terminating zero
|
||||
full_name_len--;
|
||||
if (!validate_ptr(modulePtr, moduleSize, name_ptr, full_name_len)) {
|
||||
return false; //invalid pointer, cannot save
|
||||
}
|
||||
}
|
||||
memcpy(name_ptr, found_name.c_str(), full_name_len);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImportsUneraser::uneraseDllName(IMAGE_IMPORT_DESCRIPTOR* lib_desc, const std::string &dll_name)
|
||||
{
|
||||
LPSTR name_ptr = nullptr;
|
||||
if (lib_desc->Name != 0) {
|
||||
name_ptr = (LPSTR)((ULONGLONG) modulePtr + lib_desc->Name);
|
||||
}
|
||||
if (name_ptr == nullptr || !validate_ptr(modulePtr, moduleSize, name_ptr, sizeof(char) * MIN_DLL_LEN)) {
|
||||
//try to get the cave:
|
||||
DWORD cave_size = DWORD(dll_name.length() + 1 + 5); //ending null + padding
|
||||
PBYTE ptr = find_ending_cave(modulePtr, moduleSize, cave_size);
|
||||
if (ptr == nullptr) {
|
||||
std::cerr << "Cannot save the DLL name: " << dll_name << std::endl;
|
||||
return false;
|
||||
}
|
||||
DWORD cave_rva = static_cast<DWORD>(ptr - modulePtr);
|
||||
lib_desc->Name = cave_rva;
|
||||
}
|
||||
|
||||
if (writeFoundDllName(lib_desc, dll_name)) {
|
||||
return true; // written the found name
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename FIELD_T>
|
||||
bool ImportsUneraser::findNameInBinaryAndFill(IMAGE_IMPORT_DESCRIPTOR* lib_desc,
|
||||
LPVOID call_via_ptr,
|
||||
LPVOID thunk_ptr,
|
||||
const FIELD_T ordinal_flag,
|
||||
std::map<ULONGLONG, std::set<ExportedFunc>> &addr_to_func
|
||||
)
|
||||
{
|
||||
if (call_via_ptr == NULL || modulePtr == NULL || lib_desc == NULL) {
|
||||
return false; //malformed input
|
||||
}
|
||||
IMAGE_DATA_DIRECTORY *importsDir = get_directory_entry((BYTE*)modulePtr, IMAGE_DIRECTORY_ENTRY_IMPORT);
|
||||
if (!importsDir) return false;
|
||||
|
||||
const DWORD impAddr = importsDir->VirtualAddress; //start of the import table
|
||||
|
||||
FIELD_T *call_via_val = (FIELD_T*)call_via_ptr;
|
||||
if (*call_via_val == 0) {
|
||||
//nothing to fill, probably the last record
|
||||
return false;
|
||||
}
|
||||
ULONGLONG searchedAddr = ULONGLONG(*call_via_val);
|
||||
bool is_name_saved = false;
|
||||
|
||||
FIELD_T lastOrdinal = 0; //store also ordinal of the matching function
|
||||
std::set<ExportedFunc>::iterator funcname_itr = addr_to_func[searchedAddr].begin();
|
||||
|
||||
for (funcname_itr = addr_to_func[searchedAddr].begin();
|
||||
funcname_itr != addr_to_func[searchedAddr].end();
|
||||
++funcname_itr)
|
||||
{
|
||||
const ExportedFunc &found_func = *funcname_itr;
|
||||
lastOrdinal = found_func.funcOrdinal;
|
||||
|
||||
const char* names_start = ((const char*) modulePtr + impAddr);
|
||||
BYTE* found_ptr = (BYTE*) search_name(found_func.funcName, names_start, moduleSize - (names_start - (const char*)modulePtr));
|
||||
if (!found_ptr) {
|
||||
//name not found in the binary
|
||||
//TODO: maybe it is imported by ordinal?
|
||||
continue;
|
||||
}
|
||||
|
||||
const ULONGLONG name_offset = (ULONGLONG)found_ptr - (ULONGLONG)modulePtr;
|
||||
#ifdef _DEBUG
|
||||
//if it is not the first name from the list, inform about it:
|
||||
if (funcname_itr != addr_to_func[searchedAddr].begin()) {
|
||||
std::cout << ">[*][" << std::hex << searchedAddr << "] " << found_func.toString() << std::endl;
|
||||
}
|
||||
std::cout <<"[+] Found the name at: " << std::hex << name_offset << std::endl;
|
||||
#endif
|
||||
PIMAGE_IMPORT_BY_NAME imp_field = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(name_offset - sizeof(WORD)); // substract the size of Hint
|
||||
//TODO: validate more...
|
||||
memcpy(thunk_ptr, &imp_field, sizeof(FIELD_T));
|
||||
#ifdef _DEBUG
|
||||
std::cout << "[+] Wrote found to offset: " << std::hex << call_via_ptr << std::endl;
|
||||
#endif
|
||||
is_name_saved = true;
|
||||
break;
|
||||
}
|
||||
//name not found or could not be saved - fill the ordinal instead:
|
||||
if (!is_name_saved && lastOrdinal != 0) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "[+] Filling ordinal: " << lastOrdinal << std::endl;
|
||||
#endif
|
||||
FIELD_T ord_thunk = lastOrdinal | ordinal_flag;
|
||||
memcpy(thunk_ptr, &ord_thunk, sizeof(FIELD_T));
|
||||
is_name_saved = true;
|
||||
}
|
||||
return is_name_saved;
|
||||
}
|
||||
|
||||
template <typename FIELD_T, typename IMAGE_THUNK_DATA_T>
|
||||
bool ImportsUneraser::writeFoundFunction(IMAGE_THUNK_DATA_T* desc, const FIELD_T ordinal_flag, const ExportedFunc &foundFunc)
|
||||
{
|
||||
if (foundFunc.isByOrdinal) {
|
||||
FIELD_T ordinal = foundFunc.funcOrdinal | ordinal_flag;
|
||||
FIELD_T* by_ord = (FIELD_T*) desc;
|
||||
*by_ord = ordinal;
|
||||
#ifdef _DEBUG
|
||||
std::cout << "[+] Saved ordinal" << std::endl;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
PIMAGE_IMPORT_BY_NAME by_name = (PIMAGE_IMPORT_BY_NAME) ((ULONGLONG) modulePtr + desc->u1.AddressOfData);
|
||||
|
||||
LPSTR func_name_ptr = reinterpret_cast<LPSTR>(by_name->Name);
|
||||
std::string found_name = foundFunc.funcName;
|
||||
bool is_nameptr_valid = validate_ptr(modulePtr, moduleSize, func_name_ptr, found_name.length());
|
||||
// try to save the found name under the pointer:
|
||||
if (is_nameptr_valid) {
|
||||
by_name->Hint = MASK_TO_WORD(foundFunc.funcOrdinal);
|
||||
memcpy(func_name_ptr, found_name.c_str(), found_name.length() + 1); // with the ending '\0'
|
||||
#ifdef _DEBUG
|
||||
std::cout << "[+] Saved name" << std::endl;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename FIELD_T, typename IMAGE_THUNK_DATA_T>
|
||||
bool ImportsUneraser::fillImportNames(
|
||||
IN OUT IMAGE_IMPORT_DESCRIPTOR* lib_desc,
|
||||
IN const FIELD_T ordinal_flag,
|
||||
IN std::map<ULONGLONG, std::set<ExportedFunc>> &addr_to_func,
|
||||
OUT OPTIONAL ImpsNotCovered* notCovered
|
||||
)
|
||||
{
|
||||
if (lib_desc == NULL) return false;
|
||||
|
||||
FIELD_T call_via = lib_desc->FirstThunk;
|
||||
if (call_via == NULL) return false;
|
||||
|
||||
size_t processed_imps = 0;
|
||||
size_t recovered_imps = 0;
|
||||
|
||||
FIELD_T thunk_addr = lib_desc->OriginalFirstThunk;
|
||||
if (thunk_addr == NULL) {
|
||||
thunk_addr = call_via;
|
||||
}
|
||||
|
||||
BYTE* call_via_ptr = (BYTE*)((ULONGLONG)modulePtr + call_via);
|
||||
BYTE* thunk_ptr = (BYTE*)((ULONGLONG)modulePtr + thunk_addr);
|
||||
for (;
|
||||
call_via_ptr != NULL && thunk_ptr != NULL;
|
||||
call_via_ptr += sizeof(FIELD_T), thunk_ptr += sizeof(FIELD_T)
|
||||
)
|
||||
{
|
||||
FIELD_T *thunk_val = (FIELD_T*)thunk_ptr;
|
||||
FIELD_T *call_via_val = (FIELD_T*)call_via_ptr;
|
||||
if (*call_via_val == 0) {
|
||||
//nothing to fill, probably the last record
|
||||
break;
|
||||
}
|
||||
IMAGE_THUNK_DATA_T* desc = (IMAGE_THUNK_DATA_T*)thunk_ptr;
|
||||
if (desc->u1.Function == NULL) {
|
||||
break;
|
||||
}
|
||||
ULONGLONG searchedAddr = ULONGLONG(*call_via_val);
|
||||
std::map<ULONGLONG,std::set<ExportedFunc>>::const_iterator found_itr = addr_to_func.find(searchedAddr);
|
||||
if (found_itr == addr_to_func.end() || found_itr->second.size() == 0) {
|
||||
//not found, move on
|
||||
if (notCovered) {
|
||||
notCovered->insert((call_via_ptr - modulePtr), searchedAddr);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
std::set<ExportedFunc>::const_iterator funcname_itr = found_itr->second.begin();
|
||||
const peconv::ExportedFunc &foundFunc = *funcname_itr;
|
||||
|
||||
#ifdef _DEBUG
|
||||
std::cout << "[*][" << std::hex << searchedAddr << "] " << funcname_itr->toString() << std::endl;
|
||||
#endif
|
||||
bool is_name_saved = writeFoundFunction<FIELD_T, IMAGE_THUNK_DATA_T>(desc, ordinal_flag, *funcname_itr);
|
||||
if (!is_name_saved) {
|
||||
is_name_saved = findNameInBinaryAndFill<FIELD_T>(lib_desc, call_via_ptr, thunk_ptr, ordinal_flag, addr_to_func);
|
||||
}
|
||||
processed_imps++;
|
||||
if (is_name_saved) recovered_imps++;
|
||||
}
|
||||
|
||||
return (recovered_imps == processed_imps);
|
||||
}
|
||||
|
||||
bool ImportsUneraser::uneraseDllImports(IN OUT IMAGE_IMPORT_DESCRIPTOR* lib_desc, IN ImportedDllCoverage &dllCoverage, OUT OPTIONAL ImpsNotCovered* notCovered)
|
||||
{
|
||||
//everything mapped, now recover it:
|
||||
bool is_filled = false;
|
||||
if (!is64) {
|
||||
is_filled = fillImportNames<DWORD, IMAGE_THUNK_DATA32>(lib_desc, IMAGE_ORDINAL_FLAG32, dllCoverage.addrToFunc, notCovered);
|
||||
} else {
|
||||
is_filled = fillImportNames<ULONGLONG, IMAGE_THUNK_DATA64>(lib_desc, IMAGE_ORDINAL_FLAG64, dllCoverage.addrToFunc, notCovered);
|
||||
}
|
||||
if (!is_filled) {
|
||||
std::cerr << "[-] Could not fill some import names!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
return is_filled;
|
||||
}
|
||||
57
ai_anti_malware/libpeconv/libpeconv/src/load_config_util.cpp
Normal file
57
ai_anti_malware/libpeconv/libpeconv/src/load_config_util.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#include "peconv/load_config_util.h"
|
||||
#include "peconv/pe_hdrs_helper.h"
|
||||
|
||||
BYTE* peconv::get_load_config_ptr(BYTE* buffer, size_t buf_size)
|
||||
{
|
||||
if (!buffer || !buf_size) return nullptr;
|
||||
IMAGE_DATA_DIRECTORY* dir = peconv::get_directory_entry(buffer, IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG);
|
||||
if (!dir) {
|
||||
return 0;
|
||||
}
|
||||
DWORD entry_rva = dir->VirtualAddress;
|
||||
DWORD entry_size = dir->Size;
|
||||
if (!peconv::validate_ptr(buffer, buf_size, buffer + entry_rva, entry_size)) {
|
||||
return 0;
|
||||
}
|
||||
IMAGE_LOAD_CONFIG_DIRECTORY32* ldc = reinterpret_cast<IMAGE_LOAD_CONFIG_DIRECTORY32*>((ULONG_PTR)buffer + entry_rva);
|
||||
return reinterpret_cast<BYTE*>(ldc);
|
||||
}
|
||||
|
||||
peconv::t_load_config_ver peconv::get_load_config_version(BYTE* buffer, size_t buf_size, BYTE* ld_config_ptr)
|
||||
{
|
||||
if (!buffer || !buf_size || !ld_config_ptr) peconv::LOAD_CONFIG_NONE;
|
||||
bool is64b = peconv::is64bit(buffer);
|
||||
|
||||
if (!peconv::validate_ptr(buffer, buf_size, ld_config_ptr, sizeof(peconv::IMAGE_LOAD_CONFIG_DIR32_W7))) {
|
||||
return peconv::LOAD_CONFIG_NONE;
|
||||
}
|
||||
|
||||
peconv::IMAGE_LOAD_CONFIG_DIR32_W7* smallest = (peconv::IMAGE_LOAD_CONFIG_DIR32_W7*)ld_config_ptr;
|
||||
const size_t curr_size = smallest->Size;
|
||||
|
||||
if (is64b) {
|
||||
switch (curr_size) {
|
||||
case sizeof(peconv::IMAGE_LOAD_CONFIG_DIR64_W7) :
|
||||
return peconv::LOAD_CONFIG_W7_VER;
|
||||
case sizeof(peconv::IMAGE_LOAD_CONFIG_DIR64_W8) :
|
||||
return peconv::LOAD_CONFIG_W8_VER;
|
||||
case sizeof(peconv::IMAGE_LOAD_CONFIG_DIR64_W10) :
|
||||
return peconv::LOAD_CONFIG_W10_VER;
|
||||
default:
|
||||
return LOAD_CONFIG_UNK_VER;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (curr_size) {
|
||||
case sizeof(peconv::IMAGE_LOAD_CONFIG_DIR32_W7) :
|
||||
return peconv::LOAD_CONFIG_W7_VER;
|
||||
case sizeof(peconv::IMAGE_LOAD_CONFIG_DIR32_W8) :
|
||||
return peconv::LOAD_CONFIG_W8_VER;
|
||||
case sizeof(peconv::IMAGE_LOAD_CONFIG_DIR32_W10) :
|
||||
return peconv::LOAD_CONFIG_W10_VER;
|
||||
default:
|
||||
return LOAD_CONFIG_UNK_VER;
|
||||
}
|
||||
}
|
||||
return LOAD_CONFIG_UNK_VER;
|
||||
}
|
||||
4302
ai_anti_malware/libpeconv/libpeconv/src/ntddk.h
Normal file
4302
ai_anti_malware/libpeconv/libpeconv/src/ntddk.h
Normal file
File diff suppressed because it is too large
Load Diff
73
ai_anti_malware/libpeconv/libpeconv/src/pe_dumper.cpp
Normal file
73
ai_anti_malware/libpeconv/libpeconv/src/pe_dumper.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "peconv/pe_dumper.h"
|
||||
|
||||
#include "peconv/pe_hdrs_helper.h"
|
||||
#include "peconv/pe_virtual_to_raw.h"
|
||||
#include "peconv/fix_imports.h"
|
||||
#include "peconv/file_util.h"
|
||||
#include "peconv/pe_mode_detector.h"
|
||||
#include "fix_dot_net_ep.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace peconv;
|
||||
|
||||
t_pe_dump_mode peconv::detect_dump_mode(IN const BYTE* buffer, IN size_t mod_size)
|
||||
{
|
||||
const t_pe_dump_mode default_mode = peconv::PE_DUMP_UNMAP;
|
||||
if (peconv::is_pe_raw(buffer, mod_size)) {
|
||||
return peconv::PE_DUMP_VIRTUAL;
|
||||
}
|
||||
if (peconv::is_pe_expanded(buffer, mod_size)) {
|
||||
return peconv::PE_DUMP_REALIGN;
|
||||
}
|
||||
return default_mode;
|
||||
}
|
||||
|
||||
bool peconv::dump_pe(IN const char *out_path,
|
||||
IN OUT BYTE *buffer, IN size_t mod_size,
|
||||
IN const ULONGLONG start_addr,
|
||||
IN OUT t_pe_dump_mode &dump_mode,
|
||||
IN OPTIONAL const peconv::ExportsMapper* exportsMap
|
||||
)
|
||||
{
|
||||
// if the exportsMap is supplied, attempt to recover the (destroyed) import table:
|
||||
if (exportsMap != nullptr) {
|
||||
if (!peconv::fix_imports(buffer, mod_size, *exportsMap, NULL)) {
|
||||
std::cerr << "[-] Unable to fix imports!" << std::endl;
|
||||
}
|
||||
}
|
||||
if (dump_mode == PE_DUMP_AUTO || dump_mode >= PE_DUMP_MODES_COUNT) {
|
||||
dump_mode = detect_dump_mode(buffer, mod_size);
|
||||
}
|
||||
|
||||
BYTE* dump_data = buffer;
|
||||
size_t dump_size = mod_size;
|
||||
size_t out_size = 0;
|
||||
BYTE* unmapped_module = nullptr;
|
||||
|
||||
if (dump_mode == peconv::PE_DUMP_UNMAP || dump_mode == peconv::PE_DUMP_REALIGN) {
|
||||
//if the image base in headers is invalid, set the current base and prevent from relocating PE:
|
||||
if (peconv::get_image_base(buffer) == 0) {
|
||||
peconv::update_image_base(buffer, (ULONGLONG)start_addr);
|
||||
}
|
||||
if (is_dot_net(buffer, mod_size)) {
|
||||
fix_dot_net_ep(buffer, mod_size);
|
||||
}
|
||||
if (dump_mode == peconv::PE_DUMP_UNMAP) {
|
||||
unmapped_module = pe_virtual_to_raw(buffer, mod_size, (ULONGLONG)start_addr, out_size, false);
|
||||
}
|
||||
else if (dump_mode == peconv::PE_DUMP_REALIGN) {
|
||||
unmapped_module = peconv::pe_realign_raw_to_virtual(buffer, mod_size, (ULONGLONG)start_addr, out_size);
|
||||
}
|
||||
// unmap the PE file (convert from the Virtual Format into Raw Format)
|
||||
if (unmapped_module) {
|
||||
dump_data = unmapped_module;
|
||||
dump_size = out_size;
|
||||
}
|
||||
}
|
||||
// save the read module into a file
|
||||
const bool is_dumped = dump_to_file(out_path, dump_data, dump_size);
|
||||
|
||||
peconv::free_pe_buffer(unmapped_module, mod_size);
|
||||
return is_dumped;
|
||||
}
|
||||
633
ai_anti_malware/libpeconv/libpeconv/src/pe_hdrs_helper.cpp
Normal file
633
ai_anti_malware/libpeconv/libpeconv/src/pe_hdrs_helper.cpp
Normal file
@@ -0,0 +1,633 @@
|
||||
#include "peconv/pe_hdrs_helper.h"
|
||||
|
||||
using namespace peconv;
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
BYTE* peconv::get_nt_hdrs(IN const BYTE *pe_buffer, IN OPTIONAL size_t buffer_size)
|
||||
{
|
||||
if (!pe_buffer) return nullptr;
|
||||
|
||||
IMAGE_DOS_HEADER *idh = (IMAGE_DOS_HEADER*)pe_buffer;
|
||||
if (buffer_size != 0) {
|
||||
if (!peconv::validate_ptr((LPVOID)pe_buffer, buffer_size, (LPVOID)idh, sizeof(IMAGE_DOS_HEADER))) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
if (IsBadReadPtr(idh, sizeof(IMAGE_DOS_HEADER))) {
|
||||
return nullptr;
|
||||
}
|
||||
if (idh->e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
return nullptr;
|
||||
}
|
||||
const LONG kMaxOffset = 1024;
|
||||
LONG pe_offset = idh->e_lfanew;
|
||||
|
||||
if (pe_offset > kMaxOffset) return nullptr;
|
||||
|
||||
IMAGE_NT_HEADERS32 *inh = (IMAGE_NT_HEADERS32 *)(pe_buffer + pe_offset);
|
||||
if (buffer_size != 0) {
|
||||
if (!peconv::validate_ptr((LPVOID)pe_buffer, buffer_size, (LPVOID)inh, sizeof(IMAGE_NT_HEADERS32))) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
if (IsBadReadPtr(inh, sizeof(IMAGE_NT_HEADERS32))) {
|
||||
return nullptr;
|
||||
}
|
||||
if (inh->Signature != IMAGE_NT_SIGNATURE) {
|
||||
return nullptr;
|
||||
}
|
||||
return (BYTE*)inh;
|
||||
}
|
||||
|
||||
IMAGE_NT_HEADERS32* peconv::get_nt_hdrs32(IN const BYTE *payload)
|
||||
{
|
||||
if (!payload) return nullptr;
|
||||
|
||||
BYTE *ptr = get_nt_hdrs(payload);
|
||||
if (!ptr) return nullptr;
|
||||
|
||||
if (!is64bit(payload)) {
|
||||
return (IMAGE_NT_HEADERS32*)ptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IMAGE_NT_HEADERS64* peconv::get_nt_hdrs64(IN const BYTE *payload)
|
||||
{
|
||||
if (payload == nullptr) return nullptr;
|
||||
|
||||
BYTE *ptr = get_nt_hdrs(payload);
|
||||
if (!ptr) return nullptr;
|
||||
|
||||
if (is64bit(payload)) {
|
||||
return (IMAGE_NT_HEADERS64*)ptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DWORD peconv::get_image_size(IN const BYTE *payload)
|
||||
{
|
||||
if (!get_nt_hdrs(payload)) {
|
||||
return 0;
|
||||
}
|
||||
DWORD image_size = 0;
|
||||
if (is64bit(payload)) {
|
||||
IMAGE_NT_HEADERS64* nt64 = get_nt_hdrs64(payload);
|
||||
image_size = nt64->OptionalHeader.SizeOfImage;
|
||||
} else {
|
||||
IMAGE_NT_HEADERS32* nt32 = get_nt_hdrs32(payload);
|
||||
image_size = nt32->OptionalHeader.SizeOfImage;
|
||||
}
|
||||
return image_size;
|
||||
}
|
||||
|
||||
bool peconv::update_image_size(IN OUT BYTE* payload, IN DWORD image_size)
|
||||
{
|
||||
if (!get_nt_hdrs(payload)) {
|
||||
return false;
|
||||
}
|
||||
if (is64bit(payload)) {
|
||||
IMAGE_NT_HEADERS64* nt64 = get_nt_hdrs64(payload);
|
||||
nt64->OptionalHeader.SizeOfImage = image_size;
|
||||
}
|
||||
else {
|
||||
IMAGE_NT_HEADERS32* nt32 = get_nt_hdrs32(payload);
|
||||
nt32->OptionalHeader.SizeOfImage = image_size;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
WORD peconv::get_nt_hdr_architecture(IN const BYTE *pe_buffer)
|
||||
{
|
||||
void *ptr = get_nt_hdrs(pe_buffer);
|
||||
if (!ptr) return 0;
|
||||
|
||||
IMAGE_NT_HEADERS32 *inh = static_cast<IMAGE_NT_HEADERS32*>(ptr);
|
||||
if (IsBadReadPtr(inh, sizeof(IMAGE_NT_HEADERS32))) {
|
||||
return 0;
|
||||
}
|
||||
return inh->OptionalHeader.Magic;
|
||||
}
|
||||
|
||||
bool peconv::is64bit(IN const BYTE *pe_buffer)
|
||||
{
|
||||
WORD arch = get_nt_hdr_architecture(pe_buffer);
|
||||
if (arch == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
IMAGE_DATA_DIRECTORY* peconv::get_directory_entry(IN const BYTE *pe_buffer, IN DWORD dir_id, IN bool allow_empty)
|
||||
{
|
||||
if (dir_id >= IMAGE_NUMBEROF_DIRECTORY_ENTRIES) return nullptr;
|
||||
|
||||
BYTE* nt_headers = get_nt_hdrs((BYTE*)pe_buffer);
|
||||
if (!nt_headers) return nullptr;
|
||||
|
||||
IMAGE_DATA_DIRECTORY* peDir = nullptr;
|
||||
if (is64bit(pe_buffer)) {
|
||||
IMAGE_NT_HEADERS64* nt_headers64 = (IMAGE_NT_HEADERS64*)nt_headers;
|
||||
peDir = &(nt_headers64->OptionalHeader.DataDirectory[dir_id]);
|
||||
}
|
||||
else {
|
||||
IMAGE_NT_HEADERS32* nt_headers64 = (IMAGE_NT_HEADERS32*)nt_headers;
|
||||
peDir = &(nt_headers64->OptionalHeader.DataDirectory[dir_id]);
|
||||
}
|
||||
if (!allow_empty && peDir->VirtualAddress == NULL) {
|
||||
return nullptr;
|
||||
}
|
||||
return peDir;
|
||||
}
|
||||
|
||||
ULONGLONG peconv::get_image_base(IN const BYTE *pe_buffer)
|
||||
{
|
||||
bool is64b = is64bit(pe_buffer);
|
||||
//update image base in the written content:
|
||||
BYTE* payload_nt_hdr = get_nt_hdrs(pe_buffer);
|
||||
if (!payload_nt_hdr) {
|
||||
return 0;
|
||||
}
|
||||
ULONGLONG img_base = 0;
|
||||
if (is64b) {
|
||||
IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*)payload_nt_hdr;
|
||||
img_base = payload_nt_hdr64->OptionalHeader.ImageBase;
|
||||
} else {
|
||||
IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*)payload_nt_hdr;
|
||||
img_base = static_cast<ULONGLONG>(payload_nt_hdr32->OptionalHeader.ImageBase);
|
||||
}
|
||||
return img_base;
|
||||
}
|
||||
|
||||
DWORD peconv::get_entry_point_rva(IN const BYTE *pe_buffer)
|
||||
{
|
||||
bool is64b = is64bit(pe_buffer);
|
||||
//update image base in the written content:
|
||||
BYTE* payload_nt_hdr = get_nt_hdrs(pe_buffer);
|
||||
if (!payload_nt_hdr) {
|
||||
return 0;
|
||||
}
|
||||
DWORD value = 0;
|
||||
if (is64b) {
|
||||
IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*)payload_nt_hdr;
|
||||
value = payload_nt_hdr64->OptionalHeader.AddressOfEntryPoint;
|
||||
} else {
|
||||
IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*)payload_nt_hdr;
|
||||
value = payload_nt_hdr32->OptionalHeader.AddressOfEntryPoint;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool peconv::update_entry_point_rva(IN OUT BYTE *pe_buffer, IN DWORD value)
|
||||
{
|
||||
bool is64b = is64bit(pe_buffer);
|
||||
//update image base in the written content:
|
||||
BYTE* payload_nt_hdr = get_nt_hdrs(pe_buffer);
|
||||
if (!payload_nt_hdr) {
|
||||
return false;
|
||||
}
|
||||
if (is64b) {
|
||||
IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*)payload_nt_hdr;
|
||||
payload_nt_hdr64->OptionalHeader.AddressOfEntryPoint = value;
|
||||
} else {
|
||||
IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*)payload_nt_hdr;
|
||||
payload_nt_hdr32->OptionalHeader.AddressOfEntryPoint = value;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD peconv::get_hdrs_size(IN const BYTE *pe_buffer)
|
||||
{
|
||||
bool is64b = is64bit(pe_buffer);
|
||||
BYTE* payload_nt_hdr = get_nt_hdrs(pe_buffer);
|
||||
if (!payload_nt_hdr) {
|
||||
return 0;
|
||||
}
|
||||
DWORD hdrs_size = 0;
|
||||
if (is64b) {
|
||||
IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*)payload_nt_hdr;
|
||||
hdrs_size = payload_nt_hdr64->OptionalHeader.SizeOfHeaders;
|
||||
} else {
|
||||
IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*)payload_nt_hdr;
|
||||
hdrs_size = payload_nt_hdr32->OptionalHeader.SizeOfHeaders;
|
||||
}
|
||||
return hdrs_size;
|
||||
}
|
||||
|
||||
bool peconv::update_image_base(IN OUT BYTE* payload, IN ULONGLONG destImageBase)
|
||||
{
|
||||
bool is64b = is64bit(payload);
|
||||
BYTE* payload_nt_hdr = get_nt_hdrs(payload);
|
||||
if (!payload_nt_hdr) {
|
||||
return false;
|
||||
}
|
||||
if (is64b) {
|
||||
IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*)payload_nt_hdr;
|
||||
payload_nt_hdr64->OptionalHeader.ImageBase = (ULONGLONG)destImageBase;
|
||||
}
|
||||
else {
|
||||
IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*)payload_nt_hdr;
|
||||
payload_nt_hdr32->OptionalHeader.ImageBase = (DWORD)destImageBase;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename IMAGE_NT_HEADERS_T>
|
||||
inline const IMAGE_FILE_HEADER* fetch_file_hdr(IN const BYTE* payload, IN const size_t buffer_size, IN const IMAGE_NT_HEADERS_T *payload_nt_hdr)
|
||||
{
|
||||
if (!payload || !payload_nt_hdr) return nullptr;
|
||||
|
||||
const IMAGE_FILE_HEADER *fileHdr = &(payload_nt_hdr->FileHeader);
|
||||
|
||||
if (!validate_ptr((const LPVOID)payload, buffer_size, (const LPVOID)fileHdr, sizeof(IMAGE_FILE_HEADER))) {
|
||||
return nullptr;
|
||||
}
|
||||
return fileHdr;
|
||||
}
|
||||
|
||||
const IMAGE_FILE_HEADER* peconv::get_file_hdr(IN const BYTE* payload, IN const size_t buffer_size)
|
||||
{
|
||||
if (!payload) return nullptr;
|
||||
|
||||
BYTE* payload_nt_hdr = get_nt_hdrs(payload);
|
||||
if (!payload_nt_hdr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (is64bit(payload)) {
|
||||
return fetch_file_hdr(payload, buffer_size, (IMAGE_NT_HEADERS64*)payload_nt_hdr);
|
||||
}
|
||||
return fetch_file_hdr(payload, buffer_size, (IMAGE_NT_HEADERS32*)payload_nt_hdr);
|
||||
}
|
||||
|
||||
template <typename IMAGE_NT_HEADERS_T>
|
||||
inline const LPVOID fetch_opt_hdr(IN const BYTE* payload, IN const size_t buffer_size, IN const IMAGE_NT_HEADERS_T *payload_nt_hdr)
|
||||
{
|
||||
if (!payload) return nullptr;
|
||||
|
||||
const IMAGE_FILE_HEADER *fileHdr = fetch_file_hdr<IMAGE_NT_HEADERS_T>(payload, buffer_size, payload_nt_hdr);
|
||||
if (!fileHdr) {
|
||||
return nullptr;
|
||||
}
|
||||
const LPVOID opt_hdr = (const LPVOID) &(payload_nt_hdr->OptionalHeader);
|
||||
const size_t opt_size = fileHdr->SizeOfOptionalHeader;
|
||||
if (!validate_ptr((const LPVOID)payload, buffer_size, opt_hdr, opt_size)) {
|
||||
return nullptr;
|
||||
}
|
||||
return opt_hdr;
|
||||
}
|
||||
|
||||
LPVOID peconv::get_optional_hdr(IN const BYTE* payload, IN const size_t buffer_size)
|
||||
{
|
||||
if (!payload) return nullptr;
|
||||
|
||||
BYTE* payload_nt_hdr = get_nt_hdrs(payload);
|
||||
const IMAGE_FILE_HEADER* fileHdr = get_file_hdr(payload, buffer_size);
|
||||
if (!payload_nt_hdr || !fileHdr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (is64bit(payload)) {
|
||||
return fetch_opt_hdr<IMAGE_NT_HEADERS64>(payload,buffer_size, (IMAGE_NT_HEADERS64*)payload_nt_hdr);
|
||||
}
|
||||
return fetch_opt_hdr<IMAGE_NT_HEADERS32>(payload, buffer_size, (IMAGE_NT_HEADERS32*)payload_nt_hdr);
|
||||
}
|
||||
|
||||
template <typename IMAGE_NT_HEADERS_T>
|
||||
inline LPVOID fetch_section_hdrs_ptr(IN const BYTE* payload, IN const size_t buffer_size, IN const IMAGE_NT_HEADERS_T *payload_nt_hdr)
|
||||
{
|
||||
const IMAGE_FILE_HEADER *fileHdr = fetch_file_hdr<IMAGE_NT_HEADERS_T>(payload, buffer_size, payload_nt_hdr);
|
||||
if (!fileHdr) {
|
||||
return nullptr;
|
||||
}
|
||||
const size_t opt_size = fileHdr->SizeOfOptionalHeader;
|
||||
BYTE* opt_hdr = (BYTE*)fetch_opt_hdr(payload, buffer_size, payload_nt_hdr);
|
||||
if (!validate_ptr((const LPVOID)payload, buffer_size, opt_hdr, opt_size)) {
|
||||
return nullptr;
|
||||
}
|
||||
//sections headers starts right after the end of the optional header
|
||||
return (LPVOID)(opt_hdr + opt_size);
|
||||
}
|
||||
|
||||
size_t peconv::get_sections_count(IN const BYTE* payload, IN const size_t buffer_size)
|
||||
{
|
||||
const IMAGE_FILE_HEADER* fileHdr = get_file_hdr(payload, buffer_size);
|
||||
if (!fileHdr) {
|
||||
return 0;
|
||||
}
|
||||
return fileHdr->NumberOfSections;
|
||||
}
|
||||
|
||||
bool peconv::is_valid_sections_hdr_offset(IN const BYTE* buffer, IN const size_t buffer_size)
|
||||
{
|
||||
size_t sec_count = peconv::get_sections_count(buffer, buffer_size);
|
||||
if (sec_count == 0) {
|
||||
//no sections found - a valid PE should have at least one section
|
||||
return false;
|
||||
}
|
||||
PIMAGE_SECTION_HEADER last_hdr = get_section_hdr(buffer, buffer_size, sec_count - 1);
|
||||
if (!last_hdr) {
|
||||
//could not fetch the last section
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PIMAGE_SECTION_HEADER peconv::get_section_hdr(IN const BYTE* payload, IN const size_t buffer_size, IN size_t section_num)
|
||||
{
|
||||
if (!payload) return nullptr;
|
||||
|
||||
const size_t sections_count = peconv::get_sections_count(payload, buffer_size);
|
||||
if (section_num >= sections_count) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LPVOID nt_hdrs = peconv::get_nt_hdrs(payload);
|
||||
if (!nt_hdrs) return nullptr; //this should never happened, because the get_sections_count did not fail
|
||||
|
||||
LPVOID secptr = nullptr;
|
||||
//get the beginning of sections headers:
|
||||
if (is64bit(payload)) {
|
||||
secptr = fetch_section_hdrs_ptr<IMAGE_NT_HEADERS64>(payload, buffer_size, (IMAGE_NT_HEADERS64*)nt_hdrs);
|
||||
}
|
||||
else {
|
||||
secptr = fetch_section_hdrs_ptr<IMAGE_NT_HEADERS32>(payload, buffer_size, (IMAGE_NT_HEADERS32*)nt_hdrs);
|
||||
}
|
||||
//get the section header of given number:
|
||||
PIMAGE_SECTION_HEADER next_sec = (PIMAGE_SECTION_HEADER)(
|
||||
(ULONGLONG)secptr + (IMAGE_SIZEOF_SECTION_HEADER * section_num)
|
||||
);
|
||||
//validate pointer:
|
||||
if (!validate_ptr((const LPVOID) payload, buffer_size, (const LPVOID) next_sec, sizeof(IMAGE_SECTION_HEADER))) {
|
||||
return nullptr;
|
||||
}
|
||||
return next_sec;
|
||||
}
|
||||
|
||||
WORD peconv::get_file_characteristics(IN const BYTE* payload)
|
||||
{
|
||||
if (!payload) return 0;
|
||||
|
||||
bool is64b = is64bit(payload);
|
||||
BYTE* payload_nt_hdr = get_nt_hdrs(payload);
|
||||
if (!payload_nt_hdr) {
|
||||
return 0;
|
||||
}
|
||||
IMAGE_FILE_HEADER *fileHdr = nullptr;
|
||||
if (is64b) {
|
||||
IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*)payload_nt_hdr;
|
||||
fileHdr = &(payload_nt_hdr64->FileHeader);
|
||||
}
|
||||
else {
|
||||
IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*)payload_nt_hdr;
|
||||
fileHdr = &(payload_nt_hdr32->FileHeader);
|
||||
}
|
||||
return fileHdr->Characteristics;
|
||||
}
|
||||
|
||||
bool peconv::is_module_dll(IN const BYTE* payload)
|
||||
{
|
||||
if (!payload) return false;
|
||||
WORD charact = get_file_characteristics(payload);
|
||||
return ((charact & IMAGE_FILE_DLL) != 0);
|
||||
}
|
||||
|
||||
WORD peconv::get_dll_characteristics(IN const BYTE* payload)
|
||||
{
|
||||
if (!payload) return 0;
|
||||
|
||||
bool is64b = is64bit(payload);
|
||||
BYTE* payload_nt_hdr = get_nt_hdrs(payload);
|
||||
if (!payload_nt_hdr) {
|
||||
return 0;
|
||||
}
|
||||
WORD charact = 0;
|
||||
if (is64b) {
|
||||
IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*)payload_nt_hdr;
|
||||
charact = payload_nt_hdr64->OptionalHeader.DllCharacteristics;
|
||||
}
|
||||
else {
|
||||
IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*)payload_nt_hdr;
|
||||
charact = payload_nt_hdr32->OptionalHeader.DllCharacteristics;
|
||||
}
|
||||
return charact;
|
||||
}
|
||||
|
||||
bool peconv::set_subsystem(IN OUT BYTE* payload, IN WORD subsystem)
|
||||
{
|
||||
if (!payload) return false;
|
||||
|
||||
bool is64b = is64bit(payload);
|
||||
BYTE* payload_nt_hdr = get_nt_hdrs(payload);
|
||||
if (!payload_nt_hdr) {
|
||||
return false;
|
||||
}
|
||||
if (is64b) {
|
||||
IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*)payload_nt_hdr;
|
||||
payload_nt_hdr64->OptionalHeader.Subsystem = subsystem;
|
||||
} else {
|
||||
IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*)payload_nt_hdr;
|
||||
payload_nt_hdr32->OptionalHeader.Subsystem = subsystem;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
WORD peconv::get_subsystem(IN const BYTE* payload)
|
||||
{
|
||||
if (!payload) return 0;
|
||||
|
||||
bool is64b = is64bit(payload);
|
||||
BYTE* payload_nt_hdr = get_nt_hdrs(payload);
|
||||
if (payload_nt_hdr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (is64b) {
|
||||
IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*)payload_nt_hdr;
|
||||
return payload_nt_hdr64->OptionalHeader.Subsystem;
|
||||
} else {
|
||||
IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*)payload_nt_hdr;
|
||||
return payload_nt_hdr32->OptionalHeader.Subsystem;
|
||||
}
|
||||
}
|
||||
|
||||
bool peconv::has_relocations(IN const BYTE *pe_buffer)
|
||||
{
|
||||
IMAGE_DATA_DIRECTORY* relocDir = get_directory_entry(pe_buffer, IMAGE_DIRECTORY_ENTRY_BASERELOC);
|
||||
if (!relocDir) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
IMAGE_EXPORT_DIRECTORY* peconv::get_export_directory(IN HMODULE modulePtr)
|
||||
{
|
||||
return get_type_directory<IMAGE_EXPORT_DIRECTORY>(modulePtr, IMAGE_DIRECTORY_ENTRY_EXPORT);
|
||||
}
|
||||
|
||||
|
||||
IMAGE_COR20_HEADER * peconv::get_dotnet_hdr(IN const BYTE* module, IN size_t const module_size, IN const IMAGE_DATA_DIRECTORY * dotNetDir)
|
||||
{
|
||||
DWORD rva = dotNetDir->VirtualAddress;
|
||||
DWORD hdr_size = dotNetDir->Size;
|
||||
if (!peconv::validate_ptr(module, module_size, module + rva, hdr_size)) {
|
||||
return nullptr;
|
||||
}
|
||||
IMAGE_COR20_HEADER *dnet_hdr = (IMAGE_COR20_HEADER*)(module + rva);
|
||||
if (!peconv::validate_ptr(module, module_size, module + dnet_hdr->MetaData.VirtualAddress, dnet_hdr->MetaData.Size)) {
|
||||
return nullptr;
|
||||
}
|
||||
DWORD* signature_ptr = (DWORD*)(module + dnet_hdr->MetaData.VirtualAddress);
|
||||
const DWORD dotNetSign = 0x424A5342;
|
||||
if (*signature_ptr != dotNetSign) {
|
||||
//invalid header
|
||||
return nullptr;
|
||||
}
|
||||
return dnet_hdr;
|
||||
}
|
||||
|
||||
template <typename IMAGE_NT_HEADERS_T>
|
||||
DWORD* _get_sec_alignment_ptr(const BYTE* modulePtr, bool is_raw)
|
||||
{
|
||||
IMAGE_NT_HEADERS_T* hdrs = reinterpret_cast<IMAGE_NT_HEADERS_T*>(peconv::get_nt_hdrs(modulePtr));
|
||||
if (!hdrs) return nullptr;
|
||||
if (is_raw) {
|
||||
return &hdrs->OptionalHeader.FileAlignment;
|
||||
}
|
||||
return &hdrs->OptionalHeader.SectionAlignment;
|
||||
}
|
||||
|
||||
DWORD peconv::get_sec_alignment(IN const BYTE* modulePtr, IN bool is_raw)
|
||||
{
|
||||
DWORD* alignment = 0;
|
||||
if (peconv::is64bit(modulePtr)) {
|
||||
alignment = _get_sec_alignment_ptr<IMAGE_NT_HEADERS64>(modulePtr, is_raw);
|
||||
} else {
|
||||
alignment = _get_sec_alignment_ptr<IMAGE_NT_HEADERS32>(modulePtr, is_raw);
|
||||
}
|
||||
if (!alignment) return 0;
|
||||
return *alignment;
|
||||
}
|
||||
|
||||
bool peconv::set_sec_alignment(IN OUT BYTE* modulePtr, IN bool is_raw, IN DWORD new_alignment)
|
||||
{
|
||||
DWORD* alignment = 0;
|
||||
if (peconv::is64bit(modulePtr)) {
|
||||
alignment = _get_sec_alignment_ptr<IMAGE_NT_HEADERS64>(modulePtr, is_raw);
|
||||
}
|
||||
else {
|
||||
alignment = _get_sec_alignment_ptr<IMAGE_NT_HEADERS32>(modulePtr, is_raw);
|
||||
}
|
||||
if (!alignment) return false;
|
||||
|
||||
*alignment = new_alignment;
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD peconv::get_virtual_sec_size(IN const BYTE* pe_hdr, IN const PIMAGE_SECTION_HEADER sec_hdr, IN bool rounded)
|
||||
{
|
||||
if (!pe_hdr || !sec_hdr) {
|
||||
return 0;
|
||||
}
|
||||
if (!rounded) {
|
||||
return sec_hdr->Misc.VirtualSize;;
|
||||
}
|
||||
//TODO: calculate real size, round up to Virtual Alignment
|
||||
DWORD alignment = peconv::get_sec_alignment((const PBYTE)pe_hdr, false);
|
||||
DWORD vsize = sec_hdr->Misc.VirtualSize;
|
||||
|
||||
DWORD units = vsize / alignment;
|
||||
if ((vsize % alignment) > 0) units++;
|
||||
|
||||
vsize = units * alignment;
|
||||
|
||||
DWORD image_size = peconv::get_image_size(pe_hdr);
|
||||
//if it is bigger than the image size, use the size from the headers
|
||||
if ((sec_hdr->VirtualAddress + vsize) > image_size) {
|
||||
vsize = sec_hdr->Misc.VirtualSize;
|
||||
}
|
||||
return vsize;
|
||||
}
|
||||
|
||||
PIMAGE_SECTION_HEADER peconv::get_last_section(IN const PBYTE pe_buffer, IN size_t pe_size, IN bool is_raw)
|
||||
{
|
||||
SIZE_T module_end = peconv::get_hdrs_size(pe_buffer);
|
||||
const size_t sections_count = peconv::get_sections_count(pe_buffer, pe_size);
|
||||
if (sections_count == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
PIMAGE_SECTION_HEADER last_sec = nullptr;
|
||||
//walk through sections
|
||||
for (size_t i = 0; i < sections_count; i++) {
|
||||
PIMAGE_SECTION_HEADER sec = peconv::get_section_hdr(pe_buffer, pe_size, i);
|
||||
if (!sec) break;
|
||||
|
||||
size_t new_end = is_raw ? (sec->PointerToRawData + sec->SizeOfRawData) : (sec->VirtualAddress + sec->Misc.VirtualSize);
|
||||
if (new_end > module_end) {
|
||||
module_end = new_end;
|
||||
last_sec = sec;
|
||||
}
|
||||
}
|
||||
return last_sec;
|
||||
}
|
||||
|
||||
DWORD peconv::calc_pe_size(IN const PBYTE pe_buffer, IN size_t pe_size, IN bool is_raw)
|
||||
{
|
||||
DWORD module_end = peconv::get_hdrs_size(pe_buffer);
|
||||
const size_t sections_count = peconv::get_sections_count(pe_buffer, pe_size);
|
||||
if (sections_count == 0) {
|
||||
return module_end;
|
||||
}
|
||||
//walk through sections
|
||||
for (size_t i = 0; i < sections_count; i++) {
|
||||
PIMAGE_SECTION_HEADER sec = peconv::get_section_hdr(pe_buffer, pe_size, i);
|
||||
if (!sec) break;
|
||||
|
||||
DWORD new_end = is_raw ? (sec->PointerToRawData + sec->SizeOfRawData) : (sec->VirtualAddress + sec->Misc.VirtualSize);
|
||||
if (new_end > module_end) module_end = new_end;
|
||||
}
|
||||
return module_end;
|
||||
}
|
||||
|
||||
bool peconv::is_valid_sectons_alignment(IN const BYTE* payload, IN const SIZE_T payload_size, IN bool is_raw)
|
||||
{
|
||||
if (payload == NULL) return false;
|
||||
|
||||
const DWORD my_align = peconv::get_sec_alignment(payload, is_raw);
|
||||
if (my_align == 0) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Section alignment cannot be 0\n";
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
const size_t sections_count = peconv::get_sections_count(payload, payload_size);
|
||||
if (sections_count == 0) {
|
||||
//no sections
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < sections_count; i++) {
|
||||
PIMAGE_SECTION_HEADER next_sec = peconv::get_section_hdr(payload, payload_size, i);
|
||||
if (!next_sec) return false; //the number of the sections in header is out of scope
|
||||
|
||||
const DWORD next_sec_addr = is_raw ? (next_sec->PointerToRawData) : (next_sec->VirtualAddress);
|
||||
|
||||
SIZE_T sec_size = is_raw ? next_sec->SizeOfRawData : next_sec->Misc.VirtualSize;
|
||||
if (sec_size == 0) continue;
|
||||
if (next_sec->Misc.VirtualSize == 0) {
|
||||
continue; // if the VirtualSize == 0 the section will not be mapped anyways
|
||||
}
|
||||
if (next_sec_addr == 0) {
|
||||
//if cannot be 0 if the size is not 0
|
||||
return false;
|
||||
}
|
||||
|
||||
//check only if raw_align is non-zero
|
||||
if (my_align && next_sec_addr % my_align != 0) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Section is misaligned\n";
|
||||
#endif
|
||||
return false; //misaligned
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
122
ai_anti_malware/libpeconv/libpeconv/src/pe_loader.cpp
Normal file
122
ai_anti_malware/libpeconv/libpeconv/src/pe_loader.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
#include "peconv/pe_loader.h"
|
||||
|
||||
#include "peconv/relocate.h"
|
||||
#include "peconv/imports_loader.h"
|
||||
#include "peconv/buffer_util.h"
|
||||
#include "peconv/function_resolver.h"
|
||||
#include "peconv/exports_lookup.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace peconv;
|
||||
|
||||
namespace peconv {
|
||||
BYTE* load_no_sec_pe(BYTE* dllRawData, size_t r_size, OUT size_t &v_size, bool executable)
|
||||
{
|
||||
ULONGLONG desired_base = 0;
|
||||
size_t out_size = (r_size < PAGE_SIZE) ? PAGE_SIZE : r_size;
|
||||
if (executable) {
|
||||
desired_base = get_image_base(dllRawData);
|
||||
out_size = peconv::get_image_size(dllRawData);
|
||||
}
|
||||
DWORD protect = (executable) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
|
||||
BYTE* mappedPE = peconv::alloc_pe_buffer(out_size, protect, desired_base);
|
||||
if (!mappedPE) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(mappedPE, dllRawData, r_size);
|
||||
v_size = out_size;
|
||||
return mappedPE;
|
||||
}
|
||||
};
|
||||
|
||||
BYTE* peconv::load_pe_module(BYTE* dllRawData, size_t r_size, OUT size_t &v_size, bool executable, bool relocate)
|
||||
{
|
||||
if (!peconv::get_nt_hdrs(dllRawData)) {
|
||||
return NULL;
|
||||
}
|
||||
if (peconv::get_sections_count(dllRawData, r_size) == 0) {
|
||||
return load_no_sec_pe(dllRawData, r_size, v_size, executable);
|
||||
}
|
||||
// by default, allow to load the PE at any base:
|
||||
ULONGLONG desired_base = NULL;
|
||||
// if relocating is required, but the PE has no relocation table...
|
||||
if (relocate && !has_relocations(dllRawData)) {
|
||||
// ...enforce loading the PE image at its default base (so that it will need no relocations)
|
||||
desired_base = get_image_base(dllRawData);
|
||||
}
|
||||
// load a virtual image of the PE file at the desired_base address (random if desired_base is NULL):
|
||||
BYTE *mappedDLL = pe_raw_to_virtual(dllRawData, r_size, v_size, executable, desired_base);
|
||||
if (mappedDLL) {
|
||||
//if the image was loaded at its default base, relocate_module will return always true (because relocating is already done)
|
||||
if (relocate && !relocate_module(mappedDLL, v_size, (ULONGLONG)mappedDLL)) {
|
||||
// relocating was required, but it failed - thus, the full PE image is useless
|
||||
printf("Could not relocate the module!");
|
||||
free_pe_buffer(mappedDLL, v_size);
|
||||
mappedDLL = NULL;
|
||||
}
|
||||
} else {
|
||||
printf("Could not allocate memory at the desired base!\n");
|
||||
}
|
||||
return mappedDLL;
|
||||
}
|
||||
|
||||
BYTE* peconv::load_pe_module(const char *filename, OUT size_t &v_size, bool executable, bool relocate)
|
||||
{
|
||||
size_t r_size = 0;
|
||||
BYTE *dllRawData = load_file(filename, r_size);
|
||||
if (!dllRawData) {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Cannot load the file: " << filename << std::endl;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
BYTE* mappedPE = load_pe_module(dllRawData, r_size, v_size, executable, relocate);
|
||||
free_pe_buffer(dllRawData);
|
||||
return mappedPE;
|
||||
}
|
||||
|
||||
BYTE* peconv::load_pe_executable(BYTE* dllRawData, size_t r_size, OUT size_t &v_size, t_function_resolver* import_resolver)
|
||||
{
|
||||
BYTE* loaded_pe = load_pe_module(dllRawData, r_size, v_size, true, true);
|
||||
if (!loaded_pe) {
|
||||
printf("[-] Loading failed!\n");
|
||||
return NULL;
|
||||
}
|
||||
#if _DEBUG
|
||||
printf("Loaded at: %p\n", loaded_pe);
|
||||
#endif
|
||||
if (has_valid_import_table(loaded_pe, v_size)) {
|
||||
if (!load_imports(loaded_pe, import_resolver)) {
|
||||
printf("[-] Loading imports failed!");
|
||||
free_pe_buffer(loaded_pe, v_size);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("[-] PE doesn't have a valid Import Table!\n");
|
||||
}
|
||||
return loaded_pe;
|
||||
}
|
||||
|
||||
|
||||
BYTE* peconv::load_pe_executable(const char *my_path, OUT size_t &v_size, t_function_resolver* import_resolver)
|
||||
{
|
||||
#if _DEBUG
|
||||
printf("Module: %s\n", my_path);
|
||||
#endif
|
||||
BYTE* loaded_pe = load_pe_module(my_path, v_size, true, true);
|
||||
if (!loaded_pe) {
|
||||
printf("Loading failed!\n");
|
||||
return NULL;
|
||||
}
|
||||
#if _DEBUG
|
||||
printf("Loaded at: %p\n", loaded_pe);
|
||||
#endif
|
||||
if (!load_imports(loaded_pe, import_resolver)) {
|
||||
printf("[-] Loading imports failed!");
|
||||
free_pe_buffer(loaded_pe, v_size);
|
||||
return NULL;
|
||||
}
|
||||
return loaded_pe;
|
||||
}
|
||||
205
ai_anti_malware/libpeconv/libpeconv/src/pe_mode_detector.cpp
Normal file
205
ai_anti_malware/libpeconv/libpeconv/src/pe_mode_detector.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
#include "peconv/pe_mode_detector.h"
|
||||
#include "peconv/util.h"
|
||||
#include "peconv/imports_loader.h"
|
||||
#include "peconv/relocate.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
// Check if gaps between sections are typical for Virtual Alignment.
|
||||
// Returns true if confirmed, false if not confirmed. False result can also mean that data was invalid/insufficient to decide.
|
||||
bool is_virtual_padding(const BYTE* pe_buffer, size_t pe_size)
|
||||
{
|
||||
const size_t r_align = peconv::get_sec_alignment((PBYTE)pe_buffer, true);
|
||||
|
||||
size_t sections_count = peconv::get_sections_count(pe_buffer, pe_size);
|
||||
if (sections_count < 2) return false;
|
||||
|
||||
bool is_valid_padding = false;
|
||||
for (size_t i = 1; i < sections_count; i += 2) {
|
||||
PIMAGE_SECTION_HEADER sec1 = peconv::get_section_hdr(pe_buffer, pe_size, i-1);
|
||||
PIMAGE_SECTION_HEADER sec2 = peconv::get_section_hdr(pe_buffer, pe_size, i);
|
||||
if (!sec1 || !sec2) continue; //skip if fetching any of the sections failed
|
||||
|
||||
if (sec1->SizeOfRawData == 0) continue; //skip empty sections
|
||||
|
||||
const DWORD sec1_end_offset = sec1->VirtualAddress + sec1->SizeOfRawData;
|
||||
if (sec2->VirtualAddress == sec1_end_offset) continue;
|
||||
|
||||
if (sec2->VirtualAddress < sec1_end_offset) {
|
||||
//std::cout << "Invalid size of the section: " << std::hex << sec2->VirtualAddress << " vs "<< sec1_end_offset << std::endl;
|
||||
return false;
|
||||
}
|
||||
const size_t diff = sec2->VirtualAddress - sec1_end_offset;
|
||||
if (diff < r_align) continue; //to small to determine
|
||||
|
||||
BYTE* sec1_end_ptr = (BYTE*)((ULONGLONG)pe_buffer + sec1_end_offset);
|
||||
if (!peconv::validate_ptr((const LPVOID)pe_buffer, pe_size, sec1_end_ptr, diff)) {
|
||||
//std::cout << "Invalid pointer to the section\n";
|
||||
return false;
|
||||
}
|
||||
if (peconv::is_padding(sec1_end_ptr, diff, 0)) {
|
||||
is_valid_padding = true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return is_valid_padding;
|
||||
}
|
||||
|
||||
// Check if the gap between the end of headers and the first section is typical for Virtual Alignment.
|
||||
// Returns true if confirmed, false if not confirmed. False result can also mean that data was invalid/insufficient to decide.
|
||||
bool is_hdr_virtual_align(const BYTE* pe_buffer, size_t pe_size)
|
||||
{
|
||||
const size_t v_align = peconv::get_sec_alignment((PBYTE)pe_buffer, false);
|
||||
if (peconv::get_hdrs_size(pe_buffer) >= v_align) {
|
||||
//undetermined for such case
|
||||
return false;
|
||||
}
|
||||
//walk through sections and check their sizes
|
||||
size_t sections_count = peconv::get_sections_count(pe_buffer, pe_size);
|
||||
if (sections_count == 0) return false;
|
||||
for (size_t i = 0; i < sections_count; i++) {
|
||||
PIMAGE_SECTION_HEADER sec = peconv::get_section_hdr(pe_buffer, pe_size, i);
|
||||
if (!sec || sec->PointerToRawData == 0 || sec->SizeOfRawData == 0) {
|
||||
continue; // check next
|
||||
}
|
||||
if (sec->PointerToRawData >= v_align) continue;
|
||||
|
||||
size_t diff = v_align - sec->PointerToRawData;
|
||||
BYTE* sec_raw_ptr = (BYTE*)((ULONGLONG)pe_buffer + sec->PointerToRawData);
|
||||
if (!peconv::validate_ptr((const LPVOID)pe_buffer, pe_size, sec_raw_ptr, diff)) {
|
||||
return false;
|
||||
}
|
||||
if (peconv::is_padding(sec_raw_ptr, diff, 0)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sec_hdrs_erased(IN const BYTE* pe_buffer, IN size_t pe_size, bool is_raw)
|
||||
{
|
||||
const size_t count = peconv::get_sections_count(pe_buffer, pe_size);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const IMAGE_SECTION_HEADER* hdr = peconv::get_section_hdr(pe_buffer, pe_size, i);
|
||||
if (!hdr) continue;
|
||||
if (is_raw) {
|
||||
if (hdr->PointerToRawData != 0) return false;
|
||||
}
|
||||
else {
|
||||
if (hdr->VirtualAddress != 0) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool peconv::is_pe_raw_eq_virtual(IN const BYTE* pe_buffer, IN size_t pe_size)
|
||||
{
|
||||
const size_t count = peconv::get_sections_count(pe_buffer, pe_size);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const IMAGE_SECTION_HEADER* hdr = peconv::get_section_hdr(pe_buffer, pe_size, i);
|
||||
if (!hdr) continue;
|
||||
|
||||
if (hdr->VirtualAddress != hdr->PointerToRawData) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_pe_mapped(IN const BYTE* pe_buffer, IN size_t pe_size)
|
||||
{
|
||||
size_t v_score = 0;
|
||||
if (peconv::has_valid_import_table((const PBYTE)pe_buffer, pe_size)) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Valid Import Table found" << std::endl;
|
||||
#endif
|
||||
v_score++;
|
||||
}
|
||||
if (peconv::has_valid_relocation_table((const PBYTE)pe_buffer, pe_size)) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Valid Relocations Table found" << std::endl;
|
||||
#endif
|
||||
v_score++;
|
||||
}
|
||||
if (is_hdr_virtual_align(pe_buffer, pe_size)) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Header virtual align OK" << std::endl;
|
||||
#endif
|
||||
v_score++;
|
||||
}
|
||||
if (is_virtual_padding(pe_buffer, pe_size)) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Virtual Padding OK" << std::endl;
|
||||
#endif
|
||||
v_score++;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << "TOTAL v_score: " << std::dec << v_score << std::endl;
|
||||
#endif
|
||||
if (v_score > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool peconv::is_pe_raw(IN const BYTE* pe_buffer, IN size_t pe_size)
|
||||
{
|
||||
if (peconv::get_sections_count(pe_buffer, pe_size) == 0) {
|
||||
return true;
|
||||
}
|
||||
if (is_pe_mapped(pe_buffer, pe_size)) {
|
||||
// it has artefacts typical for a PE in a virtual alignment
|
||||
return false;
|
||||
}
|
||||
if (sec_hdrs_erased(pe_buffer, pe_size, true)) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Raw alignment is erased\n";
|
||||
#endif
|
||||
// the raw alignment of the sections is erased
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// checks if any of the executable sections has been expanded in the memory
|
||||
bool peconv::is_pe_expanded(IN const BYTE* pe_buffer, IN size_t pe_size)
|
||||
{
|
||||
//walk through sections and check their sizes
|
||||
size_t sections_count = peconv::get_sections_count(pe_buffer, pe_size);
|
||||
for (size_t i = 0; i < sections_count; i++) {
|
||||
PIMAGE_SECTION_HEADER sec = peconv::get_section_hdr(pe_buffer, pe_size, i);
|
||||
//scan only executable sections
|
||||
if ((sec->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0) {
|
||||
if (is_section_expanded(pe_buffer, pe_size, sec)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// checks if the section's content in memory is bigger than in the raw format
|
||||
bool peconv::is_section_expanded(IN const BYTE* pe_buffer, IN size_t pe_size, IN const PIMAGE_SECTION_HEADER sec)
|
||||
{
|
||||
if (!sec) return false;
|
||||
|
||||
size_t sec_vsize = peconv::get_virtual_sec_size(pe_buffer, sec, true);
|
||||
size_t sec_rsize = sec->SizeOfRawData;
|
||||
|
||||
if (sec_rsize >= sec_vsize) return false;
|
||||
size_t diff = sec_vsize - sec_rsize;
|
||||
|
||||
BYTE* sec_raw_end_ptr = (BYTE*)((ULONGLONG)pe_buffer + sec->VirtualAddress + sec_rsize);
|
||||
if (!peconv::validate_ptr((const LPVOID)pe_buffer, pe_size, sec_raw_end_ptr, diff)) {
|
||||
return false;
|
||||
}
|
||||
if (!is_padding(sec_raw_end_ptr, diff, 0)) {
|
||||
//this is not padding: non-zero content detected
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
140
ai_anti_malware/libpeconv/libpeconv/src/pe_raw_to_virtual.cpp
Normal file
140
ai_anti_malware/libpeconv/libpeconv/src/pe_raw_to_virtual.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#include "peconv/pe_raw_to_virtual.h"
|
||||
|
||||
#include "peconv/util.h"
|
||||
#include "peconv/pe_hdrs_helper.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace peconv;
|
||||
|
||||
// Map raw PE into virtual memory of local process:
|
||||
bool sections_raw_to_virtual(IN const BYTE* payload, IN SIZE_T payloadSize, OUT BYTE* destBuffer, IN SIZE_T destBufferSize)
|
||||
{
|
||||
if (!payload || !destBuffer) return false;
|
||||
|
||||
bool is64b = is64bit(payload);
|
||||
|
||||
BYTE* payload_nt_hdr = get_nt_hdrs(payload);
|
||||
if (payload_nt_hdr == NULL) {
|
||||
std::cerr << "Invalid payload: " << std::hex << (ULONGLONG) payload << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
IMAGE_FILE_HEADER *fileHdr = NULL;
|
||||
DWORD hdrsSize = 0;
|
||||
LPVOID secptr = NULL;
|
||||
if (is64b) {
|
||||
IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*)payload_nt_hdr;
|
||||
fileHdr = &(payload_nt_hdr64->FileHeader);
|
||||
hdrsSize = payload_nt_hdr64->OptionalHeader.SizeOfHeaders;
|
||||
secptr = (LPVOID)((ULONGLONG)&(payload_nt_hdr64->OptionalHeader) + fileHdr->SizeOfOptionalHeader);
|
||||
}
|
||||
else {
|
||||
IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*)payload_nt_hdr;
|
||||
fileHdr = &(payload_nt_hdr32->FileHeader);
|
||||
hdrsSize = payload_nt_hdr32->OptionalHeader.SizeOfHeaders;
|
||||
secptr = (LPVOID)((ULONGLONG)&(payload_nt_hdr32->OptionalHeader) + fileHdr->SizeOfOptionalHeader);
|
||||
}
|
||||
|
||||
DWORD first_raw = 0;
|
||||
//copy all the sections, one by one:
|
||||
SIZE_T raw_end = 0;
|
||||
for (WORD i = 0; i < fileHdr->NumberOfSections; i++) {
|
||||
PIMAGE_SECTION_HEADER next_sec = (PIMAGE_SECTION_HEADER)((ULONGLONG)secptr + (IMAGE_SIZEOF_SECTION_HEADER * i));
|
||||
if (!validate_ptr((const LPVOID)payload, destBufferSize, next_sec, IMAGE_SIZEOF_SECTION_HEADER)) {
|
||||
return false;
|
||||
}
|
||||
if (next_sec->PointerToRawData == 0 || next_sec->SizeOfRawData == 0) {
|
||||
continue; //skipping empty
|
||||
}
|
||||
LPVOID section_mapped = destBuffer + next_sec->VirtualAddress;
|
||||
LPVOID section_raw_ptr = (BYTE*)payload + next_sec->PointerToRawData;
|
||||
SIZE_T sec_size = next_sec->SizeOfRawData;
|
||||
raw_end = next_sec->SizeOfRawData + next_sec->PointerToRawData;
|
||||
|
||||
if ((next_sec->VirtualAddress + sec_size) > destBufferSize) {
|
||||
std::cerr << "[!] Virtual section size is out ouf bounds: " << std::hex << sec_size << std::endl;
|
||||
sec_size = (destBufferSize > next_sec->VirtualAddress) ? SIZE_T(destBufferSize - next_sec->VirtualAddress) : 0;
|
||||
std::cerr << "[!] Truncated to maximal size: " << std::hex << sec_size << ", buffer size:" << destBufferSize << std::endl;
|
||||
}
|
||||
if (next_sec->VirtualAddress >= destBufferSize && sec_size != 0) {
|
||||
std::cerr << "[-] VirtualAddress of section is out ouf bounds: " << std::hex << next_sec->VirtualAddress << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (next_sec->PointerToRawData + sec_size > destBufferSize) {
|
||||
std::cerr << "[-] Raw section size is out ouf bounds: " << std::hex << sec_size << std::endl;
|
||||
return false;
|
||||
}
|
||||
// validate source:
|
||||
if (!validate_ptr((const LPVOID)payload, payloadSize, section_raw_ptr, sec_size)) {
|
||||
std::cerr << "[-] Section " << i << ": out ouf bounds, skipping... " << std::endl;
|
||||
continue;
|
||||
}
|
||||
// validate destination:
|
||||
if (!peconv::validate_ptr(destBuffer, destBufferSize, section_mapped, sec_size)) {
|
||||
std::cerr << "[-] Section " << i << ": out ouf bounds, skipping... " << std::endl;
|
||||
continue;
|
||||
}
|
||||
memcpy(section_mapped, section_raw_ptr, sec_size);
|
||||
if (first_raw == 0 || (next_sec->PointerToRawData < first_raw)) {
|
||||
first_raw = next_sec->PointerToRawData;
|
||||
}
|
||||
}
|
||||
|
||||
//copy payload's headers:
|
||||
if (hdrsSize == 0) {
|
||||
hdrsSize= first_raw;
|
||||
#ifdef _DEBUG
|
||||
std::cout << "hdrsSize not filled, using calculated size: " << std::hex << hdrsSize << "\n";
|
||||
#endif
|
||||
}
|
||||
if (!validate_ptr((const LPVOID)payload, destBufferSize, (const LPVOID)payload, hdrsSize)) {
|
||||
return false;
|
||||
}
|
||||
memcpy(destBuffer, payload, hdrsSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
BYTE* peconv::pe_raw_to_virtual(
|
||||
IN const BYTE* payload,
|
||||
IN size_t in_size,
|
||||
OUT size_t &out_size,
|
||||
IN OPTIONAL bool executable,
|
||||
IN OPTIONAL ULONGLONG desired_base
|
||||
)
|
||||
{
|
||||
//check payload:
|
||||
BYTE* nt_hdr = get_nt_hdrs(payload);
|
||||
if (nt_hdr == NULL) {
|
||||
std::cerr << "Invalid payload: " << std::hex << (ULONGLONG) payload << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
DWORD payloadImageSize = 0;
|
||||
|
||||
bool is64 = is64bit(payload);
|
||||
if (is64) {
|
||||
IMAGE_NT_HEADERS64* payload_nt_hdr = (IMAGE_NT_HEADERS64*)nt_hdr;
|
||||
payloadImageSize = payload_nt_hdr->OptionalHeader.SizeOfImage;
|
||||
}
|
||||
else {
|
||||
IMAGE_NT_HEADERS32* payload_nt_hdr = (IMAGE_NT_HEADERS32*)nt_hdr;
|
||||
payloadImageSize = payload_nt_hdr->OptionalHeader.SizeOfImage;
|
||||
}
|
||||
|
||||
DWORD protect = executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
|
||||
|
||||
//first we will prepare the payload image in the local memory, so that it will be easier to edit it, apply relocations etc.
|
||||
//when it will be ready, we will copy it into the space reserved in the target process
|
||||
BYTE* localCopyAddress = alloc_pe_buffer(payloadImageSize, protect, desired_base);
|
||||
if (localCopyAddress == NULL) {
|
||||
std::cerr << "Could not allocate memory in the current process" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
//printf("Allocated local memory: %p size: %x\n", localCopyAddress, payloadImageSize);
|
||||
if (!sections_raw_to_virtual(payload, in_size, (BYTE*)localCopyAddress, payloadImageSize)) {
|
||||
std::cerr << "Could not copy PE file" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
out_size = payloadImageSize;
|
||||
return localCopyAddress;
|
||||
}
|
||||
213
ai_anti_malware/libpeconv/libpeconv/src/pe_virtual_to_raw.cpp
Normal file
213
ai_anti_malware/libpeconv/libpeconv/src/pe_virtual_to_raw.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
#include "peconv/pe_virtual_to_raw.h"
|
||||
|
||||
#include "peconv/util.h"
|
||||
#include "peconv/pe_hdrs_helper.h"
|
||||
#include "peconv/relocate.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace peconv;
|
||||
|
||||
bool sections_virtual_to_raw(BYTE* payload, SIZE_T payload_size, OUT BYTE* destAddress, OUT SIZE_T *raw_size_ptr)
|
||||
{
|
||||
if (!payload || !destAddress) return false;
|
||||
|
||||
bool is64b = is64bit(payload);
|
||||
|
||||
BYTE* payload_nt_hdr = get_nt_hdrs(payload);
|
||||
if (payload_nt_hdr == NULL) {
|
||||
std::cerr << "Invalid payload: " << std::hex << (ULONGLONG) payload << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
IMAGE_FILE_HEADER *fileHdr = NULL;
|
||||
DWORD hdrsSize = 0;
|
||||
LPVOID secptr = NULL;
|
||||
if (is64b) {
|
||||
IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*) payload_nt_hdr;
|
||||
fileHdr = &(payload_nt_hdr64->FileHeader);
|
||||
hdrsSize = payload_nt_hdr64->OptionalHeader.SizeOfHeaders;
|
||||
secptr = (LPVOID)((ULONGLONG)&(payload_nt_hdr64->OptionalHeader) + fileHdr->SizeOfOptionalHeader);
|
||||
} else {
|
||||
IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*) payload_nt_hdr;
|
||||
fileHdr = &(payload_nt_hdr32->FileHeader);
|
||||
hdrsSize = payload_nt_hdr32->OptionalHeader.SizeOfHeaders;
|
||||
secptr = (LPVOID)((ULONGLONG)&(payload_nt_hdr32->OptionalHeader) + fileHdr->SizeOfOptionalHeader);
|
||||
}
|
||||
|
||||
//copy all the sections, one by one:
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Coping sections:" << std::endl;
|
||||
#endif
|
||||
DWORD first_raw = 0;
|
||||
SIZE_T raw_end = hdrsSize;
|
||||
for (WORD i = 0; i < fileHdr->NumberOfSections; i++) {
|
||||
PIMAGE_SECTION_HEADER next_sec = (PIMAGE_SECTION_HEADER)((ULONGLONG)secptr + (IMAGE_SIZEOF_SECTION_HEADER * i));
|
||||
if (!validate_ptr(payload, payload_size, next_sec, IMAGE_SIZEOF_SECTION_HEADER)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LPVOID section_mapped = (BYTE*) payload + next_sec->VirtualAddress;
|
||||
LPVOID section_raw_ptr = destAddress + next_sec->PointerToRawData;
|
||||
SIZE_T sec_size = next_sec->SizeOfRawData;
|
||||
|
||||
size_t new_end = sec_size + next_sec->PointerToRawData;
|
||||
if (new_end > raw_end) raw_end = new_end;
|
||||
|
||||
if ((next_sec->VirtualAddress + sec_size) > payload_size) {
|
||||
std::cerr << "[!] Virtual section size is out ouf bounds: " << std::hex << sec_size << std::endl;
|
||||
sec_size = (payload_size > next_sec->VirtualAddress) ? SIZE_T(payload_size - next_sec->VirtualAddress) : 0;
|
||||
std::cerr << "[!] Truncated to maximal size: " << std::hex << sec_size << ", buffer size: " << payload_size << std::endl;
|
||||
}
|
||||
if (next_sec->VirtualAddress > payload_size && sec_size != 0) {
|
||||
std::cerr << "[-] VirtualAddress of section is out ouf bounds: " << std::hex << next_sec->VirtualAddress << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (next_sec->PointerToRawData + sec_size > payload_size) {
|
||||
std::cerr << "[-] Raw section size is out ouf bounds: " << std::hex << sec_size << std::endl;
|
||||
return false;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << "[+] " << next_sec->Name << " to: " << std::hex << section_raw_ptr << std::endl;
|
||||
#endif
|
||||
//validate source:
|
||||
if (!peconv::validate_ptr(payload, payload_size, section_mapped, sec_size)) {
|
||||
std::cerr << "[-] Section " << i << ": out ouf bounds, skipping... " << std::endl;
|
||||
continue;
|
||||
}
|
||||
//validate destination:
|
||||
if (!peconv::validate_ptr(destAddress, payload_size, section_raw_ptr, sec_size)) {
|
||||
std::cerr << "[-] Section " << i << ": out ouf bounds, skipping... " << std::endl;
|
||||
continue;
|
||||
}
|
||||
memcpy(section_raw_ptr, section_mapped, sec_size);
|
||||
if (first_raw == 0 || (next_sec->PointerToRawData < first_raw)) {
|
||||
first_raw = next_sec->PointerToRawData;
|
||||
}
|
||||
}
|
||||
if (raw_end > payload_size) raw_end = payload_size;
|
||||
if (raw_size_ptr != NULL) {
|
||||
(*raw_size_ptr) = raw_end;
|
||||
}
|
||||
|
||||
//copy payload's headers:
|
||||
if (hdrsSize == 0) {
|
||||
hdrsSize = first_raw;
|
||||
#ifdef _DEBUG
|
||||
std::cout << "hdrsSize not filled, using calculated size: " << std::hex << hdrsSize << "\n";
|
||||
#endif
|
||||
}
|
||||
if (!validate_ptr(payload, payload_size, payload, hdrsSize)) {
|
||||
return false;
|
||||
}
|
||||
memcpy(destAddress, payload, hdrsSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
BYTE* peconv::pe_virtual_to_raw(
|
||||
IN BYTE* payload,
|
||||
IN size_t in_size,
|
||||
IN ULONGLONG loadBase,
|
||||
OUT size_t &out_size,
|
||||
IN OPTIONAL bool rebuffer
|
||||
)
|
||||
{
|
||||
BYTE* out_buf = (BYTE*)alloc_pe_buffer(in_size, PAGE_READWRITE);
|
||||
if (out_buf == NULL) return NULL; //could not allocate output buffer
|
||||
|
||||
BYTE* in_buf = payload;
|
||||
if (rebuffer) {
|
||||
in_buf = (BYTE*) alloc_pe_buffer(in_size, PAGE_READWRITE);
|
||||
if (in_buf == NULL) {
|
||||
free_pe_buffer(out_buf, in_size);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(in_buf, payload, in_size);
|
||||
}
|
||||
|
||||
ULONGLONG oldBase = get_image_base(in_buf);
|
||||
bool isOk = true;
|
||||
// from the loadBase go back to the original base
|
||||
if (!relocate_module(in_buf, in_size, oldBase, loadBase)) {
|
||||
//Failed relocating the module! Changing image base instead...
|
||||
if (!update_image_base(in_buf, (ULONGLONG)loadBase)) {
|
||||
std::cerr << "[-] Failed relocating the module!" << std::endl;
|
||||
isOk = false;
|
||||
} else {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "[!] WARNING: The module could not be relocated, so the ImageBase has been changed instead!" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
SIZE_T raw_size = 0;
|
||||
if (isOk) {
|
||||
if (!sections_virtual_to_raw(in_buf, in_size, out_buf, &raw_size)) {
|
||||
isOk = false;
|
||||
}
|
||||
}
|
||||
if (rebuffer && in_buf != NULL) {
|
||||
free_pe_buffer(in_buf, in_size);
|
||||
in_buf = NULL;
|
||||
}
|
||||
if (!isOk) {
|
||||
free_pe_buffer(out_buf, in_size);
|
||||
out_buf = NULL;
|
||||
raw_size = 0;
|
||||
}
|
||||
out_size = raw_size;
|
||||
return out_buf;
|
||||
}
|
||||
|
||||
BYTE* peconv::pe_realign_raw_to_virtual(
|
||||
IN const BYTE* payload,
|
||||
IN size_t in_size,
|
||||
IN ULONGLONG loadBase,
|
||||
OUT size_t &out_size
|
||||
)
|
||||
{
|
||||
out_size = in_size;
|
||||
BYTE* out_buf = (BYTE*)alloc_pe_buffer(out_size, PAGE_READWRITE);
|
||||
if (!out_buf) {
|
||||
out_size = 0;
|
||||
return nullptr;
|
||||
}
|
||||
memcpy(out_buf, payload, in_size);
|
||||
|
||||
ULONGLONG oldBase = get_image_base(out_buf);
|
||||
bool isOk = true;
|
||||
// from the loadBase go back to the original base
|
||||
if (!relocate_module(out_buf, out_size, oldBase, loadBase)) {
|
||||
//Failed relocating the module! Changing image base instead...
|
||||
if (!update_image_base(out_buf, (ULONGLONG)loadBase)) {
|
||||
std::cerr << "[-] Failed relocating the module!" << std::endl;
|
||||
isOk = false;
|
||||
} else {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "[!] WARNING: The module could not be relocated, so the ImageBase has been changed instead!" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//---
|
||||
//set raw alignment the same as virtual
|
||||
DWORD v_alignment = peconv::get_sec_alignment((const PBYTE)payload, false);
|
||||
if (!peconv::set_sec_alignment(out_buf, true, v_alignment)) {
|
||||
isOk = false;
|
||||
}
|
||||
//set Raw pointers and sizes of the sections same as Virtual
|
||||
size_t sections_count = peconv::get_sections_count(out_buf, out_size);
|
||||
for (size_t i = 0; i < sections_count; i++) {
|
||||
PIMAGE_SECTION_HEADER sec = peconv::get_section_hdr(out_buf, out_size, i);
|
||||
if (!sec) break;
|
||||
|
||||
sec->Misc.VirtualSize = peconv::get_virtual_sec_size(out_buf, sec, true);
|
||||
sec->SizeOfRawData = sec->Misc.VirtualSize;
|
||||
sec->PointerToRawData = sec->VirtualAddress;
|
||||
}
|
||||
//!---
|
||||
if (!isOk) {
|
||||
free_pe_buffer(out_buf);
|
||||
out_buf = nullptr;
|
||||
out_size = 0;
|
||||
}
|
||||
return out_buf;
|
||||
}
|
||||
178
ai_anti_malware/libpeconv/libpeconv/src/peb_lookup.cpp
Normal file
178
ai_anti_malware/libpeconv/libpeconv/src/peb_lookup.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
#include "ntddk.h"
|
||||
|
||||
#include <peconv/peb_lookup.h>
|
||||
|
||||
class SectionLocker {
|
||||
public:
|
||||
SectionLocker(RTL_CRITICAL_SECTION &_section)
|
||||
: section(_section)
|
||||
{
|
||||
RtlEnterCriticalSection(§ion);
|
||||
}
|
||||
|
||||
~SectionLocker()
|
||||
{
|
||||
RtlLeaveCriticalSection(§ion);
|
||||
}
|
||||
|
||||
protected:
|
||||
RTL_CRITICAL_SECTION §ion;
|
||||
};
|
||||
|
||||
//here we don't want to use any functions imported form extenal modules
|
||||
|
||||
typedef struct _LDR_MODULE {
|
||||
LIST_ENTRY InLoadOrderModuleList;// +0x00
|
||||
LIST_ENTRY InMemoryOrderModuleList;// +0x08
|
||||
LIST_ENTRY InInitializationOrderModuleList;// +0x10
|
||||
void* BaseAddress; // +0x18
|
||||
void* EntryPoint; // +0x1c
|
||||
ULONG SizeOfImage;
|
||||
UNICODE_STRING FullDllName;
|
||||
UNICODE_STRING BaseDllName;
|
||||
ULONG Flags;
|
||||
SHORT LoadCount;
|
||||
SHORT TlsIndex;
|
||||
HANDLE SectionHandle;
|
||||
ULONG CheckSum;
|
||||
ULONG TimeDateStamp;
|
||||
} LDR_MODULE, *PLDR_MODULE;
|
||||
|
||||
inline PPEB get_peb()
|
||||
{
|
||||
#if defined(_WIN64)
|
||||
return (PPEB)__readgsqword(0x60);
|
||||
#else
|
||||
return (PPEB)__readfsdword(0x30);
|
||||
/*
|
||||
//alternative way to fetch it:
|
||||
LPVOID PEB = NULL;
|
||||
__asm {
|
||||
mov eax, fs:[30h]
|
||||
mov PEB, eax
|
||||
};
|
||||
return (PPEB)PEB;
|
||||
|
||||
or:
|
||||
LPVOID PEB = RtlGetCurrentPeb();
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
inline WCHAR to_lowercase(WCHAR c1)
|
||||
{
|
||||
if (c1 <= L'Z' && c1 >= L'A') {
|
||||
c1 = (c1 - L'A') + L'a';
|
||||
}
|
||||
return c1;
|
||||
}
|
||||
|
||||
bool is_wanted_module(LPWSTR curr_name, LPWSTR wanted_name)
|
||||
{
|
||||
if (wanted_name == NULL || curr_name == NULL) return false;
|
||||
|
||||
WCHAR *curr_end_ptr = curr_name;
|
||||
while (*curr_end_ptr != L'\0') {
|
||||
curr_end_ptr++;
|
||||
}
|
||||
if (curr_end_ptr == curr_name) return false;
|
||||
|
||||
WCHAR *wanted_end_ptr = wanted_name;
|
||||
while (*wanted_end_ptr != L'\0') {
|
||||
wanted_end_ptr++;
|
||||
}
|
||||
if (wanted_end_ptr == wanted_name) return false;
|
||||
|
||||
while ((curr_end_ptr != curr_name) && (wanted_end_ptr != wanted_name)) {
|
||||
|
||||
if (to_lowercase(*wanted_end_ptr) != to_lowercase(*curr_end_ptr)) {
|
||||
return false;
|
||||
}
|
||||
wanted_end_ptr--;
|
||||
curr_end_ptr--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
HMODULE peconv::get_module_via_peb(IN OPTIONAL LPWSTR module_name)
|
||||
{
|
||||
PPEB peb = get_peb();
|
||||
if (!peb) {
|
||||
return NULL;
|
||||
}
|
||||
SectionLocker locker(*peb->LoaderLock);
|
||||
LIST_ENTRY head = peb->Ldr->InLoadOrderModuleList;
|
||||
|
||||
const PLDR_MODULE first_module = *((PLDR_MODULE *)(&head));
|
||||
PLDR_MODULE curr_module = first_module;
|
||||
if (!module_name) {
|
||||
return (HMODULE)(curr_module->BaseAddress);
|
||||
}
|
||||
|
||||
// it is a cyclic list, so if the next record links to the initial one, it means we went throught the full loop
|
||||
do {
|
||||
// this should also work as a terminator, because the BaseAddress of the last module in the cycle is NULL
|
||||
if (curr_module == NULL || curr_module->BaseAddress == NULL) {
|
||||
break;
|
||||
}
|
||||
if (is_wanted_module(curr_module->BaseDllName.Buffer, module_name)) {
|
||||
return (HMODULE)(curr_module->BaseAddress);
|
||||
}
|
||||
curr_module = (PLDR_MODULE)curr_module->InLoadOrderModuleList.Flink;
|
||||
|
||||
} while (curr_module != first_module);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t peconv::get_module_size_via_peb(IN OPTIONAL HMODULE hModule)
|
||||
{
|
||||
PPEB peb = get_peb();
|
||||
if (!peb) {
|
||||
return 0;
|
||||
}
|
||||
SectionLocker locker(*peb->LoaderLock);
|
||||
LIST_ENTRY head = peb->Ldr->InLoadOrderModuleList;
|
||||
|
||||
const PLDR_MODULE first_module = *((PLDR_MODULE *)(&head));
|
||||
PLDR_MODULE curr_module = first_module;
|
||||
if (!hModule) {
|
||||
return (size_t)(curr_module->SizeOfImage);
|
||||
}
|
||||
|
||||
// it is a cyclic list, so if the next record links to the initial one, it means we went throught the full loop
|
||||
do {
|
||||
// this should also work as a terminator, because the BaseAddress of the last module in the cycle is NULL
|
||||
if (curr_module == NULL || curr_module->BaseAddress == NULL) {
|
||||
break;
|
||||
}
|
||||
if (hModule == (HMODULE)(curr_module->BaseAddress)) {
|
||||
return (size_t)(curr_module->SizeOfImage);
|
||||
}
|
||||
curr_module = (PLDR_MODULE)curr_module->InLoadOrderModuleList.Flink;
|
||||
|
||||
} while (curr_module != first_module);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool peconv::set_main_module_in_peb(HMODULE module_ptr)
|
||||
{
|
||||
PPEB peb = get_peb();
|
||||
if (peb == NULL) {
|
||||
return false;
|
||||
}
|
||||
SectionLocker locker(*peb->FastPebLock);
|
||||
peb->ImageBaseAddress = module_ptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
HMODULE peconv::get_main_module_via_peb()
|
||||
{
|
||||
PPEB peb = get_peb();
|
||||
if (peb == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
SectionLocker locker(*peb->FastPebLock);
|
||||
return (HMODULE) peb->ImageBaseAddress;
|
||||
}
|
||||
189
ai_anti_malware/libpeconv/libpeconv/src/relocate.cpp
Normal file
189
ai_anti_malware/libpeconv/libpeconv/src/relocate.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
#include "peconv/relocate.h"
|
||||
|
||||
#include "peconv/pe_hdrs_helper.h"
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace peconv;
|
||||
|
||||
#define RELOC_32BIT_FIELD 3
|
||||
#define RELOC_64BIT_FIELD 0xA
|
||||
|
||||
class ApplyRelocCallback : public RelocBlockCallback
|
||||
{
|
||||
public:
|
||||
ApplyRelocCallback(bool _is64bit, ULONGLONG _oldBase, ULONGLONG _newBase)
|
||||
: RelocBlockCallback(_is64bit), oldBase(_oldBase), newBase(_newBase)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool processRelocField(ULONG_PTR relocField)
|
||||
{
|
||||
if (is64bit) {
|
||||
ULONGLONG* relocateAddr = (ULONGLONG*)((ULONG_PTR)relocField);
|
||||
ULONGLONG rva = (*relocateAddr) - oldBase;
|
||||
(*relocateAddr) = rva + newBase;
|
||||
}
|
||||
else {
|
||||
DWORD* relocateAddr = (DWORD*)((ULONG_PTR)relocField);
|
||||
ULONGLONG rva = ULONGLONG(*relocateAddr) - oldBase;
|
||||
(*relocateAddr) = static_cast<DWORD>(rva + newBase);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
ULONGLONG oldBase;
|
||||
ULONGLONG newBase;
|
||||
};
|
||||
|
||||
bool is_empty_reloc_block(BASE_RELOCATION_ENTRY *block, SIZE_T entriesNum, DWORD page, PVOID modulePtr, SIZE_T moduleSize)
|
||||
{
|
||||
if (entriesNum == 0) {
|
||||
return true; // nothing to process
|
||||
}
|
||||
BASE_RELOCATION_ENTRY* entry = block;
|
||||
for (SIZE_T i = 0; i < entriesNum; i++) {
|
||||
if (!validate_ptr(modulePtr, moduleSize, entry, sizeof(BASE_RELOCATION_ENTRY))) {
|
||||
return false;
|
||||
}
|
||||
DWORD type = entry->Type;
|
||||
if (type != 0) {
|
||||
//non empty block found
|
||||
return false;
|
||||
}
|
||||
entry = (BASE_RELOCATION_ENTRY*)((ULONG_PTR)entry + sizeof(WORD));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool process_reloc_block(BASE_RELOCATION_ENTRY *block, SIZE_T entriesNum, DWORD page, PVOID modulePtr, SIZE_T moduleSize, bool is64bit, RelocBlockCallback *callback)
|
||||
{
|
||||
if (entriesNum == 0) {
|
||||
return true; // nothing to process
|
||||
}
|
||||
BASE_RELOCATION_ENTRY* entry = block;
|
||||
SIZE_T i = 0;
|
||||
for (i = 0; i < entriesNum; i++) {
|
||||
if (!validate_ptr(modulePtr, moduleSize, entry, sizeof(BASE_RELOCATION_ENTRY))) {
|
||||
break;
|
||||
}
|
||||
DWORD offset = entry->Offset;
|
||||
DWORD type = entry->Type;
|
||||
if (type == 0) {
|
||||
break;
|
||||
}
|
||||
if (type != RELOC_32BIT_FIELD && type != RELOC_64BIT_FIELD) {
|
||||
if (callback) { //print debug messages only if the callback function was set
|
||||
printf("[-] Not supported relocations format at %d: %d\n", (int)i, (int)type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
DWORD reloc_field = page + offset;
|
||||
if (reloc_field >= moduleSize) {
|
||||
if (callback) { //print debug messages only if the callback function was set
|
||||
printf("[-] Malformed field: %lx\n", reloc_field);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (callback) {
|
||||
bool isOk = callback->processRelocField(((ULONG_PTR)modulePtr + reloc_field));
|
||||
if (!isOk) {
|
||||
std::cout << "[-] Failed processing reloc field at: " << std::hex << reloc_field << "\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
entry = (BASE_RELOCATION_ENTRY*)((ULONG_PTR)entry + sizeof(WORD));
|
||||
}
|
||||
return (i != 0);
|
||||
}
|
||||
|
||||
bool peconv::process_relocation_table(IN PVOID modulePtr, IN SIZE_T moduleSize, IN RelocBlockCallback *callback)
|
||||
{
|
||||
IMAGE_DATA_DIRECTORY* relocDir = peconv::get_directory_entry((const BYTE*)modulePtr, IMAGE_DIRECTORY_ENTRY_BASERELOC);
|
||||
if (relocDir == NULL) {
|
||||
std::cout << "[!] WARNING: no relocation table found!\n";
|
||||
return false;
|
||||
}
|
||||
if (!validate_ptr(modulePtr, moduleSize, relocDir, sizeof(IMAGE_DATA_DIRECTORY))) {
|
||||
std::cerr << "[!] Invalid relocDir pointer\n";
|
||||
return false;
|
||||
}
|
||||
DWORD maxSize = relocDir->Size;
|
||||
DWORD relocAddr = relocDir->VirtualAddress;
|
||||
bool is64b = is64bit((BYTE*)modulePtr);
|
||||
|
||||
IMAGE_BASE_RELOCATION* reloc = NULL;
|
||||
|
||||
DWORD parsedSize = 0;
|
||||
DWORD validBlocks = 0;
|
||||
while (parsedSize < maxSize) {
|
||||
reloc = (IMAGE_BASE_RELOCATION*)(relocAddr + parsedSize + (ULONG_PTR)modulePtr);
|
||||
if (!validate_ptr(modulePtr, moduleSize, reloc, sizeof(IMAGE_BASE_RELOCATION))) {
|
||||
std::cerr << "[-] Invalid address of relocations\n";
|
||||
return false;
|
||||
}
|
||||
if (reloc->SizeOfBlock == 0) {
|
||||
break;
|
||||
}
|
||||
size_t entriesNum = (reloc->SizeOfBlock - 2 * sizeof(DWORD)) / sizeof(WORD);
|
||||
DWORD page = reloc->VirtualAddress;
|
||||
|
||||
BASE_RELOCATION_ENTRY* block = (BASE_RELOCATION_ENTRY*)((ULONG_PTR)reloc + sizeof(DWORD) + sizeof(DWORD));
|
||||
if (!validate_ptr(modulePtr, moduleSize, block, sizeof(BASE_RELOCATION_ENTRY))) {
|
||||
std::cerr << "[-] Invalid address of relocations block\n";
|
||||
return false;
|
||||
}
|
||||
if (!is_empty_reloc_block(block, entriesNum, page, modulePtr, moduleSize)) {
|
||||
if (process_reloc_block(block, entriesNum, page, modulePtr, moduleSize, is64b, callback)) {
|
||||
validBlocks++;
|
||||
}
|
||||
else {
|
||||
// the block was malformed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
parsedSize += reloc->SizeOfBlock;
|
||||
}
|
||||
return (validBlocks != 0);
|
||||
}
|
||||
|
||||
bool apply_relocations(PVOID modulePtr, SIZE_T moduleSize, ULONGLONG newBase, ULONGLONG oldBase)
|
||||
{
|
||||
const bool is64b = is64bit((BYTE*)modulePtr);
|
||||
ApplyRelocCallback callback(is64b, oldBase, newBase);
|
||||
return process_relocation_table(modulePtr, moduleSize, &callback);
|
||||
}
|
||||
|
||||
bool peconv::relocate_module(IN BYTE* modulePtr, IN SIZE_T moduleSize, IN ULONGLONG newBase, IN ULONGLONG oldBase)
|
||||
{
|
||||
if (modulePtr == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (oldBase == 0) {
|
||||
oldBase = get_image_base(modulePtr);
|
||||
}
|
||||
printf("<EFBFBD><EFBFBD>ʼ<EFBFBD>ض<EFBFBD>λ: %p -> %p \n", oldBase, newBase);
|
||||
|
||||
#ifdef _DEBUG
|
||||
printf("New Base: %llx\n", newBase);
|
||||
printf("Old Base: %llx\n", oldBase);
|
||||
#endif
|
||||
if (newBase == oldBase) {
|
||||
printf("Nothing to relocate! oldBase is the same as the newBase!\n");
|
||||
return true; //nothing to relocate
|
||||
}
|
||||
if (apply_relocations(modulePtr, moduleSize, newBase, oldBase)) {
|
||||
return true;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
printf("Could not relocate the module!\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool peconv::has_valid_relocation_table(IN const PBYTE modulePtr, IN const size_t moduleSize)
|
||||
{
|
||||
return process_relocation_table(modulePtr, moduleSize, nullptr);
|
||||
}
|
||||
|
||||
299
ai_anti_malware/libpeconv/libpeconv/src/remote_pe_reader.cpp
Normal file
299
ai_anti_malware/libpeconv/libpeconv/src/remote_pe_reader.cpp
Normal file
@@ -0,0 +1,299 @@
|
||||
#include "peconv/remote_pe_reader.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "peconv/util.h"
|
||||
#include "peconv/fix_imports.h"
|
||||
|
||||
using namespace peconv;
|
||||
|
||||
bool peconv::fetch_region_info(HANDLE processHandle, BYTE* moduleBase, MEMORY_BASIC_INFORMATION &page_info)
|
||||
{
|
||||
memset(&page_info, 0, sizeof(MEMORY_BASIC_INFORMATION));
|
||||
SIZE_T out = VirtualQueryEx(processHandle, (LPCVOID)moduleBase, &page_info, sizeof(page_info));
|
||||
if (out != sizeof(page_info)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t peconv::fetch_region_size(HANDLE processHandle, BYTE* moduleBase)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION page_info = { 0 };
|
||||
if (!peconv::fetch_region_info(processHandle, moduleBase, page_info)) {
|
||||
return 0;
|
||||
}
|
||||
if (page_info.Type == 0) {
|
||||
return false; //invalid type, skip it
|
||||
}
|
||||
if ((BYTE*)page_info.BaseAddress > moduleBase) {
|
||||
return 0; //should never happen
|
||||
}
|
||||
size_t offset = moduleBase - (BYTE*)page_info.BaseAddress;
|
||||
size_t area_size = page_info.RegionSize - offset;
|
||||
return area_size;
|
||||
}
|
||||
|
||||
ULONGLONG peconv::fetch_alloc_base(HANDLE processHandle, BYTE* moduleBase)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION page_info = { 0 };
|
||||
if (!peconv::fetch_region_info(processHandle, moduleBase, page_info)) {
|
||||
return 0;
|
||||
}
|
||||
if (page_info.Type == 0) {
|
||||
return 0; //invalid type, skip it
|
||||
}
|
||||
return (ULONGLONG) page_info.AllocationBase;
|
||||
}
|
||||
|
||||
size_t peconv::read_remote_memory(HANDLE processHandle, BYTE *start_addr, OUT BYTE* buffer, const size_t buffer_size, const SIZE_T step_size)
|
||||
{
|
||||
if (!buffer) {
|
||||
return 0;
|
||||
}
|
||||
memset(buffer, 0, buffer_size);
|
||||
|
||||
SIZE_T read_size = 0;
|
||||
DWORD last_error = ERROR_SUCCESS;
|
||||
|
||||
for (SIZE_T to_read_size = buffer_size; to_read_size > 0; to_read_size -= step_size)
|
||||
{
|
||||
if (ReadProcessMemory(processHandle, start_addr, buffer, to_read_size, &read_size)) {
|
||||
break;
|
||||
}
|
||||
// is it not the first attempt?
|
||||
if (last_error != ERROR_SUCCESS) {
|
||||
if (read_size == 0 && (last_error != ERROR_PARTIAL_COPY)) {
|
||||
last_error = GetLastError();
|
||||
break; // no progress, break
|
||||
}
|
||||
}
|
||||
|
||||
last_error = GetLastError();
|
||||
|
||||
if ((to_read_size < step_size) || step_size == 0) {
|
||||
break;
|
||||
}
|
||||
//otherwise, decrease the to_read_size, and try again...
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (read_size == 0) {
|
||||
std::cerr << "[WARNING] Cannot read memory. Last Error : " << last_error << std::endl;
|
||||
}
|
||||
else if (read_size < buffer_size) {
|
||||
std::cerr << "[WARNING] Read size: " << std::hex << read_size
|
||||
<< " is smaller than the requested size: " << std::hex << buffer_size
|
||||
<< ". Last Error: " << last_error << std::endl;
|
||||
|
||||
}
|
||||
#endif
|
||||
return static_cast<size_t>(read_size);
|
||||
}
|
||||
|
||||
size_t read_remote_region(HANDLE processHandle, BYTE *start_addr, OUT BYTE* buffer, const size_t buffer_size, const SIZE_T step_size)
|
||||
{
|
||||
if (buffer == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
size_t region_size = peconv::fetch_region_size(processHandle, start_addr);
|
||||
if (region_size == 0) return false;
|
||||
|
||||
if (region_size >= buffer_size) {
|
||||
return peconv::read_remote_memory(processHandle, start_addr, buffer, buffer_size, step_size);
|
||||
}
|
||||
return peconv::read_remote_memory(processHandle, start_addr, buffer, region_size, step_size);
|
||||
}
|
||||
|
||||
size_t peconv::read_remote_area(HANDLE processHandle, BYTE *start_addr, OUT BYTE* buffer, const size_t buffer_size, const SIZE_T step_size)
|
||||
{
|
||||
if (!buffer || !start_addr) {
|
||||
return 0;
|
||||
}
|
||||
memset(buffer, 0, buffer_size);
|
||||
|
||||
size_t read = 0;
|
||||
for (read = 0; read < buffer_size; ) {
|
||||
size_t read_chunk = read_remote_region(processHandle, start_addr + read, buffer + read, buffer_size - read, step_size);
|
||||
if (read_chunk == 0) {
|
||||
size_t region_size = peconv::fetch_region_size(processHandle, start_addr);
|
||||
if (region_size == 0) break;
|
||||
//skip the region that could not be read:
|
||||
read += region_size;
|
||||
continue;
|
||||
}
|
||||
read += read_chunk;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
bool peconv::read_remote_pe_header(HANDLE processHandle, BYTE *start_addr, OUT BYTE* buffer, const size_t buffer_size)
|
||||
{
|
||||
if (buffer == nullptr) {
|
||||
return false;
|
||||
}
|
||||
SIZE_T read_size = read_remote_memory(processHandle, start_addr, buffer, buffer_size);
|
||||
if (read_size == 0) {
|
||||
return false;
|
||||
}
|
||||
BYTE *nt_ptr = get_nt_hdrs(buffer);
|
||||
if (nt_ptr == nullptr) {
|
||||
return false;
|
||||
}
|
||||
const size_t nt_offset = nt_ptr - buffer;
|
||||
const size_t nt_size = peconv::is64bit(buffer) ? sizeof(IMAGE_NT_HEADERS64) : sizeof(IMAGE_NT_HEADERS32);
|
||||
const size_t min_size = nt_offset + nt_size;
|
||||
|
||||
if (read_size < min_size) {
|
||||
std::cerr << "[-] [" << std::dec << get_process_id(processHandle)
|
||||
<< " ][" << std::hex << (ULONGLONG) start_addr
|
||||
<< "] Read size: " << std::hex << read_size
|
||||
<< " is smaller that the minimal size:" << get_hdrs_size(buffer)
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
//reading succeeded and the header passed the checks:
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace peconv {
|
||||
inline size_t roundup_to_unit(size_t size, size_t unit)
|
||||
{
|
||||
if (unit == 0) {
|
||||
return size;
|
||||
}
|
||||
size_t parts = size / unit;
|
||||
if (size % unit) parts++;
|
||||
return parts * unit;
|
||||
}
|
||||
};
|
||||
|
||||
peconv::UNALIGNED_BUF peconv::get_remote_pe_section(HANDLE processHandle, BYTE *start_addr, const size_t section_num, OUT size_t §ion_size, bool roundup)
|
||||
{
|
||||
BYTE header_buffer[MAX_HEADER_SIZE] = { 0 };
|
||||
|
||||
if (!read_remote_pe_header(processHandle, start_addr, header_buffer, MAX_HEADER_SIZE)) {
|
||||
return NULL;
|
||||
}
|
||||
PIMAGE_SECTION_HEADER section_hdr = get_section_hdr(header_buffer, MAX_HEADER_SIZE, section_num);
|
||||
if (section_hdr == NULL || section_hdr->Misc.VirtualSize == 0) {
|
||||
return NULL;
|
||||
}
|
||||
size_t buffer_size = section_hdr->Misc.VirtualSize;
|
||||
if (roundup) {
|
||||
DWORD va = peconv::get_sec_alignment(header_buffer, false);
|
||||
if (va == 0) va = PAGE_SIZE;
|
||||
buffer_size = roundup_to_unit(section_hdr->Misc.VirtualSize, va);
|
||||
}
|
||||
UNALIGNED_BUF module_code = peconv::alloc_unaligned(buffer_size);
|
||||
if (module_code == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
size_t read_size = read_remote_memory(processHandle, start_addr + section_hdr->VirtualAddress, module_code, buffer_size);
|
||||
if (read_size == 0) {
|
||||
peconv::free_unaligned(module_code);
|
||||
return NULL;
|
||||
}
|
||||
section_size = buffer_size;
|
||||
return module_code;
|
||||
}
|
||||
|
||||
size_t peconv::read_remote_pe(const HANDLE processHandle, BYTE *start_addr, const size_t mod_size, OUT BYTE* buffer, const size_t bufferSize)
|
||||
{
|
||||
if (buffer == nullptr) {
|
||||
std::cerr << "[-] Invalid output buffer: NULL pointer" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
if (bufferSize < mod_size || bufferSize < MAX_HEADER_SIZE ) {
|
||||
std::cerr << "[-] Invalid output buffer: too small size!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
// read PE section by section
|
||||
PBYTE hdr_buffer = buffer;
|
||||
//try to read headers:
|
||||
if (!read_remote_pe_header(processHandle, start_addr, hdr_buffer, MAX_HEADER_SIZE)) {
|
||||
std::cerr << "[-] Failed to read the module header" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
if (!is_valid_sections_hdr_offset(hdr_buffer, MAX_HEADER_SIZE)) {
|
||||
std::cerr << "[-] Sections headers are invalid or atypically aligned" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
size_t sections_count = get_sections_count(hdr_buffer, MAX_HEADER_SIZE);
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Sections: " << sections_count << std::endl;
|
||||
#endif
|
||||
size_t read_size = MAX_HEADER_SIZE;
|
||||
|
||||
for (size_t i = 0; i < sections_count; i++) {
|
||||
PIMAGE_SECTION_HEADER hdr = get_section_hdr(hdr_buffer, MAX_HEADER_SIZE, i);
|
||||
if (!hdr) {
|
||||
std::cerr << "[-] Failed to read the header of section: " << i << std::endl;
|
||||
break;
|
||||
}
|
||||
const DWORD sec_va = hdr->VirtualAddress;
|
||||
const DWORD sec_vsize = get_virtual_sec_size(hdr_buffer, hdr, true);
|
||||
if (sec_va + sec_vsize > bufferSize) {
|
||||
std::cerr << "[-] No more space in the buffer!" << std::endl;
|
||||
break;
|
||||
}
|
||||
if (sec_vsize > 0 && !read_remote_memory(processHandle, start_addr + sec_va, buffer + sec_va, sec_vsize)) {
|
||||
std::cerr << "[-] Failed to read the module section " << i <<" : at: " << std::hex << ULONG_PTR(start_addr + sec_va) << std::endl;
|
||||
}
|
||||
// update the end of the read area:
|
||||
size_t new_end = sec_va + sec_vsize;
|
||||
if (new_end > read_size) read_size = new_end;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Total read size: " << read_size << std::endl;
|
||||
#endif
|
||||
return read_size;
|
||||
}
|
||||
|
||||
DWORD peconv::get_remote_image_size(IN const HANDLE processHandle, IN BYTE *start_addr)
|
||||
{
|
||||
BYTE hdr_buffer[MAX_HEADER_SIZE] = { 0 };
|
||||
if (!read_remote_pe_header(processHandle, start_addr, hdr_buffer, MAX_HEADER_SIZE)) {
|
||||
return 0;
|
||||
}
|
||||
return peconv::get_image_size(hdr_buffer);
|
||||
}
|
||||
|
||||
bool peconv::dump_remote_pe(IN const char *out_path,
|
||||
IN const HANDLE processHandle,
|
||||
IN BYTE* start_addr,
|
||||
IN OUT t_pe_dump_mode &dump_mode,
|
||||
IN OPTIONAL peconv::ExportsMapper* exportsMap)
|
||||
{
|
||||
DWORD mod_size = get_remote_image_size(processHandle, start_addr);
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Module Size: " << mod_size << std::endl;
|
||||
#endif
|
||||
if (mod_size == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BYTE* buffer = peconv::alloc_pe_buffer(mod_size, PAGE_READWRITE);
|
||||
if (buffer == nullptr) {
|
||||
std::cerr << "[-] Failed allocating buffer. Error: " << GetLastError() << std::endl;
|
||||
return false;
|
||||
}
|
||||
//read the module that it mapped in the remote process:
|
||||
const size_t read_size = read_remote_pe(processHandle, start_addr, mod_size, buffer, mod_size);
|
||||
if (read_size == 0) {
|
||||
std::cerr << "[-] Failed reading module. Error: " << GetLastError() << std::endl;
|
||||
peconv::free_pe_buffer(buffer, mod_size);
|
||||
buffer = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool is_dumped = peconv::dump_pe(out_path,
|
||||
buffer, mod_size,
|
||||
reinterpret_cast<ULONGLONG>(start_addr),
|
||||
dump_mode, exportsMap);
|
||||
|
||||
peconv::free_pe_buffer(buffer, mod_size);
|
||||
buffer = nullptr;
|
||||
return is_dumped;
|
||||
}
|
||||
|
||||
90
ai_anti_malware/libpeconv/libpeconv/src/resource_parser.cpp
Normal file
90
ai_anti_malware/libpeconv/libpeconv/src/resource_parser.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
#include "peconv/resource_parser.h"
|
||||
#include "peconv/pe_hdrs_helper.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
bool parse_resource_dir(BYTE* modulePtr, const size_t moduleSize,
|
||||
IMAGE_RESOURCE_DIRECTORY_ENTRY *root_dir,
|
||||
const IMAGE_RESOURCE_DIRECTORY *upper_dir,
|
||||
IMAGE_RESOURCE_DIRECTORY* curr_dir,
|
||||
peconv::t_on_res_entry_found on_entry);
|
||||
|
||||
bool parse_resource_entry(BYTE* modulePtr, const size_t moduleSize,
|
||||
IMAGE_RESOURCE_DIRECTORY_ENTRY *root_dir,
|
||||
const IMAGE_RESOURCE_DIRECTORY *upper_dir,
|
||||
IMAGE_RESOURCE_DIRECTORY_ENTRY* entry,
|
||||
peconv::t_on_res_entry_found on_entry)
|
||||
{
|
||||
if (!entry->DataIsDirectory) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Entry is NOT a directory\n";
|
||||
#endif
|
||||
DWORD offset = entry->OffsetToData;
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Offset: " << offset << std::endl;
|
||||
#endif
|
||||
IMAGE_RESOURCE_DATA_ENTRY *data_entry = (IMAGE_RESOURCE_DATA_ENTRY*)(offset + (ULONGLONG)upper_dir);
|
||||
if (!peconv::validate_ptr(modulePtr, moduleSize, data_entry, sizeof(IMAGE_RESOURCE_DATA_ENTRY))) {
|
||||
return false;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Data Offset: " << data_entry->OffsetToData << " : " << data_entry->Size << std::endl;
|
||||
#endif
|
||||
BYTE* data_ptr = (BYTE*)((ULONGLONG)modulePtr + data_entry->OffsetToData);
|
||||
if (!peconv::validate_ptr(modulePtr, moduleSize, data_ptr, data_entry->Size)) {
|
||||
return false;
|
||||
}
|
||||
on_entry(modulePtr, root_dir, data_entry);
|
||||
return true;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Entry is a directory\n";
|
||||
#endif
|
||||
//else: it is a next level directory
|
||||
DWORD offset = entry->OffsetToDirectory;
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Offset: " << offset << std::endl;
|
||||
#endif
|
||||
IMAGE_RESOURCE_DIRECTORY *next_dir = (IMAGE_RESOURCE_DIRECTORY*)(offset + (ULONGLONG)upper_dir);
|
||||
if (!peconv::validate_ptr(modulePtr, moduleSize, next_dir, sizeof(IMAGE_RESOURCE_DIRECTORY))) {
|
||||
return false;
|
||||
}
|
||||
return parse_resource_dir(modulePtr, moduleSize, root_dir, upper_dir, next_dir, on_entry);
|
||||
}
|
||||
|
||||
bool parse_resource_dir(BYTE* modulePtr, const size_t moduleSize,
|
||||
IMAGE_RESOURCE_DIRECTORY_ENTRY *root_dir,
|
||||
const IMAGE_RESOURCE_DIRECTORY *upper_dir,
|
||||
IMAGE_RESOURCE_DIRECTORY* curr_dir,
|
||||
peconv::t_on_res_entry_found on_entry)
|
||||
{
|
||||
size_t total_entries = curr_dir->NumberOfIdEntries + curr_dir->NumberOfNamedEntries;
|
||||
IMAGE_RESOURCE_DIRECTORY_ENTRY* first_entry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)((ULONGLONG)&curr_dir->NumberOfIdEntries + sizeof(WORD));
|
||||
for (size_t i = 0; i < total_entries; i++) {
|
||||
IMAGE_RESOURCE_DIRECTORY_ENTRY* entry = &first_entry[i];
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Entry:" << std::hex << i << " ; " << "Id: " << entry->Id << " ; dataOffset:" << entry->OffsetToData << "\n";
|
||||
#endif
|
||||
if (root_dir == nullptr) {
|
||||
root_dir = entry;
|
||||
}
|
||||
parse_resource_entry(modulePtr, moduleSize, root_dir, upper_dir, entry, on_entry);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool peconv::parse_resources(BYTE* modulePtr, t_on_res_entry_found on_entry)
|
||||
{
|
||||
const size_t module_size = peconv::get_image_size(modulePtr);
|
||||
IMAGE_DATA_DIRECTORY *dir = peconv::get_directory_entry(modulePtr, IMAGE_DIRECTORY_ENTRY_RESOURCE);
|
||||
if (!dir || dir->VirtualAddress == 0 || dir->Size == 0) {
|
||||
return false;
|
||||
}
|
||||
IMAGE_RESOURCE_DIRECTORY *res_dir = (IMAGE_RESOURCE_DIRECTORY*)(dir->VirtualAddress + (ULONGLONG)modulePtr);
|
||||
if (!peconv::validate_ptr(modulePtr, module_size, res_dir, sizeof(IMAGE_DEBUG_DIRECTORY))) {
|
||||
return false;
|
||||
}
|
||||
return parse_resource_dir(modulePtr, module_size, nullptr, res_dir, res_dir, on_entry);
|
||||
}
|
||||
56
ai_anti_malware/libpeconv/libpeconv/src/resource_util.cpp
Normal file
56
ai_anti_malware/libpeconv/libpeconv/src/resource_util.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "peconv/resource_util.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
HMODULE peconv::get_current_module_handle()
|
||||
{
|
||||
HMODULE hMod = NULL;
|
||||
GetModuleHandleExW(
|
||||
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
reinterpret_cast<LPCWSTR>(&peconv::get_current_module_handle),
|
||||
&hMod);
|
||||
return hMod;
|
||||
}
|
||||
|
||||
peconv::ALIGNED_BUF peconv::load_resource_data(OUT size_t &out_size, int res_id, const LPSTR res_type, HMODULE hInstance)
|
||||
{
|
||||
if (hInstance == nullptr) {
|
||||
hInstance = GetModuleHandleA(NULL);
|
||||
}
|
||||
HRSRC res = FindResourceA(hInstance, MAKEINTRESOURCEA(res_id), res_type);
|
||||
if (!res) {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Cannot find resource" << std::endl;
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
HGLOBAL res_handle = LoadResource(hInstance, res);
|
||||
if (res_handle == nullptr) {
|
||||
#ifdef _DEBUG
|
||||
std::cerr << "Cannot get resource handle" << std::endl;
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
BYTE* res_data = (BYTE*) LockResource(res_handle);
|
||||
size_t r_size = static_cast<size_t>(SizeofResource(hInstance, res));
|
||||
if (out_size != 0 && out_size <= r_size) {
|
||||
r_size = out_size;
|
||||
}
|
||||
|
||||
peconv::ALIGNED_BUF out_buf = peconv::alloc_aligned(r_size, PAGE_READWRITE);
|
||||
if (out_buf != nullptr) {
|
||||
memcpy(out_buf, res_data, r_size);
|
||||
out_size = r_size;
|
||||
} else {
|
||||
out_size = 0;
|
||||
}
|
||||
FreeResource(res_handle);
|
||||
return out_buf;
|
||||
}
|
||||
|
||||
void peconv::free_resource_data(peconv::ALIGNED_BUF buffer)
|
||||
{
|
||||
peconv::free_aligned(buffer);
|
||||
}
|
||||
100
ai_anti_malware/libpeconv/libpeconv/src/util.cpp
Normal file
100
ai_anti_malware/libpeconv/libpeconv/src/util.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#include "peconv/util.h"
|
||||
|
||||
namespace peconv {
|
||||
DWORD(WINAPI *g_GetProcessId)(IN HANDLE Process) = nullptr;
|
||||
|
||||
HMODULE g_kernel32Hndl = nullptr;
|
||||
HMODULE g_ntdllHndl = nullptr;
|
||||
|
||||
HMODULE get_kernel32_hndl()
|
||||
{
|
||||
if (g_kernel32Hndl == nullptr) {
|
||||
g_kernel32Hndl = LoadLibraryA("kernel32.dll");
|
||||
}
|
||||
return g_kernel32Hndl;
|
||||
}
|
||||
|
||||
HMODULE get_ntdll_hndl()
|
||||
{
|
||||
if (g_ntdllHndl == nullptr) {
|
||||
g_ntdllHndl = LoadLibraryA("ntdll.dll");
|
||||
}
|
||||
return g_ntdllHndl;
|
||||
}
|
||||
};
|
||||
|
||||
DWORD ntdll_get_process_id(HANDLE hProcess)
|
||||
{
|
||||
#if !defined PROCESSINFOCLASS
|
||||
typedef LONG PROCESSINFOCLASS;
|
||||
#endif
|
||||
|
||||
NTSTATUS(WINAPI *_ZwQueryInformationProcess)(
|
||||
IN HANDLE ProcessHandle,
|
||||
IN PROCESSINFOCLASS ProcessInformationClass,
|
||||
OUT PVOID ProcessInformation,
|
||||
IN ULONG ProcessInformationLength,
|
||||
OUT PULONG ReturnLength
|
||||
) = NULL;
|
||||
|
||||
HINSTANCE hNtDll = peconv::get_ntdll_hndl();
|
||||
if (!hNtDll) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
FARPROC procPtr = GetProcAddress(hNtDll, "ZwQueryInformationProcess");
|
||||
if (!procPtr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
_ZwQueryInformationProcess = (NTSTATUS(WINAPI *)(
|
||||
HANDLE,
|
||||
PROCESSINFOCLASS,
|
||||
PVOID,
|
||||
ULONG,
|
||||
PULONG)
|
||||
) procPtr;
|
||||
|
||||
typedef struct _PROCESS_BASIC_INFORMATION {
|
||||
PVOID Reserved1;
|
||||
PVOID PebBaseAddress;
|
||||
PVOID Reserved2[2];
|
||||
ULONG_PTR UniqueProcessId;
|
||||
PVOID Reserved3;
|
||||
} PROCESS_BASIC_INFORMATION;
|
||||
|
||||
PROCESS_BASIC_INFORMATION pbi = { 0 };
|
||||
if (_ZwQueryInformationProcess(hProcess, 0, &pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL) == S_OK) {
|
||||
const DWORD pid = static_cast<DWORD>(pbi.UniqueProcessId);
|
||||
return pid;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD peconv::get_process_id(HANDLE hProcess)
|
||||
{
|
||||
if (!peconv::g_GetProcessId) {
|
||||
HMODULE kernelLib = peconv::get_kernel32_hndl();
|
||||
if (!kernelLib) return FALSE;
|
||||
|
||||
FARPROC procPtr = GetProcAddress(kernelLib, "GetProcessId");
|
||||
if (!procPtr) return FALSE;
|
||||
|
||||
peconv::g_GetProcessId = (DWORD(WINAPI *) (IN HANDLE))procPtr;
|
||||
}
|
||||
if (peconv::g_GetProcessId) {
|
||||
return peconv::g_GetProcessId(hProcess);
|
||||
}
|
||||
//could not retrieve Pid using GetProcessId, try using NTDLL:
|
||||
return ntdll_get_process_id(hProcess);
|
||||
}
|
||||
|
||||
bool peconv::is_padding(const BYTE *cave_ptr, size_t cave_size, const BYTE padding)
|
||||
{
|
||||
for (size_t i = 0; i < cave_size; i++) {
|
||||
if (cave_ptr[i] != padding) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
1028
ai_anti_malware/native_struct.h
Normal file
1028
ai_anti_malware/native_struct.h
Normal file
File diff suppressed because it is too large
Load Diff
575
ai_anti_malware/sandbox.cpp
Normal file
575
ai_anti_malware/sandbox.cpp
Normal file
@@ -0,0 +1,575 @@
|
||||
#include "sandbox.h"
|
||||
#include "sandbox_callbacks.h"
|
||||
std::string getDllNameFromApiSetMap(const std::string& apiSet) {
|
||||
const std::wstring wApiSet(apiSet.begin(), apiSet.end());
|
||||
|
||||
// 获取系统版本信息
|
||||
using RtlGetVersionFunc = LONG(__stdcall*)(PRTL_OSVERSIONINFOW);
|
||||
const auto pRtlGetVersion = reinterpret_cast<RtlGetVersionFunc>(
|
||||
GetProcAddress(LoadLibraryA("ntdll.dll"), "RtlGetVersion"));
|
||||
|
||||
RTL_OSVERSIONINFOEXW verInfo{};
|
||||
verInfo.dwOSVersionInfoSize = sizeof(verInfo);
|
||||
pRtlGetVersion(reinterpret_cast<PRTL_OSVERSIONINFOW>(&verInfo));
|
||||
|
||||
const ULONG verShort = (verInfo.dwMajorVersion << 8) |
|
||||
(verInfo.dwMinorVersion << 4) |
|
||||
verInfo.wServicePackMajor;
|
||||
|
||||
if (verShort >= static_cast<ULONG>(WinVer::kWin10)) {
|
||||
const auto apiSetMap = reinterpret_cast<API_SET_NAMESPACE_ARRAY_10*>(
|
||||
reinterpret_cast<X64PEB*>(__readgsqword(0x60))->ApiSetMap);
|
||||
const auto apiSetMapAsNumber = reinterpret_cast<ULONG_PTR>(apiSetMap);
|
||||
auto nsEntry = reinterpret_cast<PAPI_SET_NAMESPACE_ENTRY_10>(
|
||||
apiSetMap->Start + apiSetMapAsNumber);
|
||||
|
||||
// 遍历API集合查找匹配项
|
||||
for (ULONG i = 0; i < apiSetMap->Count; i++) {
|
||||
UNICODE_STRING nameString{}, valueString{};
|
||||
nameString.MaximumLength = static_cast<USHORT>(nsEntry->NameLength);
|
||||
nameString.Length = static_cast<USHORT>(nsEntry->NameLength);
|
||||
nameString.Buffer = reinterpret_cast<PWCHAR>(apiSetMapAsNumber +
|
||||
nsEntry->NameOffset);
|
||||
|
||||
const std::wstring name(nameString.Buffer,
|
||||
nameString.Length / sizeof(WCHAR));
|
||||
const std::wstring fullName = name + L".dll";
|
||||
|
||||
if (_wcsicmp(wApiSet.c_str(), fullName.c_str()) == 0) {
|
||||
if (nsEntry->ValueCount == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const auto valueEntry =
|
||||
reinterpret_cast<PAPI_SET_VALUE_ENTRY_10>(
|
||||
apiSetMapAsNumber + nsEntry->ValueOffset);
|
||||
valueString.Buffer = reinterpret_cast<PWCHAR>(
|
||||
apiSetMapAsNumber + valueEntry->ValueOffset);
|
||||
valueString.MaximumLength =
|
||||
static_cast<USHORT>(valueEntry->ValueLength);
|
||||
valueString.Length =
|
||||
static_cast<USHORT>(valueEntry->ValueLength);
|
||||
|
||||
const std::wstring value(valueString.Buffer,
|
||||
valueString.Length / sizeof(WCHAR));
|
||||
return {value.begin(), value.end()};
|
||||
}
|
||||
++nsEntry;
|
||||
}
|
||||
} else {
|
||||
// 不支持Windows 10以下版本
|
||||
throw std::runtime_error("Unsupported Windows version");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
class ImportResolver : public peconv::t_function_resolver {
|
||||
public:
|
||||
explicit ImportResolver(std::map<std::string, uint64_t> context)
|
||||
: _functionMap(std::move(context)) {}
|
||||
|
||||
FARPROC resolve_func(LPSTR libName, LPSTR funcName) override {
|
||||
return reinterpret_cast<FARPROC>(_functionMap[std::string(funcName)]);
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<std::string, uint64_t> _functionMap;
|
||||
};
|
||||
|
||||
class cListImportNames : public peconv::ImportThunksCallback {
|
||||
public:
|
||||
cListImportNames(BYTE* _modulePtr, size_t _moduleSize,
|
||||
std::vector<std::shared_ptr<moudle_import>>& name_to_addr)
|
||||
: ImportThunksCallback(_modulePtr, _moduleSize),
|
||||
nameToAddr(name_to_addr) {}
|
||||
|
||||
virtual bool processThunks(LPSTR lib_name, ULONG_PTR origFirstThunkPtr,
|
||||
ULONG_PTR firstThunkPtr) {
|
||||
if (this->is64b) {
|
||||
IMAGE_THUNK_DATA64* desc =
|
||||
reinterpret_cast<IMAGE_THUNK_DATA64*>(origFirstThunkPtr);
|
||||
ULONGLONG* call_via = reinterpret_cast<ULONGLONG*>(firstThunkPtr);
|
||||
return processThunks_tpl<ULONGLONG, IMAGE_THUNK_DATA64>(
|
||||
lib_name, desc, call_via, IMAGE_ORDINAL_FLAG64);
|
||||
}
|
||||
IMAGE_THUNK_DATA32* desc =
|
||||
reinterpret_cast<IMAGE_THUNK_DATA32*>(origFirstThunkPtr);
|
||||
DWORD* call_via = reinterpret_cast<DWORD*>(firstThunkPtr);
|
||||
return processThunks_tpl<DWORD, IMAGE_THUNK_DATA32>(
|
||||
lib_name, desc, call_via, IMAGE_ORDINAL_FLAG32);
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename T_FIELD, typename T_IMAGE_THUNK_DATA>
|
||||
bool processThunks_tpl(LPSTR lib_name, T_IMAGE_THUNK_DATA* desc,
|
||||
T_FIELD* call_via, T_FIELD ordinal_flag) {
|
||||
DWORD call_via_rva = static_cast<DWORD>((ULONG_PTR)call_via -
|
||||
(ULONG_PTR)this->modulePtr);
|
||||
LPSTR func_name = NULL;
|
||||
if ((desc->u1.Ordinal & ordinal_flag) == 0) {
|
||||
PIMAGE_IMPORT_BY_NAME by_name =
|
||||
(PIMAGE_IMPORT_BY_NAME)((ULONGLONG)modulePtr +
|
||||
desc->u1.AddressOfData);
|
||||
func_name = reinterpret_cast<LPSTR>(by_name->Name);
|
||||
std::string fuck_up_api_ms = lib_name;
|
||||
if (fuck_up_api_ms.find("api-ms-") != std::string::npos) {
|
||||
fuck_up_api_ms = getDllNameFromApiSetMap(fuck_up_api_ms);
|
||||
if (fuck_up_api_ms.size() <= 1) __debugbreak();
|
||||
}
|
||||
auto import_data = std::make_shared<moudle_import>();
|
||||
memcpy(import_data->name, func_name, strlen(func_name));
|
||||
memcpy(import_data->dll_name, fuck_up_api_ms.c_str(),
|
||||
fuck_up_api_ms.size());
|
||||
import_data->function_address = call_via_rva;
|
||||
import_data->is_delayed_import = false;
|
||||
nameToAddr.push_back(import_data);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<moudle_import>>& nameToAddr;
|
||||
};
|
||||
|
||||
Sandbox::Sandbox() {}
|
||||
|
||||
Sandbox::~Sandbox() {}
|
||||
|
||||
auto Sandbox::PushModuleToVM(const char* dllName, uint64_t moduleBase,
|
||||
uint32_t x32Base) -> void {
|
||||
// 检查模块是否已加载
|
||||
auto isModuleLoaded =
|
||||
std::any_of(m_moduleList.begin(), m_moduleList.end(),
|
||||
[moduleBase](std::shared_ptr<struct_moudle> module) {
|
||||
return module->base == moduleBase;
|
||||
});
|
||||
|
||||
if (isModuleLoaded) {
|
||||
std::cout << "[PE] Skipping " << dllName << " (already loaded)\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// 解析PE头
|
||||
auto* dosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(moduleBase);
|
||||
auto* ntHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(
|
||||
reinterpret_cast<LPBYTE>(moduleBase) + dosHeader->e_lfanew);
|
||||
|
||||
// 获取区段对齐值
|
||||
DWORD sectionAlignment =
|
||||
(ntHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
|
||||
? reinterpret_cast<PIMAGE_NT_HEADERS64>(ntHeaders)
|
||||
->OptionalHeader.SectionAlignment
|
||||
: ntHeaders->OptionalHeader.SectionAlignment;
|
||||
|
||||
// 获取区段头
|
||||
auto* sectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>(
|
||||
reinterpret_cast<PUCHAR>(ntHeaders) + sizeof(ntHeaders->Signature) +
|
||||
sizeof(ntHeaders->FileHeader) +
|
||||
ntHeaders->FileHeader.SizeOfOptionalHeader);
|
||||
|
||||
// 创建新模块
|
||||
struct_moudle newModule{};
|
||||
strncpy(newModule.name, dllName, strlen(dllName));
|
||||
newModule.base = this->m_peInfo->isX64 ? moduleBase : x32Base;
|
||||
newModule.entry = ntHeaders->OptionalHeader.AddressOfEntryPoint;
|
||||
newModule.size = ntHeaders->OptionalHeader.SizeOfImage;
|
||||
|
||||
// 处理区段
|
||||
for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) {
|
||||
const auto& section = sectionHeader[i];
|
||||
|
||||
// if (!(section.Characteristics &
|
||||
// (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE))) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// 设置区段保护属性
|
||||
int protection = UC_PROT_READ;
|
||||
if (section.Characteristics & IMAGE_SCN_MEM_EXECUTE)
|
||||
protection |= UC_PROT_EXEC;
|
||||
if (section.Characteristics & IMAGE_SCN_MEM_WRITE)
|
||||
protection |= UC_PROT_WRITE;
|
||||
|
||||
// 计算区段大小
|
||||
auto sectionSize =
|
||||
AlignSize(max(section.Misc.VirtualSize, section.SizeOfRawData),
|
||||
sectionAlignment);
|
||||
|
||||
// 创建区段信息
|
||||
moudle_section newSection{};
|
||||
strncpy(newSection.name, reinterpret_cast<const char*>(section.Name),
|
||||
8);
|
||||
newSection.base = section.VirtualAddress;
|
||||
newSection.size = sectionSize;
|
||||
newSection.protect_flag = protection;
|
||||
|
||||
newModule.sections.push_back(
|
||||
std::make_shared<moudle_section>(newSection));
|
||||
std::cout << "[PE] " << dllName << " Section found: " << newSection.name
|
||||
<< '\n';
|
||||
}
|
||||
m_moduleList.push_back(std::make_shared<struct_moudle>(newModule));
|
||||
uc_mem_map(m_ucEngine, moduleBase, newModule.size,
|
||||
UC_PROT_READ | UC_PROT_EXEC);
|
||||
uc_mem_write(m_ucEngine, moduleBase, (void*)moduleBase, newModule.size);
|
||||
}
|
||||
|
||||
auto Sandbox::ResolveExport() -> void {
|
||||
DWORD exportSize = 0;
|
||||
static RtlImageDirectoryEntryToDataFn fnRtlImageDirectoryEntryToData;
|
||||
if (fnRtlImageDirectoryEntryToData == nullptr) {
|
||||
fnRtlImageDirectoryEntryToData =
|
||||
reinterpret_cast<RtlImageDirectoryEntryToDataFn>(GetProcAddress(
|
||||
GetModuleHandleA("ntdll.dll"), "RtlImageDirectoryEntryToData"));
|
||||
}
|
||||
// 获取导出表
|
||||
PIMAGE_EXPORT_DIRECTORY exportDirectory =
|
||||
static_cast<PIMAGE_EXPORT_DIRECTORY>(fnRtlImageDirectoryEntryToData(
|
||||
m_peInfo->peBuffer, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT,
|
||||
&exportSize));
|
||||
|
||||
if (exportDirectory) {
|
||||
const DWORD numberOfNames = exportDirectory->NumberOfNames;
|
||||
PDWORD addressOfFunctions =
|
||||
reinterpret_cast<PDWORD>(static_cast<PUCHAR>(m_peInfo->peBuffer) +
|
||||
exportDirectory->AddressOfFunctions);
|
||||
PDWORD addressOfNames =
|
||||
reinterpret_cast<PDWORD>(static_cast<PUCHAR>(m_peInfo->peBuffer) +
|
||||
exportDirectory->AddressOfNames);
|
||||
PWORD addressOfNameOrdinals =
|
||||
reinterpret_cast<PWORD>(static_cast<PUCHAR>(m_peInfo->peBuffer) +
|
||||
exportDirectory->AddressOfNameOrdinals);
|
||||
|
||||
// 遍历导出函数
|
||||
for (size_t i = 0; i < numberOfNames; i++) {
|
||||
PCHAR functionName = reinterpret_cast<PCHAR>(
|
||||
static_cast<PUCHAR>(m_peInfo->peBuffer) + addressOfNames[i]);
|
||||
|
||||
// 获取函数RVA
|
||||
const DWORD functionRva =
|
||||
addressOfFunctions[addressOfNameOrdinals[i]];
|
||||
|
||||
// 创建导出数据结构
|
||||
moudle_export exportData{};
|
||||
memcpy(exportData.name, functionName, strlen(functionName));
|
||||
exportData.function_address = functionRva;
|
||||
|
||||
m_exportFuncDict.push_back(
|
||||
std::make_shared<moudle_export>(exportData));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto Sandbox::processImportModule(const moudle_import* importModule) -> void {
|
||||
// 构建模块路径
|
||||
const std::string systemDir =
|
||||
m_peInfo->isX64 ? "\\System32\\" : "\\SysWOW64\\";
|
||||
char windowsPath[MAX_PATH];
|
||||
if (!GetWindowsDirectoryA(windowsPath, sizeof(windowsPath))) {
|
||||
throw std::runtime_error("Failed to get Windows directory");
|
||||
}
|
||||
|
||||
const std::string modulePath =
|
||||
std::string(windowsPath) + systemDir + importModule->dll_name;
|
||||
|
||||
// 加载PE模块
|
||||
size_t mappedPeSize = 0;
|
||||
const auto moduleBase = reinterpret_cast<uint64_t>(
|
||||
peconv::load_pe_module(modulePath.c_str(), mappedPeSize, false, false));
|
||||
|
||||
if (!moduleBase) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 添加到虚拟机
|
||||
const auto moduleBase32 = static_cast<uint32_t>(moduleBase);
|
||||
PushModuleToVM(importModule->dll_name, moduleBase, moduleBase32);
|
||||
}
|
||||
auto Sandbox::ResoveImport() -> void {
|
||||
// 处理延迟导入
|
||||
peconv::load_delayed_imports(static_cast<BYTE*>(m_peInfo->peBuffer), 0);
|
||||
|
||||
// 解析导入表
|
||||
cListImportNames importCallback(static_cast<BYTE*>(m_peInfo->peBuffer),
|
||||
m_peInfo->peSize, m_impFuncDict);
|
||||
|
||||
if (!peconv::process_import_table(static_cast<BYTE*>(m_peInfo->peBuffer),
|
||||
m_peInfo->peSize, &importCallback)) {
|
||||
throw std::runtime_error("Failed to process import table");
|
||||
}
|
||||
|
||||
// 处理每个导入模块
|
||||
for (const auto& importModule : m_impFuncDict) {
|
||||
processImportModule(importModule.get());
|
||||
}
|
||||
}
|
||||
auto Sandbox::SetupVirtualMachine() -> void {
|
||||
SegmentSelector cs = {0};
|
||||
cs.fields.index = 1;
|
||||
uc_reg_write(m_ucEngine, UC_X86_REG_CS, &cs.all);
|
||||
|
||||
SegmentSelector ds = {0};
|
||||
ds.fields.index = 2;
|
||||
uc_reg_write(m_ucEngine, UC_X86_REG_DS, &ds.all);
|
||||
|
||||
SegmentSelector ss = {0};
|
||||
ss.fields.index = 2;
|
||||
uc_reg_write(m_ucEngine, UC_X86_REG_SS, &ss.all);
|
||||
|
||||
SegmentSelector es = {0};
|
||||
es.fields.index = 2;
|
||||
uc_reg_write(m_ucEngine, UC_X86_REG_ES, &es.all);
|
||||
|
||||
SegmentSelector gs = {0};
|
||||
gs.fields.index = 2;
|
||||
uc_reg_write(m_ucEngine, UC_X86_REG_GS, &gs.all);
|
||||
|
||||
FlagRegister eflags = {0};
|
||||
eflags.fields.id = 1;
|
||||
eflags.fields.intf = 1;
|
||||
eflags.fields.reserved1 = 1;
|
||||
|
||||
uc_reg_write(m_ucEngine, UC_X86_REG_EFLAGS, &eflags.all);
|
||||
|
||||
uint64_t cr8 = 0;
|
||||
uc_reg_write(m_ucEngine, UC_X86_REG_CR8, &cr8);
|
||||
|
||||
/*
|
||||
映射 m_KSharedUserDataBase
|
||||
*/
|
||||
uint64_t m_KSharedUserDataBase = 0x7FFE0000;
|
||||
uint64_t m_KSharedUserDataEnd = 0x7FFE0FFF; // 0x7FFE2000
|
||||
uint64_t m_KSharedUserDataSize =
|
||||
AlignSize(m_KSharedUserDataEnd - m_KSharedUserDataBase, PAGE_SIZE);
|
||||
|
||||
uc_mem_map(m_ucEngine, m_KSharedUserDataBase, m_KSharedUserDataSize,
|
||||
UC_PROT_READ);
|
||||
uc_mem_write(m_ucEngine, m_KSharedUserDataBase,
|
||||
(void*)m_KSharedUserDataBase, m_KSharedUserDataSize);
|
||||
|
||||
m_tebBase = TEB_BASE; // 进程TEB地址
|
||||
m_pebBase = PEB_BASE; // 进程PEB地址
|
||||
// stack
|
||||
m_stackBase = this->m_peInfo->isX64 ? STACK_BASE_64 : STACK_BASE_32;
|
||||
m_stackSize = this->m_peInfo->isX64 ? STACK_SIZE_64 : STACK_SIZE_32;
|
||||
m_stackEnd = m_stackBase + m_stackSize;
|
||||
|
||||
// heap
|
||||
m_heapBase = this->m_peInfo->isX64 ? HEAP_ADDRESS_64 : HEAP_ADDRESS_32;
|
||||
m_heapSize = this->m_peInfo->isX64 ? HEAP_SIZE_64 : HEAP_SIZE_32;
|
||||
m_heapEnd = m_heapBase + m_heapSize;
|
||||
|
||||
// 根据PE文件类型设置PEB和TEB
|
||||
if (this->m_peInfo->isX64) {
|
||||
// 设置64位PEB
|
||||
m_peb64.ImageBaseAddress = m_peInfo->RecImageBase;
|
||||
m_pebEnd = m_pebBase + AlignSize(sizeof(X64PEB), PAGE_SIZE);
|
||||
m_tebEnd = m_tebBase + AlignSize(sizeof(X64TEB), PAGE_SIZE);
|
||||
|
||||
// 设置64位TEB
|
||||
m_teb64.ClientId.UniqueProcess = GetCurrentProcessId();
|
||||
m_teb64.ClientId.UniqueThread = GetCurrentThreadId();
|
||||
m_teb64.ProcessEnvironmentBlock = reinterpret_cast<X64PEB*>(m_pebBase);
|
||||
m_teb64.NtTib.StackBase = (DWORD64)m_stackBase;
|
||||
m_teb64.NtTib.StackLimit = (DWORD64)m_stackSize;
|
||||
|
||||
// 设置堆
|
||||
m_peb64.ProcessHeap = m_heapBase;
|
||||
|
||||
// 设置GS基址结构
|
||||
m_gsBaseStruct.teb = m_tebBase;
|
||||
m_gsBaseStruct.peb = m_pebBase;
|
||||
uint64_t gsAllocSize = AlignSize(sizeof(struct_gs_base), PAGE_SIZE);
|
||||
|
||||
// 映射PEB到虚拟内存
|
||||
uc_mem_map(m_ucEngine, m_pebBase, m_pebEnd - m_pebBase,
|
||||
UC_PROT_READ | UC_PROT_WRITE);
|
||||
uc_mem_write(m_ucEngine, m_pebBase, &m_peb64, sizeof(X64PEB));
|
||||
|
||||
// 映射TEB到虚拟内存
|
||||
uc_mem_map(m_ucEngine, m_tebBase, m_tebEnd - m_tebBase,
|
||||
UC_PROT_READ | UC_PROT_WRITE);
|
||||
uc_mem_write(m_ucEngine, m_tebBase, &m_teb64, sizeof(X64TEB));
|
||||
|
||||
// 映射GS基址结构到虚拟内存
|
||||
uc_mem_map(m_ucEngine, m_gsBase, gsAllocSize, UC_PROT_READ);
|
||||
uc_mem_write(m_ucEngine, m_gsBase, &m_gsBaseStruct,
|
||||
sizeof(struct_gs_base));
|
||||
|
||||
// 设置GS基址MSR
|
||||
uc_x86_msr msr;
|
||||
msr.rid = static_cast<uint32_t>(Msr::kIa32GsBase);
|
||||
msr.value = m_gsBase;
|
||||
uc_reg_write(m_ucEngine, UC_X86_REG_MSR, &msr);
|
||||
} else {
|
||||
// 设置32位PEB
|
||||
m_peb32.ImageBaseAddress = static_cast<ULONG>(m_peInfo->RecImageBase);
|
||||
m_pebEnd = m_pebBase + AlignSize(sizeof(X32PEB), PAGE_SIZE);
|
||||
m_tebEnd = m_tebBase + AlignSize(sizeof(X32TEB), PAGE_SIZE);
|
||||
|
||||
// 设置32位TEB
|
||||
m_teb32.ClientId.UniqueProcess = GetCurrentProcessId();
|
||||
m_teb32.ClientId.UniqueThread = GetCurrentThreadId();
|
||||
m_teb32.ProcessEnvironmentBlock = static_cast<ULONG>(m_pebBase);
|
||||
m_teb32.NtTib.StackBase = static_cast<ULONG>(m_stackBase);
|
||||
m_teb32.NtTib.StackLimit = static_cast<ULONG>(m_stackSize);
|
||||
|
||||
// 设置堆
|
||||
m_peb32.ProcessHeap = static_cast<ULONG>(m_heapBase);
|
||||
|
||||
// 映射PEB到虚拟内存
|
||||
uc_mem_map(m_ucEngine, m_pebBase, m_pebEnd - m_pebBase,
|
||||
UC_PROT_READ | UC_PROT_WRITE);
|
||||
uc_mem_write(m_ucEngine, m_pebBase, &m_peb32, sizeof(X32PEB));
|
||||
|
||||
// 映射TEB到虚拟内存
|
||||
uc_mem_map(m_ucEngine, m_tebBase, m_tebEnd - m_tebBase,
|
||||
UC_PROT_READ | UC_PROT_WRITE);
|
||||
uc_mem_write(m_ucEngine, m_tebBase, &m_teb32, sizeof(X32TEB));
|
||||
|
||||
// 对于32位,我们需要设置FS段寄存器指向TEB
|
||||
SegmentSelector fs = {0};
|
||||
fs.fields.index = 3;
|
||||
uc_reg_write(m_ucEngine, UC_X86_REG_FS, &fs.all);
|
||||
|
||||
// 设置FS基址MSR
|
||||
uc_x86_msr msr;
|
||||
msr.rid = static_cast<uint32_t>(Msr::kIa32FsBase);
|
||||
msr.value = m_tebBase;
|
||||
uc_reg_write(m_ucEngine, UC_X86_REG_MSR, &msr);
|
||||
}
|
||||
}
|
||||
auto Sandbox::InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void {
|
||||
m_peInfo = peInfo;
|
||||
|
||||
if (cs_open(CS_ARCH_X86, peInfo->isX64 ? CS_MODE_64 : CS_MODE_32,
|
||||
&m_csHandle) != CS_ERR_OK) {
|
||||
throw std::runtime_error("Failed to initialize Capstone");
|
||||
}
|
||||
if (uc_open(UC_ARCH_X86, peInfo->isX64 ? UC_MODE_64 : UC_MODE_32,
|
||||
&m_ucEngine) != UC_ERR_OK) {
|
||||
cs_close(&m_csHandle); // 清理已分配的capstone资源
|
||||
throw std::runtime_error("Failed to initialize Unicorn");
|
||||
}
|
||||
ResoveImport();
|
||||
ResolveExport();
|
||||
uc_err ucErr = uc_mem_map(m_ucEngine, m_peInfo->RecImageBase,
|
||||
m_peInfo->peSize, UC_PROT_ALL);
|
||||
if (ucErr != UC_ERR_OK) {
|
||||
throw std::runtime_error("Failed to map memory");
|
||||
}
|
||||
uc_mem_write(m_ucEngine, m_peInfo->RecImageBase, m_peInfo->peBuffer,
|
||||
m_peInfo->peSize);
|
||||
printf("map file to vm file: %llx\n", m_peInfo->RecImageBase);
|
||||
printf("map file to vm size: %llx\n", m_peInfo->peSize);
|
||||
SetupVirtualMachine();
|
||||
}
|
||||
|
||||
auto Sandbox::Run() -> void {
|
||||
// 初始化堆栈
|
||||
uc_err err = uc_mem_map(m_ucEngine, m_stackBase, m_stackSize,
|
||||
UC_PROT_READ | UC_PROT_WRITE);
|
||||
if (err != UC_ERR_OK) {
|
||||
throw std::runtime_error("Failed to map stack memory");
|
||||
}
|
||||
|
||||
// 初始化堆
|
||||
err = uc_mem_map(m_ucEngine, m_heapBase, m_heapSize,
|
||||
UC_PROT_READ | UC_PROT_WRITE);
|
||||
if (err != UC_ERR_OK) {
|
||||
throw std::runtime_error("Failed to map heap memory");
|
||||
}
|
||||
|
||||
// 设置寄存器
|
||||
uint64_t rsp = m_stackEnd - 128;
|
||||
err = uc_reg_write(m_ucEngine,
|
||||
m_peInfo->isX64 ? UC_X86_REG_RSP : UC_X86_REG_ESP, &rsp);
|
||||
if (err != UC_ERR_OK) {
|
||||
throw std::runtime_error("Failed to write stack pointer");
|
||||
}
|
||||
|
||||
// 设置入口点
|
||||
uint64_t entryPoint = m_peInfo->RecImageBase + m_peInfo->entryPoint;
|
||||
|
||||
// 添加钩子
|
||||
uc_hook hook_code, hook_mem, hook_mem_unmap, hook_mem_write, hook_syscall;
|
||||
|
||||
// 代码执行钩子
|
||||
err = uc_hook_add(m_ucEngine, &hook_code, UC_HOOK_CODE,
|
||||
reinterpret_cast<void*>(sandboxCallbacks::handleCodeRun),
|
||||
this, 1, 0);
|
||||
if (err != UC_ERR_OK) {
|
||||
throw std::runtime_error("Failed to add code hook");
|
||||
}
|
||||
|
||||
// 内存读取钩子
|
||||
err =
|
||||
uc_hook_add(m_ucEngine, &hook_mem, UC_HOOK_MEM_READ | UC_HOOK_MEM_FETCH,
|
||||
reinterpret_cast<void*>(sandboxCallbacks::handleMemoryRead),
|
||||
this, 1, 0);
|
||||
if (err != UC_ERR_OK) {
|
||||
throw std::runtime_error("Failed to add memory read hook");
|
||||
}
|
||||
|
||||
// 未映射内存访问钩子
|
||||
err = uc_hook_add(
|
||||
m_ucEngine, &hook_mem_unmap,
|
||||
UC_HOOK_MEM_FETCH_UNMAPPED | UC_HOOK_MEM_READ_UNMAPPED |
|
||||
UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_FETCH_PROT,
|
||||
reinterpret_cast<void*>(sandboxCallbacks::handleMemoryUnmapRead), this,
|
||||
1, 0);
|
||||
if (err != UC_ERR_OK) {
|
||||
throw std::runtime_error("Failed to add unmapped memory hook");
|
||||
}
|
||||
|
||||
// 内存写入钩子
|
||||
err = uc_hook_add(
|
||||
m_ucEngine, &hook_mem_write, UC_HOOK_MEM_WRITE | UC_HOOK_MEM_WRITE_PROT,
|
||||
reinterpret_cast<void*>(sandboxCallbacks::handleMemoryWrite), this, 1,
|
||||
0);
|
||||
if (err != UC_ERR_OK) {
|
||||
throw std::runtime_error("Failed to add memory write hook");
|
||||
}
|
||||
|
||||
// 系统调用钩子
|
||||
err = uc_hook_add(m_ucEngine, &hook_syscall, UC_HOOK_INTR | UC_HOOK_INSN,
|
||||
reinterpret_cast<void*>(sandboxCallbacks::handleSyscall),
|
||||
this, 1, 0, UC_X86_INS_SYSCALL);
|
||||
if (err != UC_ERR_OK) {
|
||||
throw std::runtime_error("Failed to add syscall hook");
|
||||
}
|
||||
|
||||
// 设置EIP/RIP
|
||||
err = uc_reg_write(m_ucEngine,
|
||||
m_peInfo->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP,
|
||||
&entryPoint);
|
||||
if (err != UC_ERR_OK) {
|
||||
throw std::runtime_error("Failed to set entry point");
|
||||
}
|
||||
|
||||
// 开始执行
|
||||
std::cout << "Starting execution at " << std::hex << entryPoint
|
||||
<< std::endl;
|
||||
err = uc_emu_start(m_ucEngine, entryPoint, m_peInfo->imageEnd, 0, 0);
|
||||
if (err != UC_ERR_OK) {
|
||||
std::cerr << "Emulation error: " << uc_strerror(err) << std::endl;
|
||||
|
||||
// 32位环境下的错误处理
|
||||
if (!m_peInfo->isX64) {
|
||||
uint32_t eip;
|
||||
uc_reg_read(m_ucEngine, UC_X86_REG_EIP, &eip);
|
||||
std::cerr << "Error occurred at EIP: 0x" << std::hex << eip
|
||||
<< std::endl;
|
||||
|
||||
// 尝试读取当前指令
|
||||
uint8_t instruction[16];
|
||||
if (uc_mem_read(m_ucEngine, eip, instruction,
|
||||
sizeof(instruction)) == UC_ERR_OK) {
|
||||
std::cerr << "Instruction bytes: ";
|
||||
for (int i = 0; i < 16; i++) {
|
||||
printf("%02X ", instruction[i]);
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
94
ai_anti_malware/sandbox.h
Normal file
94
ai_anti_malware/sandbox.h
Normal file
@@ -0,0 +1,94 @@
|
||||
#pragma once
|
||||
#include "head.h"
|
||||
|
||||
#define PAGE_SIZE 0x1000
|
||||
#define CF_MASK (1 << 0)
|
||||
#define PF_MASK (1 << 2)
|
||||
#define ZF_MASK (1 << 6)
|
||||
#define SF_MASK (1 << 7)
|
||||
#define OF_MASK (1 << 11)
|
||||
#define ALL_MASK (OF_MASK | SF_MASK | ZF_MASK | PF_MASK | CF_MASK)
|
||||
#define STACK_BASE_64 0x7ffffffde000
|
||||
#define STACK_BASE_32 0xfffdd000
|
||||
#define STACK_SIZE_64 0x40000
|
||||
#define STACK_SIZE_32 0x21000
|
||||
#define HEAP_ADDRESS_64 0x500000000
|
||||
#define HEAP_SIZE_64 0x5000000
|
||||
#define HEAP_ADDRESS_32 0x5000000
|
||||
#define HEAP_SIZE_32 0x5000000
|
||||
|
||||
#define PEB_BASE 0x80000
|
||||
#define TEB_BASE 0x90000
|
||||
|
||||
#define X86_GDT_ADDR 0x30000
|
||||
#define X86_GDT_LIMIT 0x1000
|
||||
#define X86_GDT_ENTRY_SIZE 0x8
|
||||
|
||||
#define API_FUNCTION_SIZE 8
|
||||
#define PAGE_ALIGN(Va) (ULONG_PTR)(Va) & ~(PAGE_SIZE - 1)
|
||||
#define PAGE_ALIGN_64(Va) (Va) & ~(0x1000ull - 1)
|
||||
#define PAGE_ALIGN_64k(Va) ((Va)) & ~(0x10000ull - 1)
|
||||
#define AlignSize(Size, Align) (Size + Align - 1) / Align* Align
|
||||
|
||||
enum class WinVer {
|
||||
kWin7 = 0x0610,
|
||||
kWin7SP1 = 0x0611,
|
||||
kWin8 = 0x0620,
|
||||
kWin81 = 0x0630,
|
||||
kWin10 = 0x0A00,
|
||||
kWin10RS1 = 0x0A01, // Anniversary update
|
||||
kWin10RS2 = 0x0A02, // Creators update
|
||||
kWin10RS3 = 0x0A03, // Fall creators update
|
||||
kWin10RS4 = 0x0A04, // Spring creators update
|
||||
kWin10RS5 = 0x0A05, // October 2018 update
|
||||
kWin1019H1 = 0x0A06, // May 2019 update 19H1
|
||||
kWin1019H2 = 0x0A07, // November 2019 update 19H2
|
||||
kWin1020H1 = 0x0A08 // April 2020 update 20H1
|
||||
};
|
||||
|
||||
class Sandbox {
|
||||
public:
|
||||
Sandbox();
|
||||
~Sandbox();
|
||||
|
||||
// Public methods
|
||||
auto InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void;
|
||||
|
||||
auto Run() -> void;
|
||||
|
||||
auto GetCapstoneHandle() const -> csh { return m_csHandle; }
|
||||
auto GetUnicornHandle() const -> uc_engine* { return m_ucEngine; }
|
||||
auto GetPeInfo() const -> std::shared_ptr<BasicPeInfo> { return m_peInfo; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<BasicPeInfo> m_peInfo;
|
||||
uint64_t m_gsBase;
|
||||
uint64_t m_pebBase;
|
||||
uint64_t m_pebEnd;
|
||||
uint64_t m_tebBase;
|
||||
uint64_t m_tebEnd;
|
||||
PVOID m_stackBuffer; // 没有释放
|
||||
uint64_t m_stackBase;
|
||||
uint64_t m_stackSize;
|
||||
uint64_t m_stackEnd;
|
||||
uint64_t m_heapBase;
|
||||
uint64_t m_heapSize;
|
||||
uint64_t m_heapEnd;
|
||||
uint64_t m_fakeBase;
|
||||
struct_gs_base m_gsBaseStruct;
|
||||
X64TEB m_teb64;
|
||||
X64PEB m_peb64;
|
||||
X32TEB m_teb32;
|
||||
X32PEB m_peb32;
|
||||
csh m_csHandle; // Capstone handle
|
||||
uc_engine* m_ucEngine; // Unicorn engine handle
|
||||
std::vector<std::shared_ptr<moudle_import>> m_impFuncDict;
|
||||
std::vector<std::shared_ptr<moudle_export>> m_exportFuncDict;
|
||||
std::vector<std::shared_ptr<struct_moudle>> m_moduleList;
|
||||
auto ResoveImport() -> void;
|
||||
auto SetupVirtualMachine() -> void;
|
||||
auto ResolveExport() -> void;
|
||||
auto PushModuleToVM(const char* dllName, uint64_t moduleBase,
|
||||
uint32_t x32Base) -> void;
|
||||
auto processImportModule(const moudle_import* importModule) -> void;
|
||||
};
|
||||
1
ai_anti_malware/sandbox_callbacks.cpp
Normal file
1
ai_anti_malware/sandbox_callbacks.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "sandbox_callbacks.h"
|
||||
70
ai_anti_malware/sandbox_callbacks.h
Normal file
70
ai_anti_malware/sandbox_callbacks.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
#include "sandbox.h"
|
||||
|
||||
namespace sandboxCallbacks {
|
||||
static void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size,
|
||||
void* userData) {
|
||||
auto* sandbox = static_cast<Sandbox*>(userData);
|
||||
if (!sandbox) return;
|
||||
|
||||
// 读取当前执行的代码
|
||||
uint8_t* codeBuffer = new uint8_t[size];
|
||||
if (uc_mem_read(uc, address, codeBuffer, size) != UC_ERR_OK) {
|
||||
delete[] codeBuffer;
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用Capstone反汇编
|
||||
cs_insn* instruction;
|
||||
size_t instructionCount =
|
||||
cs_disasm(sandbox->GetCapstoneHandle(), codeBuffer, size, address, 0,
|
||||
&instruction);
|
||||
|
||||
if (instructionCount > 0) {
|
||||
// 打印地址和反汇编结果
|
||||
printf("0x%016" PRIx64 " %-12s %s\n", instruction[0].address,
|
||||
instruction[0].mnemonic, instruction[0].op_str);
|
||||
cs_free(instruction, instructionCount);
|
||||
}
|
||||
|
||||
delete[] codeBuffer;
|
||||
}
|
||||
|
||||
static void handleMemoryRead(uc_engine* uc, uc_mem_type type, uint64_t address,
|
||||
int size, int64_t value, void* userData) {
|
||||
auto* sandbox = static_cast<Sandbox*>(userData);
|
||||
if (!sandbox) return;
|
||||
|
||||
uint64_t regRax, regRip;
|
||||
uc_reg_read(uc,
|
||||
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||
®Rax);
|
||||
uc_reg_read(uc,
|
||||
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP,
|
||||
®Rip);
|
||||
|
||||
uint64_t readAddress;
|
||||
auto readError =
|
||||
uc_mem_read(sandbox->GetUnicornHandle(), address, &readAddress, size);
|
||||
printf(
|
||||
"[handleMemoryRead] Address: %p Size: %p Rax: %p Rip: %p Error: %d "
|
||||
"ReadData: %p\n",
|
||||
address, size, regRax, regRip, readError, readAddress);
|
||||
}
|
||||
|
||||
static void handleMemoryUnmapRead(uc_engine* uc, uc_mem_type type,
|
||||
uint64_t address, int size, int64_t value,
|
||||
void* userData) {
|
||||
// 待实现
|
||||
}
|
||||
|
||||
static void handleMemoryWrite(uc_engine* uc, uc_mem_type type, uint64_t address,
|
||||
int size, int64_t value, void* userData) {
|
||||
// 待实现
|
||||
}
|
||||
|
||||
static void handleSyscall(uc_engine* uc, void* userData) {
|
||||
// 待实现
|
||||
}
|
||||
|
||||
} // namespace sandboxCallbacks
|
||||
157
ai_anti_malware/unicorn/include/unicorn/arm.h
Normal file
157
ai_anti_malware/unicorn/include/unicorn/arm.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/* Unicorn Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2015-2017 */
|
||||
/* This file is released under LGPL2.
|
||||
See COPYING.LGPL2 in root directory for more details
|
||||
*/
|
||||
|
||||
#ifndef UNICORN_ARM_H
|
||||
#define UNICORN_ARM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
//> ARM registers
|
||||
typedef enum uc_arm_reg {
|
||||
UC_ARM_REG_INVALID = 0,
|
||||
UC_ARM_REG_APSR,
|
||||
UC_ARM_REG_APSR_NZCV,
|
||||
UC_ARM_REG_CPSR,
|
||||
UC_ARM_REG_FPEXC,
|
||||
UC_ARM_REG_FPINST,
|
||||
UC_ARM_REG_FPSCR,
|
||||
UC_ARM_REG_FPSCR_NZCV,
|
||||
UC_ARM_REG_FPSID,
|
||||
UC_ARM_REG_ITSTATE,
|
||||
UC_ARM_REG_LR,
|
||||
UC_ARM_REG_PC,
|
||||
UC_ARM_REG_SP,
|
||||
UC_ARM_REG_SPSR,
|
||||
UC_ARM_REG_D0,
|
||||
UC_ARM_REG_D1,
|
||||
UC_ARM_REG_D2,
|
||||
UC_ARM_REG_D3,
|
||||
UC_ARM_REG_D4,
|
||||
UC_ARM_REG_D5,
|
||||
UC_ARM_REG_D6,
|
||||
UC_ARM_REG_D7,
|
||||
UC_ARM_REG_D8,
|
||||
UC_ARM_REG_D9,
|
||||
UC_ARM_REG_D10,
|
||||
UC_ARM_REG_D11,
|
||||
UC_ARM_REG_D12,
|
||||
UC_ARM_REG_D13,
|
||||
UC_ARM_REG_D14,
|
||||
UC_ARM_REG_D15,
|
||||
UC_ARM_REG_D16,
|
||||
UC_ARM_REG_D17,
|
||||
UC_ARM_REG_D18,
|
||||
UC_ARM_REG_D19,
|
||||
UC_ARM_REG_D20,
|
||||
UC_ARM_REG_D21,
|
||||
UC_ARM_REG_D22,
|
||||
UC_ARM_REG_D23,
|
||||
UC_ARM_REG_D24,
|
||||
UC_ARM_REG_D25,
|
||||
UC_ARM_REG_D26,
|
||||
UC_ARM_REG_D27,
|
||||
UC_ARM_REG_D28,
|
||||
UC_ARM_REG_D29,
|
||||
UC_ARM_REG_D30,
|
||||
UC_ARM_REG_D31,
|
||||
UC_ARM_REG_FPINST2,
|
||||
UC_ARM_REG_MVFR0,
|
||||
UC_ARM_REG_MVFR1,
|
||||
UC_ARM_REG_MVFR2,
|
||||
UC_ARM_REG_Q0,
|
||||
UC_ARM_REG_Q1,
|
||||
UC_ARM_REG_Q2,
|
||||
UC_ARM_REG_Q3,
|
||||
UC_ARM_REG_Q4,
|
||||
UC_ARM_REG_Q5,
|
||||
UC_ARM_REG_Q6,
|
||||
UC_ARM_REG_Q7,
|
||||
UC_ARM_REG_Q8,
|
||||
UC_ARM_REG_Q9,
|
||||
UC_ARM_REG_Q10,
|
||||
UC_ARM_REG_Q11,
|
||||
UC_ARM_REG_Q12,
|
||||
UC_ARM_REG_Q13,
|
||||
UC_ARM_REG_Q14,
|
||||
UC_ARM_REG_Q15,
|
||||
UC_ARM_REG_R0,
|
||||
UC_ARM_REG_R1,
|
||||
UC_ARM_REG_R2,
|
||||
UC_ARM_REG_R3,
|
||||
UC_ARM_REG_R4,
|
||||
UC_ARM_REG_R5,
|
||||
UC_ARM_REG_R6,
|
||||
UC_ARM_REG_R7,
|
||||
UC_ARM_REG_R8,
|
||||
UC_ARM_REG_R9,
|
||||
UC_ARM_REG_R10,
|
||||
UC_ARM_REG_R11,
|
||||
UC_ARM_REG_R12,
|
||||
UC_ARM_REG_S0,
|
||||
UC_ARM_REG_S1,
|
||||
UC_ARM_REG_S2,
|
||||
UC_ARM_REG_S3,
|
||||
UC_ARM_REG_S4,
|
||||
UC_ARM_REG_S5,
|
||||
UC_ARM_REG_S6,
|
||||
UC_ARM_REG_S7,
|
||||
UC_ARM_REG_S8,
|
||||
UC_ARM_REG_S9,
|
||||
UC_ARM_REG_S10,
|
||||
UC_ARM_REG_S11,
|
||||
UC_ARM_REG_S12,
|
||||
UC_ARM_REG_S13,
|
||||
UC_ARM_REG_S14,
|
||||
UC_ARM_REG_S15,
|
||||
UC_ARM_REG_S16,
|
||||
UC_ARM_REG_S17,
|
||||
UC_ARM_REG_S18,
|
||||
UC_ARM_REG_S19,
|
||||
UC_ARM_REG_S20,
|
||||
UC_ARM_REG_S21,
|
||||
UC_ARM_REG_S22,
|
||||
UC_ARM_REG_S23,
|
||||
UC_ARM_REG_S24,
|
||||
UC_ARM_REG_S25,
|
||||
UC_ARM_REG_S26,
|
||||
UC_ARM_REG_S27,
|
||||
UC_ARM_REG_S28,
|
||||
UC_ARM_REG_S29,
|
||||
UC_ARM_REG_S30,
|
||||
UC_ARM_REG_S31,
|
||||
|
||||
UC_ARM_REG_C1_C0_2,
|
||||
UC_ARM_REG_C13_C0_2,
|
||||
UC_ARM_REG_C13_C0_3,
|
||||
|
||||
UC_ARM_REG_IPSR,
|
||||
UC_ARM_REG_MSP,
|
||||
UC_ARM_REG_PSP,
|
||||
UC_ARM_REG_CONTROL,
|
||||
UC_ARM_REG_ENDING, // <-- mark the end of the list or registers
|
||||
|
||||
//> alias registers
|
||||
UC_ARM_REG_R13 = UC_ARM_REG_SP,
|
||||
UC_ARM_REG_R14 = UC_ARM_REG_LR,
|
||||
UC_ARM_REG_R15 = UC_ARM_REG_PC,
|
||||
|
||||
UC_ARM_REG_SB = UC_ARM_REG_R9,
|
||||
UC_ARM_REG_SL = UC_ARM_REG_R10,
|
||||
UC_ARM_REG_FP = UC_ARM_REG_R11,
|
||||
UC_ARM_REG_IP = UC_ARM_REG_R12,
|
||||
} uc_arm_reg;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
344
ai_anti_malware/unicorn/include/unicorn/arm64.h
Normal file
344
ai_anti_malware/unicorn/include/unicorn/arm64.h
Normal file
@@ -0,0 +1,344 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2015-2017 */
|
||||
/* This file is released under LGPL2.
|
||||
See COPYING.LGPL2 in root directory for more details
|
||||
*/
|
||||
|
||||
#ifndef UNICORN_ARM64_H
|
||||
#define UNICORN_ARM64_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
//> ARM64 registers
|
||||
typedef enum uc_arm64_reg {
|
||||
UC_ARM64_REG_INVALID = 0,
|
||||
|
||||
UC_ARM64_REG_X29,
|
||||
UC_ARM64_REG_X30,
|
||||
UC_ARM64_REG_NZCV,
|
||||
UC_ARM64_REG_SP,
|
||||
UC_ARM64_REG_WSP,
|
||||
UC_ARM64_REG_WZR,
|
||||
UC_ARM64_REG_XZR,
|
||||
UC_ARM64_REG_B0,
|
||||
UC_ARM64_REG_B1,
|
||||
UC_ARM64_REG_B2,
|
||||
UC_ARM64_REG_B3,
|
||||
UC_ARM64_REG_B4,
|
||||
UC_ARM64_REG_B5,
|
||||
UC_ARM64_REG_B6,
|
||||
UC_ARM64_REG_B7,
|
||||
UC_ARM64_REG_B8,
|
||||
UC_ARM64_REG_B9,
|
||||
UC_ARM64_REG_B10,
|
||||
UC_ARM64_REG_B11,
|
||||
UC_ARM64_REG_B12,
|
||||
UC_ARM64_REG_B13,
|
||||
UC_ARM64_REG_B14,
|
||||
UC_ARM64_REG_B15,
|
||||
UC_ARM64_REG_B16,
|
||||
UC_ARM64_REG_B17,
|
||||
UC_ARM64_REG_B18,
|
||||
UC_ARM64_REG_B19,
|
||||
UC_ARM64_REG_B20,
|
||||
UC_ARM64_REG_B21,
|
||||
UC_ARM64_REG_B22,
|
||||
UC_ARM64_REG_B23,
|
||||
UC_ARM64_REG_B24,
|
||||
UC_ARM64_REG_B25,
|
||||
UC_ARM64_REG_B26,
|
||||
UC_ARM64_REG_B27,
|
||||
UC_ARM64_REG_B28,
|
||||
UC_ARM64_REG_B29,
|
||||
UC_ARM64_REG_B30,
|
||||
UC_ARM64_REG_B31,
|
||||
UC_ARM64_REG_D0,
|
||||
UC_ARM64_REG_D1,
|
||||
UC_ARM64_REG_D2,
|
||||
UC_ARM64_REG_D3,
|
||||
UC_ARM64_REG_D4,
|
||||
UC_ARM64_REG_D5,
|
||||
UC_ARM64_REG_D6,
|
||||
UC_ARM64_REG_D7,
|
||||
UC_ARM64_REG_D8,
|
||||
UC_ARM64_REG_D9,
|
||||
UC_ARM64_REG_D10,
|
||||
UC_ARM64_REG_D11,
|
||||
UC_ARM64_REG_D12,
|
||||
UC_ARM64_REG_D13,
|
||||
UC_ARM64_REG_D14,
|
||||
UC_ARM64_REG_D15,
|
||||
UC_ARM64_REG_D16,
|
||||
UC_ARM64_REG_D17,
|
||||
UC_ARM64_REG_D18,
|
||||
UC_ARM64_REG_D19,
|
||||
UC_ARM64_REG_D20,
|
||||
UC_ARM64_REG_D21,
|
||||
UC_ARM64_REG_D22,
|
||||
UC_ARM64_REG_D23,
|
||||
UC_ARM64_REG_D24,
|
||||
UC_ARM64_REG_D25,
|
||||
UC_ARM64_REG_D26,
|
||||
UC_ARM64_REG_D27,
|
||||
UC_ARM64_REG_D28,
|
||||
UC_ARM64_REG_D29,
|
||||
UC_ARM64_REG_D30,
|
||||
UC_ARM64_REG_D31,
|
||||
UC_ARM64_REG_H0,
|
||||
UC_ARM64_REG_H1,
|
||||
UC_ARM64_REG_H2,
|
||||
UC_ARM64_REG_H3,
|
||||
UC_ARM64_REG_H4,
|
||||
UC_ARM64_REG_H5,
|
||||
UC_ARM64_REG_H6,
|
||||
UC_ARM64_REG_H7,
|
||||
UC_ARM64_REG_H8,
|
||||
UC_ARM64_REG_H9,
|
||||
UC_ARM64_REG_H10,
|
||||
UC_ARM64_REG_H11,
|
||||
UC_ARM64_REG_H12,
|
||||
UC_ARM64_REG_H13,
|
||||
UC_ARM64_REG_H14,
|
||||
UC_ARM64_REG_H15,
|
||||
UC_ARM64_REG_H16,
|
||||
UC_ARM64_REG_H17,
|
||||
UC_ARM64_REG_H18,
|
||||
UC_ARM64_REG_H19,
|
||||
UC_ARM64_REG_H20,
|
||||
UC_ARM64_REG_H21,
|
||||
UC_ARM64_REG_H22,
|
||||
UC_ARM64_REG_H23,
|
||||
UC_ARM64_REG_H24,
|
||||
UC_ARM64_REG_H25,
|
||||
UC_ARM64_REG_H26,
|
||||
UC_ARM64_REG_H27,
|
||||
UC_ARM64_REG_H28,
|
||||
UC_ARM64_REG_H29,
|
||||
UC_ARM64_REG_H30,
|
||||
UC_ARM64_REG_H31,
|
||||
UC_ARM64_REG_Q0,
|
||||
UC_ARM64_REG_Q1,
|
||||
UC_ARM64_REG_Q2,
|
||||
UC_ARM64_REG_Q3,
|
||||
UC_ARM64_REG_Q4,
|
||||
UC_ARM64_REG_Q5,
|
||||
UC_ARM64_REG_Q6,
|
||||
UC_ARM64_REG_Q7,
|
||||
UC_ARM64_REG_Q8,
|
||||
UC_ARM64_REG_Q9,
|
||||
UC_ARM64_REG_Q10,
|
||||
UC_ARM64_REG_Q11,
|
||||
UC_ARM64_REG_Q12,
|
||||
UC_ARM64_REG_Q13,
|
||||
UC_ARM64_REG_Q14,
|
||||
UC_ARM64_REG_Q15,
|
||||
UC_ARM64_REG_Q16,
|
||||
UC_ARM64_REG_Q17,
|
||||
UC_ARM64_REG_Q18,
|
||||
UC_ARM64_REG_Q19,
|
||||
UC_ARM64_REG_Q20,
|
||||
UC_ARM64_REG_Q21,
|
||||
UC_ARM64_REG_Q22,
|
||||
UC_ARM64_REG_Q23,
|
||||
UC_ARM64_REG_Q24,
|
||||
UC_ARM64_REG_Q25,
|
||||
UC_ARM64_REG_Q26,
|
||||
UC_ARM64_REG_Q27,
|
||||
UC_ARM64_REG_Q28,
|
||||
UC_ARM64_REG_Q29,
|
||||
UC_ARM64_REG_Q30,
|
||||
UC_ARM64_REG_Q31,
|
||||
UC_ARM64_REG_S0,
|
||||
UC_ARM64_REG_S1,
|
||||
UC_ARM64_REG_S2,
|
||||
UC_ARM64_REG_S3,
|
||||
UC_ARM64_REG_S4,
|
||||
UC_ARM64_REG_S5,
|
||||
UC_ARM64_REG_S6,
|
||||
UC_ARM64_REG_S7,
|
||||
UC_ARM64_REG_S8,
|
||||
UC_ARM64_REG_S9,
|
||||
UC_ARM64_REG_S10,
|
||||
UC_ARM64_REG_S11,
|
||||
UC_ARM64_REG_S12,
|
||||
UC_ARM64_REG_S13,
|
||||
UC_ARM64_REG_S14,
|
||||
UC_ARM64_REG_S15,
|
||||
UC_ARM64_REG_S16,
|
||||
UC_ARM64_REG_S17,
|
||||
UC_ARM64_REG_S18,
|
||||
UC_ARM64_REG_S19,
|
||||
UC_ARM64_REG_S20,
|
||||
UC_ARM64_REG_S21,
|
||||
UC_ARM64_REG_S22,
|
||||
UC_ARM64_REG_S23,
|
||||
UC_ARM64_REG_S24,
|
||||
UC_ARM64_REG_S25,
|
||||
UC_ARM64_REG_S26,
|
||||
UC_ARM64_REG_S27,
|
||||
UC_ARM64_REG_S28,
|
||||
UC_ARM64_REG_S29,
|
||||
UC_ARM64_REG_S30,
|
||||
UC_ARM64_REG_S31,
|
||||
UC_ARM64_REG_W0,
|
||||
UC_ARM64_REG_W1,
|
||||
UC_ARM64_REG_W2,
|
||||
UC_ARM64_REG_W3,
|
||||
UC_ARM64_REG_W4,
|
||||
UC_ARM64_REG_W5,
|
||||
UC_ARM64_REG_W6,
|
||||
UC_ARM64_REG_W7,
|
||||
UC_ARM64_REG_W8,
|
||||
UC_ARM64_REG_W9,
|
||||
UC_ARM64_REG_W10,
|
||||
UC_ARM64_REG_W11,
|
||||
UC_ARM64_REG_W12,
|
||||
UC_ARM64_REG_W13,
|
||||
UC_ARM64_REG_W14,
|
||||
UC_ARM64_REG_W15,
|
||||
UC_ARM64_REG_W16,
|
||||
UC_ARM64_REG_W17,
|
||||
UC_ARM64_REG_W18,
|
||||
UC_ARM64_REG_W19,
|
||||
UC_ARM64_REG_W20,
|
||||
UC_ARM64_REG_W21,
|
||||
UC_ARM64_REG_W22,
|
||||
UC_ARM64_REG_W23,
|
||||
UC_ARM64_REG_W24,
|
||||
UC_ARM64_REG_W25,
|
||||
UC_ARM64_REG_W26,
|
||||
UC_ARM64_REG_W27,
|
||||
UC_ARM64_REG_W28,
|
||||
UC_ARM64_REG_W29,
|
||||
UC_ARM64_REG_W30,
|
||||
UC_ARM64_REG_X0,
|
||||
UC_ARM64_REG_X1,
|
||||
UC_ARM64_REG_X2,
|
||||
UC_ARM64_REG_X3,
|
||||
UC_ARM64_REG_X4,
|
||||
UC_ARM64_REG_X5,
|
||||
UC_ARM64_REG_X6,
|
||||
UC_ARM64_REG_X7,
|
||||
UC_ARM64_REG_X8,
|
||||
UC_ARM64_REG_X9,
|
||||
UC_ARM64_REG_X10,
|
||||
UC_ARM64_REG_X11,
|
||||
UC_ARM64_REG_X12,
|
||||
UC_ARM64_REG_X13,
|
||||
UC_ARM64_REG_X14,
|
||||
UC_ARM64_REG_X15,
|
||||
UC_ARM64_REG_X16,
|
||||
UC_ARM64_REG_X17,
|
||||
UC_ARM64_REG_X18,
|
||||
UC_ARM64_REG_X19,
|
||||
UC_ARM64_REG_X20,
|
||||
UC_ARM64_REG_X21,
|
||||
UC_ARM64_REG_X22,
|
||||
UC_ARM64_REG_X23,
|
||||
UC_ARM64_REG_X24,
|
||||
UC_ARM64_REG_X25,
|
||||
UC_ARM64_REG_X26,
|
||||
UC_ARM64_REG_X27,
|
||||
UC_ARM64_REG_X28,
|
||||
|
||||
UC_ARM64_REG_V0,
|
||||
UC_ARM64_REG_V1,
|
||||
UC_ARM64_REG_V2,
|
||||
UC_ARM64_REG_V3,
|
||||
UC_ARM64_REG_V4,
|
||||
UC_ARM64_REG_V5,
|
||||
UC_ARM64_REG_V6,
|
||||
UC_ARM64_REG_V7,
|
||||
UC_ARM64_REG_V8,
|
||||
UC_ARM64_REG_V9,
|
||||
UC_ARM64_REG_V10,
|
||||
UC_ARM64_REG_V11,
|
||||
UC_ARM64_REG_V12,
|
||||
UC_ARM64_REG_V13,
|
||||
UC_ARM64_REG_V14,
|
||||
UC_ARM64_REG_V15,
|
||||
UC_ARM64_REG_V16,
|
||||
UC_ARM64_REG_V17,
|
||||
UC_ARM64_REG_V18,
|
||||
UC_ARM64_REG_V19,
|
||||
UC_ARM64_REG_V20,
|
||||
UC_ARM64_REG_V21,
|
||||
UC_ARM64_REG_V22,
|
||||
UC_ARM64_REG_V23,
|
||||
UC_ARM64_REG_V24,
|
||||
UC_ARM64_REG_V25,
|
||||
UC_ARM64_REG_V26,
|
||||
UC_ARM64_REG_V27,
|
||||
UC_ARM64_REG_V28,
|
||||
UC_ARM64_REG_V29,
|
||||
UC_ARM64_REG_V30,
|
||||
UC_ARM64_REG_V31,
|
||||
|
||||
//> pseudo registers
|
||||
UC_ARM64_REG_PC, // program counter register
|
||||
|
||||
UC_ARM64_REG_CPACR_EL1,
|
||||
|
||||
//> thread registers
|
||||
UC_ARM64_REG_TPIDR_EL0,
|
||||
UC_ARM64_REG_TPIDRRO_EL0,
|
||||
UC_ARM64_REG_TPIDR_EL1,
|
||||
|
||||
UC_ARM64_REG_PSTATE,
|
||||
|
||||
//> exception link registers
|
||||
UC_ARM64_REG_ELR_EL0,
|
||||
UC_ARM64_REG_ELR_EL1,
|
||||
UC_ARM64_REG_ELR_EL2,
|
||||
UC_ARM64_REG_ELR_EL3,
|
||||
|
||||
//> stack pointers registers
|
||||
UC_ARM64_REG_SP_EL0,
|
||||
UC_ARM64_REG_SP_EL1,
|
||||
UC_ARM64_REG_SP_EL2,
|
||||
UC_ARM64_REG_SP_EL3,
|
||||
|
||||
//> other CP15 registers
|
||||
UC_ARM64_REG_TTBR0_EL1,
|
||||
UC_ARM64_REG_TTBR1_EL1,
|
||||
|
||||
UC_ARM64_REG_ESR_EL0,
|
||||
UC_ARM64_REG_ESR_EL1,
|
||||
UC_ARM64_REG_ESR_EL2,
|
||||
UC_ARM64_REG_ESR_EL3,
|
||||
|
||||
UC_ARM64_REG_FAR_EL0,
|
||||
UC_ARM64_REG_FAR_EL1,
|
||||
UC_ARM64_REG_FAR_EL2,
|
||||
UC_ARM64_REG_FAR_EL3,
|
||||
|
||||
UC_ARM64_REG_PAR_EL1,
|
||||
|
||||
UC_ARM64_REG_MAIR_EL1,
|
||||
|
||||
UC_ARM64_REG_VBAR_EL0,
|
||||
UC_ARM64_REG_VBAR_EL1,
|
||||
UC_ARM64_REG_VBAR_EL2,
|
||||
UC_ARM64_REG_VBAR_EL3,
|
||||
|
||||
UC_ARM64_REG_ENDING, // <-- mark the end of the list of registers
|
||||
|
||||
//> alias registers
|
||||
|
||||
UC_ARM64_REG_IP0 = UC_ARM64_REG_X16,
|
||||
UC_ARM64_REG_IP1 = UC_ARM64_REG_X17,
|
||||
UC_ARM64_REG_FP = UC_ARM64_REG_X29,
|
||||
UC_ARM64_REG_LR = UC_ARM64_REG_X30,
|
||||
} uc_arm64_reg;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
50
ai_anti_malware/unicorn/include/unicorn/m68k.h
Normal file
50
ai_anti_malware/unicorn/include/unicorn/m68k.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2014-2017 */
|
||||
/* This file is released under LGPL2.
|
||||
See COPYING.LGPL2 in root directory for more details
|
||||
*/
|
||||
|
||||
#ifndef UNICORN_M68K_H
|
||||
#define UNICORN_M68K_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
//> M68K registers
|
||||
typedef enum uc_m68k_reg {
|
||||
UC_M68K_REG_INVALID = 0,
|
||||
|
||||
UC_M68K_REG_A0,
|
||||
UC_M68K_REG_A1,
|
||||
UC_M68K_REG_A2,
|
||||
UC_M68K_REG_A3,
|
||||
UC_M68K_REG_A4,
|
||||
UC_M68K_REG_A5,
|
||||
UC_M68K_REG_A6,
|
||||
UC_M68K_REG_A7,
|
||||
|
||||
UC_M68K_REG_D0,
|
||||
UC_M68K_REG_D1,
|
||||
UC_M68K_REG_D2,
|
||||
UC_M68K_REG_D3,
|
||||
UC_M68K_REG_D4,
|
||||
UC_M68K_REG_D5,
|
||||
UC_M68K_REG_D6,
|
||||
UC_M68K_REG_D7,
|
||||
|
||||
UC_M68K_REG_SR,
|
||||
UC_M68K_REG_PC,
|
||||
|
||||
UC_M68K_REG_ENDING, // <-- mark the end of the list of registers
|
||||
} uc_m68k_reg;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
232
ai_anti_malware/unicorn/include/unicorn/mips.h
Normal file
232
ai_anti_malware/unicorn/include/unicorn/mips.h
Normal file
@@ -0,0 +1,232 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2015-2017 */
|
||||
/* This file is released under LGPL2.
|
||||
See COPYING.LGPL2 in root directory for more details
|
||||
*/
|
||||
|
||||
#ifndef UNICORN_MIPS_H
|
||||
#define UNICORN_MIPS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// GCC MIPS toolchain has a default macro called "mips" which breaks
|
||||
// compilation
|
||||
#undef mips
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
//> MIPS registers
|
||||
typedef enum UC_MIPS_REG {
|
||||
UC_MIPS_REG_INVALID = 0,
|
||||
//> General purpose registers
|
||||
UC_MIPS_REG_PC,
|
||||
|
||||
UC_MIPS_REG_0,
|
||||
UC_MIPS_REG_1,
|
||||
UC_MIPS_REG_2,
|
||||
UC_MIPS_REG_3,
|
||||
UC_MIPS_REG_4,
|
||||
UC_MIPS_REG_5,
|
||||
UC_MIPS_REG_6,
|
||||
UC_MIPS_REG_7,
|
||||
UC_MIPS_REG_8,
|
||||
UC_MIPS_REG_9,
|
||||
UC_MIPS_REG_10,
|
||||
UC_MIPS_REG_11,
|
||||
UC_MIPS_REG_12,
|
||||
UC_MIPS_REG_13,
|
||||
UC_MIPS_REG_14,
|
||||
UC_MIPS_REG_15,
|
||||
UC_MIPS_REG_16,
|
||||
UC_MIPS_REG_17,
|
||||
UC_MIPS_REG_18,
|
||||
UC_MIPS_REG_19,
|
||||
UC_MIPS_REG_20,
|
||||
UC_MIPS_REG_21,
|
||||
UC_MIPS_REG_22,
|
||||
UC_MIPS_REG_23,
|
||||
UC_MIPS_REG_24,
|
||||
UC_MIPS_REG_25,
|
||||
UC_MIPS_REG_26,
|
||||
UC_MIPS_REG_27,
|
||||
UC_MIPS_REG_28,
|
||||
UC_MIPS_REG_29,
|
||||
UC_MIPS_REG_30,
|
||||
UC_MIPS_REG_31,
|
||||
|
||||
//> DSP registers
|
||||
UC_MIPS_REG_DSPCCOND,
|
||||
UC_MIPS_REG_DSPCARRY,
|
||||
UC_MIPS_REG_DSPEFI,
|
||||
UC_MIPS_REG_DSPOUTFLAG,
|
||||
UC_MIPS_REG_DSPOUTFLAG16_19,
|
||||
UC_MIPS_REG_DSPOUTFLAG20,
|
||||
UC_MIPS_REG_DSPOUTFLAG21,
|
||||
UC_MIPS_REG_DSPOUTFLAG22,
|
||||
UC_MIPS_REG_DSPOUTFLAG23,
|
||||
UC_MIPS_REG_DSPPOS,
|
||||
UC_MIPS_REG_DSPSCOUNT,
|
||||
|
||||
//> ACC registers
|
||||
UC_MIPS_REG_AC0,
|
||||
UC_MIPS_REG_AC1,
|
||||
UC_MIPS_REG_AC2,
|
||||
UC_MIPS_REG_AC3,
|
||||
|
||||
//> COP registers
|
||||
UC_MIPS_REG_CC0,
|
||||
UC_MIPS_REG_CC1,
|
||||
UC_MIPS_REG_CC2,
|
||||
UC_MIPS_REG_CC3,
|
||||
UC_MIPS_REG_CC4,
|
||||
UC_MIPS_REG_CC5,
|
||||
UC_MIPS_REG_CC6,
|
||||
UC_MIPS_REG_CC7,
|
||||
|
||||
//> FPU registers
|
||||
UC_MIPS_REG_F0,
|
||||
UC_MIPS_REG_F1,
|
||||
UC_MIPS_REG_F2,
|
||||
UC_MIPS_REG_F3,
|
||||
UC_MIPS_REG_F4,
|
||||
UC_MIPS_REG_F5,
|
||||
UC_MIPS_REG_F6,
|
||||
UC_MIPS_REG_F7,
|
||||
UC_MIPS_REG_F8,
|
||||
UC_MIPS_REG_F9,
|
||||
UC_MIPS_REG_F10,
|
||||
UC_MIPS_REG_F11,
|
||||
UC_MIPS_REG_F12,
|
||||
UC_MIPS_REG_F13,
|
||||
UC_MIPS_REG_F14,
|
||||
UC_MIPS_REG_F15,
|
||||
UC_MIPS_REG_F16,
|
||||
UC_MIPS_REG_F17,
|
||||
UC_MIPS_REG_F18,
|
||||
UC_MIPS_REG_F19,
|
||||
UC_MIPS_REG_F20,
|
||||
UC_MIPS_REG_F21,
|
||||
UC_MIPS_REG_F22,
|
||||
UC_MIPS_REG_F23,
|
||||
UC_MIPS_REG_F24,
|
||||
UC_MIPS_REG_F25,
|
||||
UC_MIPS_REG_F26,
|
||||
UC_MIPS_REG_F27,
|
||||
UC_MIPS_REG_F28,
|
||||
UC_MIPS_REG_F29,
|
||||
UC_MIPS_REG_F30,
|
||||
UC_MIPS_REG_F31,
|
||||
|
||||
UC_MIPS_REG_FCC0,
|
||||
UC_MIPS_REG_FCC1,
|
||||
UC_MIPS_REG_FCC2,
|
||||
UC_MIPS_REG_FCC3,
|
||||
UC_MIPS_REG_FCC4,
|
||||
UC_MIPS_REG_FCC5,
|
||||
UC_MIPS_REG_FCC6,
|
||||
UC_MIPS_REG_FCC7,
|
||||
|
||||
//> AFPR128
|
||||
UC_MIPS_REG_W0,
|
||||
UC_MIPS_REG_W1,
|
||||
UC_MIPS_REG_W2,
|
||||
UC_MIPS_REG_W3,
|
||||
UC_MIPS_REG_W4,
|
||||
UC_MIPS_REG_W5,
|
||||
UC_MIPS_REG_W6,
|
||||
UC_MIPS_REG_W7,
|
||||
UC_MIPS_REG_W8,
|
||||
UC_MIPS_REG_W9,
|
||||
UC_MIPS_REG_W10,
|
||||
UC_MIPS_REG_W11,
|
||||
UC_MIPS_REG_W12,
|
||||
UC_MIPS_REG_W13,
|
||||
UC_MIPS_REG_W14,
|
||||
UC_MIPS_REG_W15,
|
||||
UC_MIPS_REG_W16,
|
||||
UC_MIPS_REG_W17,
|
||||
UC_MIPS_REG_W18,
|
||||
UC_MIPS_REG_W19,
|
||||
UC_MIPS_REG_W20,
|
||||
UC_MIPS_REG_W21,
|
||||
UC_MIPS_REG_W22,
|
||||
UC_MIPS_REG_W23,
|
||||
UC_MIPS_REG_W24,
|
||||
UC_MIPS_REG_W25,
|
||||
UC_MIPS_REG_W26,
|
||||
UC_MIPS_REG_W27,
|
||||
UC_MIPS_REG_W28,
|
||||
UC_MIPS_REG_W29,
|
||||
UC_MIPS_REG_W30,
|
||||
UC_MIPS_REG_W31,
|
||||
|
||||
UC_MIPS_REG_HI,
|
||||
UC_MIPS_REG_LO,
|
||||
|
||||
UC_MIPS_REG_P0,
|
||||
UC_MIPS_REG_P1,
|
||||
UC_MIPS_REG_P2,
|
||||
|
||||
UC_MIPS_REG_MPL0,
|
||||
UC_MIPS_REG_MPL1,
|
||||
UC_MIPS_REG_MPL2,
|
||||
|
||||
UC_MIPS_REG_CP0_CONFIG3,
|
||||
UC_MIPS_REG_CP0_USERLOCAL,
|
||||
|
||||
UC_MIPS_REG_ENDING, // <-- mark the end of the list or registers
|
||||
|
||||
// alias registers
|
||||
UC_MIPS_REG_ZERO = UC_MIPS_REG_0,
|
||||
UC_MIPS_REG_AT = UC_MIPS_REG_1,
|
||||
UC_MIPS_REG_V0 = UC_MIPS_REG_2,
|
||||
UC_MIPS_REG_V1 = UC_MIPS_REG_3,
|
||||
UC_MIPS_REG_A0 = UC_MIPS_REG_4,
|
||||
UC_MIPS_REG_A1 = UC_MIPS_REG_5,
|
||||
UC_MIPS_REG_A2 = UC_MIPS_REG_6,
|
||||
UC_MIPS_REG_A3 = UC_MIPS_REG_7,
|
||||
UC_MIPS_REG_T0 = UC_MIPS_REG_8,
|
||||
UC_MIPS_REG_T1 = UC_MIPS_REG_9,
|
||||
UC_MIPS_REG_T2 = UC_MIPS_REG_10,
|
||||
UC_MIPS_REG_T3 = UC_MIPS_REG_11,
|
||||
UC_MIPS_REG_T4 = UC_MIPS_REG_12,
|
||||
UC_MIPS_REG_T5 = UC_MIPS_REG_13,
|
||||
UC_MIPS_REG_T6 = UC_MIPS_REG_14,
|
||||
UC_MIPS_REG_T7 = UC_MIPS_REG_15,
|
||||
UC_MIPS_REG_S0 = UC_MIPS_REG_16,
|
||||
UC_MIPS_REG_S1 = UC_MIPS_REG_17,
|
||||
UC_MIPS_REG_S2 = UC_MIPS_REG_18,
|
||||
UC_MIPS_REG_S3 = UC_MIPS_REG_19,
|
||||
UC_MIPS_REG_S4 = UC_MIPS_REG_20,
|
||||
UC_MIPS_REG_S5 = UC_MIPS_REG_21,
|
||||
UC_MIPS_REG_S6 = UC_MIPS_REG_22,
|
||||
UC_MIPS_REG_S7 = UC_MIPS_REG_23,
|
||||
UC_MIPS_REG_T8 = UC_MIPS_REG_24,
|
||||
UC_MIPS_REG_T9 = UC_MIPS_REG_25,
|
||||
UC_MIPS_REG_K0 = UC_MIPS_REG_26,
|
||||
UC_MIPS_REG_K1 = UC_MIPS_REG_27,
|
||||
UC_MIPS_REG_GP = UC_MIPS_REG_28,
|
||||
UC_MIPS_REG_SP = UC_MIPS_REG_29,
|
||||
UC_MIPS_REG_FP = UC_MIPS_REG_30, UC_MIPS_REG_S8 = UC_MIPS_REG_30,
|
||||
UC_MIPS_REG_RA = UC_MIPS_REG_31,
|
||||
|
||||
UC_MIPS_REG_HI0 = UC_MIPS_REG_AC0,
|
||||
UC_MIPS_REG_HI1 = UC_MIPS_REG_AC1,
|
||||
UC_MIPS_REG_HI2 = UC_MIPS_REG_AC2,
|
||||
UC_MIPS_REG_HI3 = UC_MIPS_REG_AC3,
|
||||
|
||||
UC_MIPS_REG_LO0 = UC_MIPS_REG_HI0,
|
||||
UC_MIPS_REG_LO1 = UC_MIPS_REG_HI1,
|
||||
UC_MIPS_REG_LO2 = UC_MIPS_REG_HI2,
|
||||
UC_MIPS_REG_LO3 = UC_MIPS_REG_HI3,
|
||||
} UC_MIPS_REG;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
221
ai_anti_malware/unicorn/include/unicorn/platform.h
Normal file
221
ai_anti_malware/unicorn/include/unicorn/platform.h
Normal file
@@ -0,0 +1,221 @@
|
||||
/* This file is released under LGPL2.
|
||||
See COPYING.LGPL2 in root directory for more details
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is to support header files that are missing in MSVC and
|
||||
other non-standard compilers.
|
||||
*/
|
||||
#ifndef UNICORN_PLATFORM_H
|
||||
#define UNICORN_PLATFORM_H
|
||||
|
||||
/*
|
||||
These are the various MSVC versions as given by _MSC_VER:
|
||||
MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
|
||||
MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
|
||||
MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
|
||||
MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
|
||||
MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
|
||||
MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
|
||||
MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio 2003)
|
||||
MSVC++ 7.0 _MSC_VER == 1300
|
||||
MSVC++ 6.0 _MSC_VER == 1200
|
||||
MSVC++ 5.0 _MSC_VER == 1100
|
||||
*/
|
||||
#define MSC_VER_VS2003 1310
|
||||
#define MSC_VER_VS2005 1400
|
||||
#define MSC_VER_VS2008 1500
|
||||
#define MSC_VER_VS2010 1600
|
||||
#define MSC_VER_VS2012 1700
|
||||
#define MSC_VER_VS2013 1800
|
||||
#define MSC_VER_VS2015 1900
|
||||
|
||||
// handle stdbool.h compatibility
|
||||
#if !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64))
|
||||
// MSVC
|
||||
|
||||
// stdbool.h
|
||||
#if (_MSC_VER < MSC_VER_VS2013) || defined(_KERNEL_MODE)
|
||||
// this system does not have stdbool.h
|
||||
#ifndef __cplusplus
|
||||
typedef unsigned char bool;
|
||||
#define false 0
|
||||
#define true 1
|
||||
#endif // __cplusplus
|
||||
|
||||
#else
|
||||
// VisualStudio 2013+ -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif // (_MSC_VER < MSC_VER_VS2013) || defined(_KERNEL_MODE)
|
||||
|
||||
#else
|
||||
// not MSVC -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif // !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64))
|
||||
|
||||
#if (defined(_MSC_VER) && (_MSC_VER < MSC_VER_VS2010)) || defined(_KERNEL_MODE)
|
||||
// this system does not have stdint.h
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef signed long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
#ifndef _INTPTR_T_DEFINED
|
||||
#define _INTPTR_T_DEFINED
|
||||
#ifdef _WIN64
|
||||
typedef long long intptr_t;
|
||||
#else /* _WIN64 */
|
||||
typedef _W64 int intptr_t;
|
||||
#endif /* _WIN64 */
|
||||
#endif /* _INTPTR_T_DEFINED */
|
||||
|
||||
#ifndef _UINTPTR_T_DEFINED
|
||||
#define _UINTPTR_T_DEFINED
|
||||
#ifdef _WIN64
|
||||
typedef unsigned long long uintptr_t;
|
||||
#else /* _WIN64 */
|
||||
typedef _W64 unsigned int uintptr_t;
|
||||
#endif /* _WIN64 */
|
||||
#endif /* _UINTPTR_T_DEFINED */
|
||||
|
||||
#define INT8_MIN (-127i8 - 1)
|
||||
#define INT16_MIN (-32767i16 - 1)
|
||||
#define INT32_MIN (-2147483647i32 - 1)
|
||||
#define INT64_MIN (-9223372036854775807i64 - 1)
|
||||
#define INT8_MAX 127i8
|
||||
#define INT16_MAX 32767i16
|
||||
#define INT32_MAX 2147483647i32
|
||||
#define INT64_MAX 9223372036854775807i64
|
||||
#define UINT8_MAX 0xffui8
|
||||
#define UINT16_MAX 0xffffui16
|
||||
#define UINT32_MAX 0xffffffffui32
|
||||
#define UINT64_MAX 0xffffffffffffffffui64
|
||||
#else // this system has stdint.h
|
||||
#include <stdint.h>
|
||||
#endif // (defined(_MSC_VER) && (_MSC_VER < MSC_VER_VS2010)) || defined(_KERNEL_MODE)
|
||||
|
||||
// handle inttypes.h compatibility
|
||||
#if (defined(_MSC_VER) && (_MSC_VER < MSC_VER_VS2013)) || defined(_KERNEL_MODE)
|
||||
// this system does not have inttypes.h
|
||||
|
||||
#define __PRI_8_LENGTH_MODIFIER__ "hh"
|
||||
#define __PRI_64_LENGTH_MODIFIER__ "ll"
|
||||
|
||||
#define PRId8 __PRI_8_LENGTH_MODIFIER__ "d"
|
||||
#define PRIi8 __PRI_8_LENGTH_MODIFIER__ "i"
|
||||
#define PRIo8 __PRI_8_LENGTH_MODIFIER__ "o"
|
||||
#define PRIu8 __PRI_8_LENGTH_MODIFIER__ "u"
|
||||
#define PRIx8 __PRI_8_LENGTH_MODIFIER__ "x"
|
||||
#define PRIX8 __PRI_8_LENGTH_MODIFIER__ "X"
|
||||
|
||||
#define PRId16 "hd"
|
||||
#define PRIi16 "hi"
|
||||
#define PRIo16 "ho"
|
||||
#define PRIu16 "hu"
|
||||
#define PRIx16 "hx"
|
||||
#define PRIX16 "hX"
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= MSC_VER_VS2012)
|
||||
#define PRId32 "ld"
|
||||
#define PRIi32 "li"
|
||||
#define PRIo32 "lo"
|
||||
#define PRIu32 "lu"
|
||||
#define PRIx32 "lx"
|
||||
#define PRIX32 "lX"
|
||||
#else // OSX
|
||||
#define PRId32 "d"
|
||||
#define PRIi32 "i"
|
||||
#define PRIo32 "o"
|
||||
#define PRIu32 "u"
|
||||
#define PRIx32 "x"
|
||||
#define PRIX32 "X"
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER <= MSC_VER_VS2012)
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= MSC_VER_VS2012)
|
||||
// redefine functions from inttypes.h used in cstool
|
||||
#define strtoull _strtoui64
|
||||
#endif
|
||||
|
||||
#define PRId64 __PRI_64_LENGTH_MODIFIER__ "d"
|
||||
#define PRIi64 __PRI_64_LENGTH_MODIFIER__ "i"
|
||||
#define PRIo64 __PRI_64_LENGTH_MODIFIER__ "o"
|
||||
#define PRIu64 __PRI_64_LENGTH_MODIFIER__ "u"
|
||||
#define PRIx64 __PRI_64_LENGTH_MODIFIER__ "x"
|
||||
#define PRIX64 __PRI_64_LENGTH_MODIFIER__ "X"
|
||||
|
||||
#else
|
||||
// this system has inttypes.h by default
|
||||
#include <inttypes.h>
|
||||
#endif // #if defined(_MSC_VER) && (_MSC_VER < MSC_VER_VS2013) || defined(_KERNEL_MODE)
|
||||
|
||||
// sys/time.h compatibility
|
||||
#if defined(_MSC_VER)
|
||||
#include <sys/timeb.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
||||
static int gettimeofday(struct timeval* t, void* timezone)
|
||||
{
|
||||
struct _timeb timebuffer;
|
||||
_ftime( &timebuffer );
|
||||
t->tv_sec = (long)timebuffer.time;
|
||||
t->tv_usec = 1000*timebuffer.millitm;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
// unistd.h compatibility
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
static int usleep(uint32_t usec)
|
||||
{
|
||||
HANDLE timer;
|
||||
LARGE_INTEGER due;
|
||||
|
||||
timer = CreateWaitableTimer(NULL, TRUE, NULL);
|
||||
if (!timer)
|
||||
return -1;
|
||||
|
||||
due.QuadPart = (-((int64_t) usec)) * 10LL;
|
||||
if (!SetWaitableTimer(timer, &due, 0, NULL, NULL, 0)) {
|
||||
CloseHandle(timer);
|
||||
return -1;
|
||||
}
|
||||
WaitForSingleObject(timer, INFINITE);
|
||||
CloseHandle(timer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
// misc support
|
||||
#if defined(_MSC_VER)
|
||||
#ifdef _WIN64
|
||||
typedef signed __int64 ssize_t;
|
||||
#else
|
||||
typedef _W64 signed int ssize_t;
|
||||
#endif
|
||||
|
||||
#ifndef va_copy
|
||||
#define va_copy(d,s) ((d) = (s))
|
||||
#endif
|
||||
#define strcasecmp _stricmp
|
||||
#if (_MSC_VER < MSC_VER_VS2015)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
#if (_MSC_VER <= MSC_VER_VS2013)
|
||||
#define strtoll _strtoi64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif // UNICORN_PLATFORM_H
|
||||
130
ai_anti_malware/unicorn/include/unicorn/sparc.h
Normal file
130
ai_anti_malware/unicorn/include/unicorn/sparc.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2014-2017 */
|
||||
/* This file is released under LGPL2.
|
||||
See COPYING.LGPL2 in root directory for more details
|
||||
*/
|
||||
|
||||
#ifndef UNICORN_SPARC_H
|
||||
#define UNICORN_SPARC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// GCC SPARC toolchain has a default macro called "sparc" which breaks
|
||||
// compilation
|
||||
#undef sparc
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
//> SPARC registers
|
||||
typedef enum uc_sparc_reg {
|
||||
UC_SPARC_REG_INVALID = 0,
|
||||
|
||||
UC_SPARC_REG_F0,
|
||||
UC_SPARC_REG_F1,
|
||||
UC_SPARC_REG_F2,
|
||||
UC_SPARC_REG_F3,
|
||||
UC_SPARC_REG_F4,
|
||||
UC_SPARC_REG_F5,
|
||||
UC_SPARC_REG_F6,
|
||||
UC_SPARC_REG_F7,
|
||||
UC_SPARC_REG_F8,
|
||||
UC_SPARC_REG_F9,
|
||||
UC_SPARC_REG_F10,
|
||||
UC_SPARC_REG_F11,
|
||||
UC_SPARC_REG_F12,
|
||||
UC_SPARC_REG_F13,
|
||||
UC_SPARC_REG_F14,
|
||||
UC_SPARC_REG_F15,
|
||||
UC_SPARC_REG_F16,
|
||||
UC_SPARC_REG_F17,
|
||||
UC_SPARC_REG_F18,
|
||||
UC_SPARC_REG_F19,
|
||||
UC_SPARC_REG_F20,
|
||||
UC_SPARC_REG_F21,
|
||||
UC_SPARC_REG_F22,
|
||||
UC_SPARC_REG_F23,
|
||||
UC_SPARC_REG_F24,
|
||||
UC_SPARC_REG_F25,
|
||||
UC_SPARC_REG_F26,
|
||||
UC_SPARC_REG_F27,
|
||||
UC_SPARC_REG_F28,
|
||||
UC_SPARC_REG_F29,
|
||||
UC_SPARC_REG_F30,
|
||||
UC_SPARC_REG_F31,
|
||||
UC_SPARC_REG_F32,
|
||||
UC_SPARC_REG_F34,
|
||||
UC_SPARC_REG_F36,
|
||||
UC_SPARC_REG_F38,
|
||||
UC_SPARC_REG_F40,
|
||||
UC_SPARC_REG_F42,
|
||||
UC_SPARC_REG_F44,
|
||||
UC_SPARC_REG_F46,
|
||||
UC_SPARC_REG_F48,
|
||||
UC_SPARC_REG_F50,
|
||||
UC_SPARC_REG_F52,
|
||||
UC_SPARC_REG_F54,
|
||||
UC_SPARC_REG_F56,
|
||||
UC_SPARC_REG_F58,
|
||||
UC_SPARC_REG_F60,
|
||||
UC_SPARC_REG_F62,
|
||||
UC_SPARC_REG_FCC0, // Floating condition codes
|
||||
UC_SPARC_REG_FCC1,
|
||||
UC_SPARC_REG_FCC2,
|
||||
UC_SPARC_REG_FCC3,
|
||||
UC_SPARC_REG_G0,
|
||||
UC_SPARC_REG_G1,
|
||||
UC_SPARC_REG_G2,
|
||||
UC_SPARC_REG_G3,
|
||||
UC_SPARC_REG_G4,
|
||||
UC_SPARC_REG_G5,
|
||||
UC_SPARC_REG_G6,
|
||||
UC_SPARC_REG_G7,
|
||||
UC_SPARC_REG_I0,
|
||||
UC_SPARC_REG_I1,
|
||||
UC_SPARC_REG_I2,
|
||||
UC_SPARC_REG_I3,
|
||||
UC_SPARC_REG_I4,
|
||||
UC_SPARC_REG_I5,
|
||||
UC_SPARC_REG_FP,
|
||||
UC_SPARC_REG_I7,
|
||||
UC_SPARC_REG_ICC, // Integer condition codes
|
||||
UC_SPARC_REG_L0,
|
||||
UC_SPARC_REG_L1,
|
||||
UC_SPARC_REG_L2,
|
||||
UC_SPARC_REG_L3,
|
||||
UC_SPARC_REG_L4,
|
||||
UC_SPARC_REG_L5,
|
||||
UC_SPARC_REG_L6,
|
||||
UC_SPARC_REG_L7,
|
||||
UC_SPARC_REG_O0,
|
||||
UC_SPARC_REG_O1,
|
||||
UC_SPARC_REG_O2,
|
||||
UC_SPARC_REG_O3,
|
||||
UC_SPARC_REG_O4,
|
||||
UC_SPARC_REG_O5,
|
||||
UC_SPARC_REG_SP,
|
||||
UC_SPARC_REG_O7,
|
||||
UC_SPARC_REG_Y,
|
||||
|
||||
// special register
|
||||
UC_SPARC_REG_XCC,
|
||||
|
||||
// pseudo register
|
||||
UC_SPARC_REG_PC, // program counter register
|
||||
|
||||
UC_SPARC_REG_ENDING, // <-- mark the end of the list of registers
|
||||
|
||||
// extras
|
||||
UC_SPARC_REG_O6 = UC_SPARC_REG_SP,
|
||||
UC_SPARC_REG_I6 = UC_SPARC_REG_FP,
|
||||
} uc_sparc_reg;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
779
ai_anti_malware/unicorn/include/unicorn/unicorn.h
Normal file
779
ai_anti_malware/unicorn/include/unicorn/unicorn.h
Normal file
@@ -0,0 +1,779 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2015-2017 */
|
||||
/* This file is released under LGPL2.
|
||||
See COPYING.LGPL2 in root directory for more details
|
||||
*/
|
||||
|
||||
#ifndef UNICORN_ENGINE_H
|
||||
#define UNICORN_ENGINE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#if defined(UNICORN_HAS_OSXKERNEL)
|
||||
#include <libkern/libkern.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
struct uc_struct;
|
||||
typedef struct uc_struct uc_engine;
|
||||
|
||||
typedef size_t uc_hook;
|
||||
|
||||
#include "m68k.h"
|
||||
#include "x86.h"
|
||||
#include "arm.h"
|
||||
#include "arm64.h"
|
||||
#include "mips.h"
|
||||
#include "sparc.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define DEFAULT_VISIBILITY __attribute__((visibility("default")))
|
||||
#else
|
||||
#define DEFAULT_VISIBILITY
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#pragma warning(disable:4100)
|
||||
#ifdef UNICORN_SHARED
|
||||
#define UNICORN_EXPORT __declspec(dllexport)
|
||||
#else // defined(UNICORN_STATIC)
|
||||
#define UNICORN_EXPORT
|
||||
#endif
|
||||
#else
|
||||
#ifdef __GNUC__
|
||||
#define UNICORN_EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define UNICORN_EXPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define UNICORN_DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
#define UNICORN_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
#pragma message("WARNING: You need to implement UNICORN_DEPRECATED for this compiler")
|
||||
#define UNICORN_DEPRECATED
|
||||
#endif
|
||||
|
||||
// Unicorn API version
|
||||
#define UC_API_MAJOR 1
|
||||
#define UC_API_MINOR 0
|
||||
|
||||
// Unicorn package version
|
||||
#define UC_VERSION_MAJOR UC_API_MAJOR
|
||||
#define UC_VERSION_MINOR UC_API_MINOR
|
||||
#define UC_VERSION_EXTRA 2
|
||||
|
||||
|
||||
/*
|
||||
Macro to create combined version which can be compared to
|
||||
result of uc_version() API.
|
||||
*/
|
||||
#define UC_MAKE_VERSION(major, minor) ((major << 8) + minor)
|
||||
|
||||
// Scales to calculate timeout on microsecond unit
|
||||
// 1 second = 1000,000 microseconds
|
||||
#define UC_SECOND_SCALE 1000000
|
||||
// 1 milisecond = 1000 nanoseconds
|
||||
#define UC_MILISECOND_SCALE 1000
|
||||
|
||||
// Architecture type
|
||||
typedef enum uc_arch {
|
||||
UC_ARCH_ARM = 1, // ARM architecture (including Thumb, Thumb-2)
|
||||
UC_ARCH_ARM64, // ARM-64, also called AArch64
|
||||
UC_ARCH_MIPS, // Mips architecture
|
||||
UC_ARCH_X86, // X86 architecture (including x86 & x86-64)
|
||||
UC_ARCH_PPC, // PowerPC architecture (currently unsupported)
|
||||
UC_ARCH_SPARC, // Sparc architecture
|
||||
UC_ARCH_M68K, // M68K architecture
|
||||
UC_ARCH_MAX,
|
||||
} uc_arch;
|
||||
|
||||
// Mode type
|
||||
typedef enum uc_mode {
|
||||
UC_MODE_LITTLE_ENDIAN = 0, // little-endian mode (default mode)
|
||||
UC_MODE_BIG_ENDIAN = 1 << 30, // big-endian mode
|
||||
|
||||
// arm / arm64
|
||||
UC_MODE_ARM = 0, // ARM mode
|
||||
UC_MODE_THUMB = 1 << 4, // THUMB mode (including Thumb-2)
|
||||
UC_MODE_MCLASS = 1 << 5, // ARM's Cortex-M series (currently unsupported)
|
||||
UC_MODE_V8 = 1 << 6, // ARMv8 A32 encodings for ARM (currently unsupported)
|
||||
|
||||
// arm (32bit) cpu types
|
||||
UC_MODE_ARM926 = 1 << 7, // ARM926 CPU type
|
||||
UC_MODE_ARM946 = 1 << 8, // ARM946 CPU type
|
||||
UC_MODE_ARM1176 = 1 << 9, // ARM1176 CPU type
|
||||
|
||||
// mips
|
||||
UC_MODE_MICRO = 1 << 4, // MicroMips mode (currently unsupported)
|
||||
UC_MODE_MIPS3 = 1 << 5, // Mips III ISA (currently unsupported)
|
||||
UC_MODE_MIPS32R6 = 1 << 6, // Mips32r6 ISA (currently unsupported)
|
||||
UC_MODE_MIPS32 = 1 << 2, // Mips32 ISA
|
||||
UC_MODE_MIPS64 = 1 << 3, // Mips64 ISA
|
||||
|
||||
// x86 / x64
|
||||
UC_MODE_16 = 1 << 1, // 16-bit mode
|
||||
UC_MODE_32 = 1 << 2, // 32-bit mode
|
||||
UC_MODE_64 = 1 << 3, // 64-bit mode
|
||||
|
||||
// ppc
|
||||
UC_MODE_PPC32 = 1 << 2, // 32-bit mode (currently unsupported)
|
||||
UC_MODE_PPC64 = 1 << 3, // 64-bit mode (currently unsupported)
|
||||
UC_MODE_QPX = 1 << 4, // Quad Processing eXtensions mode (currently unsupported)
|
||||
|
||||
// sparc
|
||||
UC_MODE_SPARC32 = 1 << 2, // 32-bit mode
|
||||
UC_MODE_SPARC64 = 1 << 3, // 64-bit mode
|
||||
UC_MODE_V9 = 1 << 4, // SparcV9 mode (currently unsupported)
|
||||
|
||||
// m68k
|
||||
} uc_mode;
|
||||
|
||||
// All type of errors encountered by Unicorn API.
|
||||
// These are values returned by uc_errno()
|
||||
typedef enum uc_err {
|
||||
UC_ERR_OK = 0, // No error: everything was fine
|
||||
UC_ERR_NOMEM, // Out-Of-Memory error: uc_open(), uc_emulate()
|
||||
UC_ERR_ARCH, // Unsupported architecture: uc_open()
|
||||
UC_ERR_HANDLE, // Invalid handle
|
||||
UC_ERR_MODE, // Invalid/unsupported mode: uc_open()
|
||||
UC_ERR_VERSION, // Unsupported version (bindings)
|
||||
UC_ERR_READ_UNMAPPED, // Quit emulation due to READ on unmapped memory: uc_emu_start()
|
||||
UC_ERR_WRITE_UNMAPPED, // Quit emulation due to WRITE on unmapped memory: uc_emu_start()
|
||||
UC_ERR_FETCH_UNMAPPED, // Quit emulation due to FETCH on unmapped memory: uc_emu_start()
|
||||
UC_ERR_HOOK, // Invalid hook type: uc_hook_add()
|
||||
UC_ERR_INSN_INVALID, // Quit emulation due to invalid instruction: uc_emu_start()
|
||||
UC_ERR_MAP, // Invalid memory mapping: uc_mem_map()
|
||||
UC_ERR_WRITE_PROT, // Quit emulation due to UC_MEM_WRITE_PROT violation: uc_emu_start()
|
||||
UC_ERR_READ_PROT, // Quit emulation due to UC_MEM_READ_PROT violation: uc_emu_start()
|
||||
UC_ERR_FETCH_PROT, // Quit emulation due to UC_MEM_FETCH_PROT violation: uc_emu_start()
|
||||
UC_ERR_ARG, // Inavalid argument provided to uc_xxx function (See specific function API)
|
||||
UC_ERR_READ_UNALIGNED, // Unaligned read
|
||||
UC_ERR_WRITE_UNALIGNED, // Unaligned write
|
||||
UC_ERR_FETCH_UNALIGNED, // Unaligned fetch
|
||||
UC_ERR_HOOK_EXIST, // hook for this event already existed
|
||||
UC_ERR_RESOURCE, // Insufficient resource: uc_emu_start()
|
||||
UC_ERR_EXCEPTION, // Unhandled CPU exception
|
||||
} uc_err;
|
||||
|
||||
|
||||
/*
|
||||
Callback function for tracing code (UC_HOOK_CODE & UC_HOOK_BLOCK)
|
||||
|
||||
@address: address where the code is being executed
|
||||
@size: size of machine instruction(s) being executed, or 0 when size is unknown
|
||||
@user_data: user data passed to tracing APIs.
|
||||
*/
|
||||
typedef void (*uc_cb_hookcode_t)(uc_engine *uc, uint64_t address, uint32_t size, void *user_data);
|
||||
|
||||
/*
|
||||
Callback function for tracing interrupts (for uc_hook_intr())
|
||||
|
||||
@intno: interrupt number
|
||||
@user_data: user data passed to tracing APIs.
|
||||
*/
|
||||
typedef void (*uc_cb_hookintr_t)(uc_engine *uc, uint32_t intno, void *user_data);
|
||||
|
||||
/*
|
||||
Callback function for tracing invalid instructions
|
||||
|
||||
@user_data: user data passed to tracing APIs.
|
||||
|
||||
@return: return true to continue, or false to stop program (due to invalid instruction).
|
||||
*/
|
||||
typedef bool (*uc_cb_hookinsn_invalid_t)(uc_engine *uc, void *user_data);
|
||||
|
||||
/*
|
||||
Callback function for tracing IN instruction of X86
|
||||
|
||||
@port: port number
|
||||
@size: data size (1/2/4) to be read from this port
|
||||
@user_data: user data passed to tracing APIs.
|
||||
*/
|
||||
typedef uint32_t (*uc_cb_insn_in_t)(uc_engine *uc, uint32_t port, int size, void *user_data);
|
||||
|
||||
/*
|
||||
Callback function for OUT instruction of X86
|
||||
|
||||
@port: port number
|
||||
@size: data size (1/2/4) to be written to this port
|
||||
@value: data value to be written to this port
|
||||
*/
|
||||
typedef void (*uc_cb_insn_out_t)(uc_engine *uc, uint32_t port, int size, uint32_t value, void *user_data);
|
||||
|
||||
// All type of memory accesses for UC_HOOK_MEM_*
|
||||
typedef enum uc_mem_type {
|
||||
UC_MEM_READ = 16, // Memory is read from
|
||||
UC_MEM_WRITE, // Memory is written to
|
||||
UC_MEM_FETCH, // Memory is fetched
|
||||
UC_MEM_READ_UNMAPPED, // Unmapped memory is read from
|
||||
UC_MEM_WRITE_UNMAPPED, // Unmapped memory is written to
|
||||
UC_MEM_FETCH_UNMAPPED, // Unmapped memory is fetched
|
||||
UC_MEM_WRITE_PROT, // Write to write protected, but mapped, memory
|
||||
UC_MEM_READ_PROT, // Read from read protected, but mapped, memory
|
||||
UC_MEM_FETCH_PROT, // Fetch from non-executable, but mapped, memory
|
||||
UC_MEM_READ_AFTER, // Memory is read from (successful access)
|
||||
} uc_mem_type;
|
||||
|
||||
// All type of hooks for uc_hook_add() API.
|
||||
typedef enum uc_hook_type {
|
||||
// Hook all interrupt/syscall events
|
||||
UC_HOOK_INTR = 1 << 0,
|
||||
// Hook a particular instruction - only a very small subset of instructions supported here
|
||||
UC_HOOK_INSN = 1 << 1,
|
||||
// Hook a range of code
|
||||
UC_HOOK_CODE = 1 << 2,
|
||||
// Hook basic blocks
|
||||
UC_HOOK_BLOCK = 1 << 3,
|
||||
// Hook for memory read on unmapped memory
|
||||
UC_HOOK_MEM_READ_UNMAPPED = 1 << 4,
|
||||
// Hook for invalid memory write events
|
||||
UC_HOOK_MEM_WRITE_UNMAPPED = 1 << 5,
|
||||
// Hook for invalid memory fetch for execution events
|
||||
UC_HOOK_MEM_FETCH_UNMAPPED = 1 << 6,
|
||||
// Hook for memory read on read-protected memory
|
||||
UC_HOOK_MEM_READ_PROT = 1 << 7,
|
||||
// Hook for memory write on write-protected memory
|
||||
UC_HOOK_MEM_WRITE_PROT = 1 << 8,
|
||||
// Hook for memory fetch on non-executable memory
|
||||
UC_HOOK_MEM_FETCH_PROT = 1 << 9,
|
||||
// Hook memory read events.
|
||||
UC_HOOK_MEM_READ = 1 << 10,
|
||||
// Hook memory write events.
|
||||
UC_HOOK_MEM_WRITE = 1 << 11,
|
||||
// Hook memory fetch for execution events
|
||||
UC_HOOK_MEM_FETCH = 1 << 12,
|
||||
// Hook memory read events, but only successful access.
|
||||
// The callback will be triggered after successful read.
|
||||
UC_HOOK_MEM_READ_AFTER = 1 << 13,
|
||||
// Hook invalid instructions exceptions.
|
||||
UC_HOOK_INSN_INVALID = 1 << 14,
|
||||
} uc_hook_type;
|
||||
|
||||
// Hook type for all events of unmapped memory access
|
||||
#define UC_HOOK_MEM_UNMAPPED (UC_HOOK_MEM_READ_UNMAPPED + UC_HOOK_MEM_WRITE_UNMAPPED + UC_HOOK_MEM_FETCH_UNMAPPED)
|
||||
// Hook type for all events of illegal protected memory access
|
||||
#define UC_HOOK_MEM_PROT (UC_HOOK_MEM_READ_PROT + UC_HOOK_MEM_WRITE_PROT + UC_HOOK_MEM_FETCH_PROT)
|
||||
// Hook type for all events of illegal read memory access
|
||||
#define UC_HOOK_MEM_READ_INVALID (UC_HOOK_MEM_READ_PROT + UC_HOOK_MEM_READ_UNMAPPED)
|
||||
// Hook type for all events of illegal write memory access
|
||||
#define UC_HOOK_MEM_WRITE_INVALID (UC_HOOK_MEM_WRITE_PROT + UC_HOOK_MEM_WRITE_UNMAPPED)
|
||||
// Hook type for all events of illegal fetch memory access
|
||||
#define UC_HOOK_MEM_FETCH_INVALID (UC_HOOK_MEM_FETCH_PROT + UC_HOOK_MEM_FETCH_UNMAPPED)
|
||||
// Hook type for all events of illegal memory access
|
||||
#define UC_HOOK_MEM_INVALID (UC_HOOK_MEM_UNMAPPED + UC_HOOK_MEM_PROT)
|
||||
// Hook type for all events of valid memory access
|
||||
// NOTE: UC_HOOK_MEM_READ is triggered before UC_HOOK_MEM_READ_PROT and UC_HOOK_MEM_READ_UNMAPPED, so
|
||||
// this hook may technically trigger on some invalid reads.
|
||||
#define UC_HOOK_MEM_VALID (UC_HOOK_MEM_READ + UC_HOOK_MEM_WRITE + UC_HOOK_MEM_FETCH)
|
||||
|
||||
/*
|
||||
Callback function for hooking memory (READ, WRITE & FETCH)
|
||||
|
||||
@type: this memory is being READ, or WRITE
|
||||
@address: address where the code is being executed
|
||||
@size: size of data being read or written
|
||||
@value: value of data being written to memory, or irrelevant if type = READ.
|
||||
@user_data: user data passed to tracing APIs
|
||||
*/
|
||||
typedef void (*uc_cb_hookmem_t)(uc_engine *uc, uc_mem_type type,
|
||||
uint64_t address, int size, int64_t value, void *user_data);
|
||||
|
||||
/*
|
||||
Callback function for handling invalid memory access events (UNMAPPED and
|
||||
PROT events)
|
||||
|
||||
@type: this memory is being READ, or WRITE
|
||||
@address: address where the code is being executed
|
||||
@size: size of data being read or written
|
||||
@value: value of data being written to memory, or irrelevant if type = READ.
|
||||
@user_data: user data passed to tracing APIs
|
||||
|
||||
@return: return true to continue, or false to stop program (due to invalid memory).
|
||||
NOTE: returning true to continue execution will only work if if the accessed
|
||||
memory is made accessible with the correct permissions during the hook.
|
||||
|
||||
In the event of a UC_MEM_READ_UNMAPPED or UC_MEM_WRITE_UNMAPPED callback,
|
||||
the memory should be uc_mem_map()-ed with the correct permissions, and the
|
||||
instruction will then read or write to the address as it was supposed to.
|
||||
|
||||
In the event of a UC_MEM_FETCH_UNMAPPED callback, the memory can be mapped
|
||||
in as executable, in which case execution will resume from the fetched address.
|
||||
The instruction pointer may be written to in order to change where execution resumes,
|
||||
but the fetch must succeed if execution is to resume.
|
||||
*/
|
||||
typedef bool (*uc_cb_eventmem_t)(uc_engine *uc, uc_mem_type type,
|
||||
uint64_t address, int size, int64_t value, void *user_data);
|
||||
|
||||
/*
|
||||
Memory region mapped by uc_mem_map() and uc_mem_map_ptr()
|
||||
Retrieve the list of memory regions with uc_mem_regions()
|
||||
*/
|
||||
typedef struct uc_mem_region {
|
||||
uint64_t begin; // begin address of the region (inclusive)
|
||||
uint64_t end; // end address of the region (inclusive)
|
||||
uint32_t perms; // memory permissions of the region
|
||||
} uc_mem_region;
|
||||
|
||||
// All type of queries for uc_query() API.
|
||||
typedef enum uc_query_type {
|
||||
// Dynamically query current hardware mode.
|
||||
UC_QUERY_MODE = 1,
|
||||
UC_QUERY_PAGE_SIZE, // query pagesize of engine
|
||||
UC_QUERY_ARCH, // query architecture of engine (for ARM to query Thumb mode)
|
||||
UC_QUERY_TIMEOUT, // query if emulation stops due to timeout (indicated if result = True)
|
||||
} uc_query_type;
|
||||
|
||||
// Opaque storage for CPU context, used with uc_context_*()
|
||||
struct uc_context;
|
||||
typedef struct uc_context uc_context;
|
||||
|
||||
/*
|
||||
Return combined API version & major and minor version numbers.
|
||||
|
||||
@major: major number of API version
|
||||
@minor: minor number of API version
|
||||
|
||||
@return hexical number as (major << 8 | minor), which encodes both
|
||||
major & minor versions.
|
||||
NOTE: This returned value can be compared with version number made
|
||||
with macro UC_MAKE_VERSION
|
||||
|
||||
For example, second API version would return 1 in @major, and 1 in @minor
|
||||
The return value would be 0x0101
|
||||
|
||||
NOTE: if you only care about returned value, but not major and minor values,
|
||||
set both @major & @minor arguments to NULL.
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
unsigned int uc_version(unsigned int *major, unsigned int *minor);
|
||||
|
||||
|
||||
/*
|
||||
Determine if the given architecture is supported by this library.
|
||||
|
||||
@arch: architecture type (UC_ARCH_*)
|
||||
|
||||
@return True if this library supports the given arch.
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
bool uc_arch_supported(uc_arch arch);
|
||||
|
||||
|
||||
/*
|
||||
Create new instance of unicorn engine.
|
||||
|
||||
@arch: architecture type (UC_ARCH_*)
|
||||
@mode: hardware mode. This is combined of UC_MODE_*
|
||||
@uc: pointer to uc_engine, which will be updated at return time
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **uc);
|
||||
|
||||
/*
|
||||
Close a Unicorn engine instance.
|
||||
NOTE: this must be called only when there is no longer any
|
||||
usage of @uc. This API releases some of @uc's cached memory, thus
|
||||
any use of the Unicorn API with @uc after it has been closed may
|
||||
crash your application. After this, @uc is invalid, and is no
|
||||
longer usable.
|
||||
|
||||
@uc: pointer to a handle returned by uc_open()
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_close(uc_engine *uc);
|
||||
|
||||
/*
|
||||
Query internal status of engine.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@type: query type. See uc_query_type
|
||||
|
||||
@result: save the internal status queried
|
||||
|
||||
@return: error code of uc_err enum type (UC_ERR_*, see above)
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_query(uc_engine *uc, uc_query_type type, size_t *result);
|
||||
|
||||
/*
|
||||
Report the last error number when some API function fail.
|
||||
Like glibc's errno, uc_errno might not retain its old value once accessed.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
|
||||
@return: error code of uc_err enum type (UC_ERR_*, see above)
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_errno(uc_engine *uc);
|
||||
|
||||
/*
|
||||
Return a string describing given error code.
|
||||
|
||||
@code: error code (see UC_ERR_* above)
|
||||
|
||||
@return: returns a pointer to a string that describes the error code
|
||||
passed in the argument @code
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
const char *uc_strerror(uc_err code);
|
||||
|
||||
/*
|
||||
Write to register.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@regid: register ID that is to be modified.
|
||||
@value: pointer to the value that will set to register @regid
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_reg_write(uc_engine *uc, int regid, const void *value);
|
||||
|
||||
/*
|
||||
Read register value.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@regid: register ID that is to be retrieved.
|
||||
@value: pointer to a variable storing the register value.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_reg_read(uc_engine *uc, int regid, void *value);
|
||||
|
||||
/*
|
||||
Write multiple register values.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@rges: array of register IDs to store
|
||||
@value: pointer to array of register values
|
||||
@count: length of both *regs and *vals
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_reg_write_batch(uc_engine *uc, int *regs, void *const *vals, int count);
|
||||
|
||||
/*
|
||||
Read multiple register values.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@rges: array of register IDs to retrieve
|
||||
@value: pointer to array of values to hold registers
|
||||
@count: length of both *regs and *vals
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_reg_read_batch(uc_engine *uc, int *regs, void **vals, int count);
|
||||
|
||||
/*
|
||||
Write to a range of bytes in memory.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@address: starting memory address of bytes to set.
|
||||
@bytes: pointer to a variable containing data to be written to memory.
|
||||
@size: size of memory to write to.
|
||||
|
||||
NOTE: @bytes must be big enough to contain @size bytes.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *bytes, size_t size);
|
||||
|
||||
/*
|
||||
Read a range of bytes in memory.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@address: starting memory address of bytes to get.
|
||||
@bytes: pointer to a variable containing data copied from memory.
|
||||
@size: size of memory to read.
|
||||
|
||||
NOTE: @bytes must be big enough to contain @size bytes.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *bytes, size_t size);
|
||||
|
||||
/*
|
||||
Emulate machine code in a specific duration of time.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@begin: address where emulation starts
|
||||
@until: address where emulation stops (i.e when this address is hit)
|
||||
@timeout: duration to emulate the code (in microseconds). When this value is 0,
|
||||
we will emulate the code in infinite time, until the code is finished.
|
||||
@count: the number of instructions to be emulated. When this value is 0,
|
||||
we will emulate all the code available, until the code is finished.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_emu_start(uc_engine *uc, uint64_t begin, uint64_t until, uint64_t timeout, size_t count);
|
||||
|
||||
/*
|
||||
Stop emulation (which was started by uc_emu_start() API.
|
||||
This is typically called from callback functions registered via tracing APIs.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_emu_stop(uc_engine *uc);
|
||||
|
||||
/*
|
||||
Register callback for a hook event.
|
||||
The callback will be run when the hook event is hit.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@hh: hook handle returned from this registration. To be used in uc_hook_del() API
|
||||
@type: hook type
|
||||
@callback: callback to be run when instruction is hit
|
||||
@user_data: user-defined data. This will be passed to callback function in its
|
||||
last argument @user_data
|
||||
@begin: start address of the area where the callback is effect (inclusive)
|
||||
@end: end address of the area where the callback is effect (inclusive)
|
||||
NOTE 1: the callback is called only if related address is in range [@begin, @end]
|
||||
NOTE 2: if @begin > @end, callback is called whenever this hook type is triggered
|
||||
@...: variable arguments (depending on @type)
|
||||
NOTE: if @type = UC_HOOK_INSN, this is the instruction ID (ex: UC_X86_INS_OUT)
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback,
|
||||
void *user_data, uint64_t begin, uint64_t end, ...);
|
||||
|
||||
/*
|
||||
Unregister (remove) a hook callback.
|
||||
This API removes the hook callback registered by uc_hook_add().
|
||||
NOTE: this should be called only when you no longer want to trace.
|
||||
After this, @hh is invalid, and nolonger usable.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@hh: handle returned by uc_hook_add()
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_hook_del(uc_engine *uc, uc_hook hh);
|
||||
|
||||
typedef enum uc_prot {
|
||||
UC_PROT_NONE = 0,
|
||||
UC_PROT_READ = 1,
|
||||
UC_PROT_WRITE = 2,
|
||||
UC_PROT_EXEC = 4,
|
||||
UC_PROT_ALL = 7,
|
||||
} uc_prot;
|
||||
|
||||
/*
|
||||
Map memory in for emulation.
|
||||
This API adds a memory region that can be used by emulation.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@address: starting address of the new memory region to be mapped in.
|
||||
This address must be aligned to 4KB, or this will return with UC_ERR_ARG error.
|
||||
@size: size of the new memory region to be mapped in.
|
||||
This size must be multiple of 4KB, or this will return with UC_ERR_ARG error.
|
||||
@perms: Permissions for the newly mapped region.
|
||||
This must be some combination of UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC,
|
||||
or this will return with UC_ERR_ARG error.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms);
|
||||
|
||||
/*
|
||||
Map existing host memory in for emulation.
|
||||
This API adds a memory region that can be used by emulation.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@address: starting address of the new memory region to be mapped in.
|
||||
This address must be aligned to 4KB, or this will return with UC_ERR_ARG error.
|
||||
@size: size of the new memory region to be mapped in.
|
||||
This size must be multiple of 4KB, or this will return with UC_ERR_ARG error.
|
||||
@perms: Permissions for the newly mapped region.
|
||||
This must be some combination of UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC,
|
||||
or this will return with UC_ERR_ARG error.
|
||||
@ptr: pointer to host memory backing the newly mapped memory. This host memory is
|
||||
expected to be an equal or larger size than provided, and be mapped with at
|
||||
least PROT_READ | PROT_WRITE. If it is not, the resulting behavior is undefined.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size, uint32_t perms, void *ptr);
|
||||
|
||||
/*
|
||||
Unmap a region of emulation memory.
|
||||
This API deletes a memory mapping from the emulation memory space.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@address: starting address of the memory region to be unmapped.
|
||||
This address must be aligned to 4KB, or this will return with UC_ERR_ARG error.
|
||||
@size: size of the memory region to be modified.
|
||||
This size must be multiple of 4KB, or this will return with UC_ERR_ARG error.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_unmap(uc_engine *uc, uint64_t address, size_t size);
|
||||
|
||||
/*
|
||||
Set memory permissions for emulation memory.
|
||||
This API changes permissions on an existing memory region.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@address: starting address of the memory region to be modified.
|
||||
This address must be aligned to 4KB, or this will return with UC_ERR_ARG error.
|
||||
@size: size of the memory region to be modified.
|
||||
This size must be multiple of 4KB, or this will return with UC_ERR_ARG error.
|
||||
@perms: New permissions for the mapped region.
|
||||
This must be some combination of UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC,
|
||||
or this will return with UC_ERR_ARG error.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_protect(uc_engine *uc, uint64_t address, size_t size, uint32_t perms);
|
||||
|
||||
/*
|
||||
Retrieve all memory regions mapped by uc_mem_map() and uc_mem_map_ptr()
|
||||
This API allocates memory for @regions, and user must free this memory later
|
||||
by free() to avoid leaking memory.
|
||||
NOTE: memory regions may be splitted by uc_mem_unmap()
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@regions: pointer to an array of uc_mem_region struct. This is allocated by
|
||||
Unicorn, and must be freed by user later with uc_free()
|
||||
@count: pointer to number of struct uc_mem_region contained in @regions
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_regions(uc_engine *uc, uc_mem_region **regions, uint32_t *count);
|
||||
|
||||
/*
|
||||
Allocate a region that can be used with uc_context_{save,restore} to perform
|
||||
quick save/rollback of the CPU context, which includes registers and some
|
||||
internal metadata. Contexts may not be shared across engine instances with
|
||||
differing arches or modes.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@context: pointer to a uc_engine*. This will be updated with the pointer to
|
||||
the new context on successful return of this function.
|
||||
Later, this allocated memory must be freed with uc_free().
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_context_alloc(uc_engine *uc, uc_context **context);
|
||||
|
||||
/*
|
||||
Free the memory allocated by uc_mem_regions.
|
||||
WARNING: After Unicorn 1.0.1rc5, the memory allocated by uc_context_alloc should
|
||||
be free-ed by uc_context_free(). Calling uc_free() may still work, but the result
|
||||
is **undefined**.
|
||||
|
||||
@mem: memory allocated by uc_mem_regions (returned in *regions).
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_free(void *mem);
|
||||
|
||||
/*
|
||||
Save a copy of the internal CPU context.
|
||||
This API should be used to efficiently make or update a saved copy of the
|
||||
internal CPU state.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@context: handle returned by uc_context_alloc()
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_context_save(uc_engine *uc, uc_context *context);
|
||||
|
||||
/*
|
||||
Restore the current CPU context from a saved copy.
|
||||
This API should be used to roll the CPU context back to a previous
|
||||
state saved by uc_context_save().
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@context: handle returned by uc_context_alloc that has been used with uc_context_save
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_context_restore(uc_engine *uc, uc_context *context);
|
||||
|
||||
|
||||
/*
|
||||
Return the size needed to store the cpu context. Can be used to allocate a buffer
|
||||
to contain the cpu context and directly call uc_context_save.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
|
||||
@return the size for needed to store the cpu context as as size_t.
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
size_t uc_context_size(uc_engine *uc);
|
||||
|
||||
|
||||
/*
|
||||
Free the context allocated by uc_context_alloc().
|
||||
|
||||
@context: handle returned by uc_context_alloc()
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_context_free(uc_context *context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1446
ai_anti_malware/unicorn/include/unicorn/x86.h
Normal file
1446
ai_anti_malware/unicorn/include/unicorn/x86.h
Normal file
File diff suppressed because it is too large
Load Diff
23
ai_anti_malware/unicorn/unicorn-master/.github/workflows/cifuzz.yml
vendored
Normal file
23
ai_anti_malware/unicorn/unicorn-master/.github/workflows/cifuzz.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: CIFuzz
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
Fuzzing:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Build Fuzzers
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
||||
with:
|
||||
oss-fuzz-project-name: 'unicorn'
|
||||
dry-run: false
|
||||
- name: Run Fuzzers
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
|
||||
with:
|
||||
oss-fuzz-project-name: 'unicorn'
|
||||
fuzz-seconds: 600
|
||||
dry-run: false
|
||||
- name: Upload Crash
|
||||
uses: actions/upload-artifact@v1
|
||||
if: failure()
|
||||
with:
|
||||
name: artifacts
|
||||
path: ./out/artifacts
|
||||
67
ai_anti_malware/unicorn/unicorn-master/.github/workflows/python-publish.yml
vendored
Normal file
67
ai_anti_malware/unicorn/unicorn-master/.github/workflows/python-publish.yml
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
name: PyPI 📦 Distribution
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-latest, macos-latest, ubuntu-latest]
|
||||
platform: [x32, x64]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
|
||||
- name: Set up MSVC
|
||||
if: matrix.os == 'windows-latest'
|
||||
uses: microsoft/setup-msbuild@v1
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install setuptools wheel
|
||||
|
||||
- name: Build distribution 📦
|
||||
shell: bash
|
||||
run: |
|
||||
if [ ${{ matrix.platform }} == 'x32' ] && [ ${{ matrix.os }} == 'windows-latest' ]; then
|
||||
cd bindings/python && python setup.py build -p win32 sdist bdist_wheel -p win32
|
||||
rm dist/*.tar.gz
|
||||
elif [ ${{ matrix.platform }} == 'x32' ] && [ ${{ matrix.os }} == 'ubuntu-latest' ]; then
|
||||
docker run --rm -v `pwd`/:/work dockcross/manylinux1-x86 > ./dockcross
|
||||
chmod +x ./dockcross
|
||||
./dockcross bindings/python/build_wheel.sh
|
||||
elif [ ${{ matrix.platform }} == 'x64' ] && [ ${{ matrix.os }} == 'ubuntu-latest' ]; then
|
||||
docker run --rm -v `pwd`/:/work dockcross/manylinux1-x64 > ./dockcross
|
||||
chmod +x ./dockcross
|
||||
./dockcross bindings/python/build_wheel.sh
|
||||
elif [ ${{ matrix.platform }} == 'x32' ] && [ ${{ matrix.os }} == 'macos-latest' ]; then
|
||||
cd bindings/python && python setup.py sdist
|
||||
else
|
||||
cd bindings/python && python setup.py bdist_wheel
|
||||
fi
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
path: ${{ github.workspace }}/bindings/python/dist/*
|
||||
|
||||
publish:
|
||||
needs: [build]
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
steps:
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: artifact
|
||||
path: dist
|
||||
|
||||
- name: Publish distribution 📦 to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@master
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.pypi_pass }}
|
||||
101
ai_anti_malware/unicorn/unicorn-master/.gitignore
vendored
Normal file
101
ai_anti_malware/unicorn/unicorn-master/.gitignore
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
.DS_Store
|
||||
*.swp
|
||||
*.d
|
||||
*.o
|
||||
*.a
|
||||
*.dSYM
|
||||
*.so
|
||||
*.so.*
|
||||
*.exe
|
||||
*.dll
|
||||
*.class
|
||||
*.jar
|
||||
*~
|
||||
|
||||
qemu/config-all-devices.mak
|
||||
|
||||
qemu/aarch64-softmmu/
|
||||
qemu/aarch64eb-softmmu/
|
||||
qemu/arm-softmmu/
|
||||
qemu/armeb-softmmu/
|
||||
qemu/m68k-softmmu/
|
||||
qemu/mips64el-softmmu/
|
||||
qemu/mips64-softmmu/
|
||||
qemu/mipsel-softmmu/
|
||||
qemu/mips-softmmu/
|
||||
qemu/sparc64-softmmu/
|
||||
qemu/sparc-softmmu/
|
||||
qemu/i386-softmmu/
|
||||
qemu/x86_64-softmmu/
|
||||
qemu/ppc-softmmu/
|
||||
qemu/ppc64-softmmu/
|
||||
|
||||
tags
|
||||
qemu/config-host.ld
|
||||
qemu/config.log
|
||||
qemu/config.status
|
||||
qemu/config-host.h
|
||||
qemu/config-host.h-timestamp
|
||||
qemu/config-host.mak
|
||||
|
||||
libunicorn*.dll
|
||||
libunicorn*.so
|
||||
libunicorn*.dylib
|
||||
|
||||
unicorn.pc
|
||||
|
||||
unicorn.lib
|
||||
unicorn.dll
|
||||
unicorn.exp
|
||||
unicorn.def
|
||||
unicorn_*.lib
|
||||
unicorn_*.exp
|
||||
unicorn_*.dll
|
||||
|
||||
|
||||
*.tgz
|
||||
*.zip
|
||||
*.pyc
|
||||
_*.txt
|
||||
_*.diff
|
||||
tmp/
|
||||
|
||||
bindings/python/build/
|
||||
bindings/python/dist/
|
||||
bindings/python/src/
|
||||
bindings/python/unicorn.egg-info/
|
||||
bindings/python/unicorn/lib/
|
||||
bindings/python/unicorn/include/
|
||||
bindings/python/MANIFEST
|
||||
config.log
|
||||
|
||||
|
||||
#################
|
||||
## Visual Studio
|
||||
#################
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# vscode
|
||||
.vscode
|
||||
.vscode/
|
||||
|
||||
# User-specific files
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
Win32/
|
||||
build/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
packages/
|
||||
cmocka/
|
||||
353
ai_anti_malware/unicorn/unicorn-master/.travis.yml
Normal file
353
ai_anti_malware/unicorn/unicorn-master/.travis.yml
Normal file
@@ -0,0 +1,353 @@
|
||||
language: c
|
||||
env:
|
||||
- PATH=$PATH:/usr/local/opt/binutils/bin
|
||||
script:
|
||||
- |
|
||||
if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then
|
||||
if [[ "$TRAVIS_COMPILER" == "clang" ]]; then
|
||||
choco install cygwin cyg-get && \
|
||||
cyg-get.bat default autoconf automake make gcc-core clang pkg-config libpcre-devel cmake python27-setuptools ruby wget && \
|
||||
export SHELLOPTS && set -o igncr && \
|
||||
cmd.exe //C "C:\\tools\\cygwin\\bin\\bash.exe -lc 'cd /cygdrive/$TRAVIS_BUILD_DIR; make header; make'"
|
||||
else
|
||||
choco install cygwin cyg-get && \
|
||||
cyg-get.bat default autoconf automake make gcc-core clang pkg-config libpcre-devel cmake python27-setuptools ruby wget && \
|
||||
export SHELLOPTS && set -o igncr && \
|
||||
cmd.exe //C "C:\\tools\\cygwin\\bin\\bash.exe -lc 'cd /cygdrive/$TRAVIS_BUILD_DIR; make header; make; ./install-cmocka-linux.sh; export PATH="$PATH":/cygdrive/$TRAVIS_BUILD_DIR:/cygdrive/$TRAVIS_BUILD_DIR/cmocka/src; make test'"
|
||||
fi
|
||||
elif [[ "$TRAVIS_CPU_ARCH" == "arm64" ]]; then
|
||||
make header && make && make -C tests/unit test && make -C tests/regress test
|
||||
else
|
||||
make header && make && make -C bindings/go && make -C bindings/go test && make test
|
||||
fi
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
os:
|
||||
- linux
|
||||
- windows
|
||||
arch:
|
||||
- amd64
|
||||
- arm64
|
||||
matrix:
|
||||
fast_finish: true
|
||||
exclude:
|
||||
- os: windows
|
||||
arch: arm64
|
||||
include:
|
||||
|
||||
- name: "Compiler: clang C"
|
||||
os: osx
|
||||
osx_image: xcode10.1
|
||||
python: 3.7
|
||||
compiler: clang
|
||||
before_cache:
|
||||
- brew cleanup
|
||||
- find /usr/local/Homebrew \! -regex ".+\.git.+" -delete;
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/Library/Caches/Homebrew
|
||||
- /usr/local/Homebrew
|
||||
before_install:
|
||||
- cd /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core && git stash && git clean -d -f
|
||||
script:
|
||||
- cd $TRAVIS_BUILD_DIR
|
||||
- make header && make && make -C bindings/go && make -C bindings/go test && make test
|
||||
|
||||
- name: "Compiler: gcc C"
|
||||
os: osx
|
||||
osx_image: xcode10.1
|
||||
python: 3.7
|
||||
compiler: gcc
|
||||
before_cache:
|
||||
- brew cleanup
|
||||
- find /usr/local/Homebrew \! -regex ".+\.git.+" -delete;
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/Library/Caches/Homebrew
|
||||
- /usr/local/Homebrew
|
||||
before_install:
|
||||
- cd /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core && git stash && git clean -d -f
|
||||
script:
|
||||
- cd $TRAVIS_BUILD_DIR
|
||||
- make header && make && make -C bindings/go && make -C bindings/go test && make test
|
||||
|
||||
- name: "Linux clang ASAN"
|
||||
os: linux
|
||||
compiler: clang
|
||||
env:
|
||||
- PATH=$PATH:/usr/local/opt/binutils/bin
|
||||
- ASAN_OPTIONS=detect_leaks=0
|
||||
- CXXFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -fsanitize=fuzzer-no-link"
|
||||
- CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -fsanitize=fuzzer-no-link"
|
||||
- LDFLAGS="-fsanitize=address"
|
||||
script:
|
||||
- make header && make
|
||||
- make -C tests/fuzz && sh tests/fuzz/dlcorpus.sh
|
||||
|
||||
- name: "Linux clang MSAN"
|
||||
os: linux
|
||||
compiler: clang
|
||||
env:
|
||||
- PATH=$PATH:/usr/local/opt/binutils/bin
|
||||
- ASAN_OPTIONS=detect_leaks=0
|
||||
- CXXFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=memory -fsanitize=fuzzer-no-link"
|
||||
- CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=memory -fsanitize=fuzzer-no-link"
|
||||
- LDFLAGS="-fsanitize=memory"
|
||||
script:
|
||||
- make header && make
|
||||
- make -C tests/fuzz && sh tests/fuzz/dlcorpus.sh
|
||||
|
||||
- name: "Linux clang USAN"
|
||||
os: linux
|
||||
compiler: clang
|
||||
env:
|
||||
- PATH=$PATH:/usr/local/opt/binutils/bin
|
||||
- ASAN_OPTIONS=detect_leaks=0
|
||||
- CXXFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=undefined -fsanitize=fuzzer-no-link"
|
||||
- CFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=undefined -fsanitize=fuzzer-no-link"
|
||||
- LDFLAGS="-fsanitize=undefined"
|
||||
script:
|
||||
- make header && make
|
||||
- make -C tests/fuzz && sh tests/fuzz/dlcorpus.sh
|
||||
|
||||
- name: "Linux 32bit"
|
||||
os: linux
|
||||
compiler: gcc
|
||||
env:
|
||||
- CFLAGS="-m32" LDFLAGS="-m32" LDFLAGS_STATIC="-m32" UNICORN_QEMU_FLAGS="--cpu=i386"
|
||||
- PATH=$PATH:/usr/local/opt/binutils/bin
|
||||
script: make header && make && make -C tests/unit test && make -C tests/regress test
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- lib32ncurses5-dev
|
||||
- lib32z1-dev
|
||||
- libpthread-stubs0-dev
|
||||
- lib32gcc-4.8-dev
|
||||
- libc6-dev-i386
|
||||
- gcc-multilib
|
||||
- libcmocka-dev:i386
|
||||
|
||||
- name: "Linux Cmake 32bit"
|
||||
os: linux
|
||||
compiler: gcc
|
||||
env:
|
||||
- CFLAGS="-m32" LDFLAGS="-m32" LDFLAGS_STATIC="-m32" UNICORN_QEMU_FLAGS="--cpu=i386"
|
||||
- PATH=$PATH:/usr/local/opt/binutils/bin
|
||||
script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../cmake.sh x86
|
||||
- cp libunicorn.* ../
|
||||
- make -C ../tests/unit test && make -C ../tests/regress test
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- lib32ncurses5-dev
|
||||
- lib32z1-dev
|
||||
- libpthread-stubs0-dev
|
||||
- lib32gcc-4.8-dev
|
||||
- libc6-dev-i386
|
||||
- gcc-multilib
|
||||
- libcmocka-dev:i386
|
||||
|
||||
- name: "Linux Cmake 64bit"
|
||||
os: linux
|
||||
compiler: gcc
|
||||
env:
|
||||
- PATH=$PATH:/usr/local/opt/binutils/bin
|
||||
script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- ../cmake.sh
|
||||
- cp libunicorn.* ../
|
||||
- make -C ../tests/unit test && make -C ../tests/regress test
|
||||
|
||||
- name: "Linux Cmake Static 32bit"
|
||||
os: linux
|
||||
compiler: gcc
|
||||
env:
|
||||
- CFLAGS="-m32" LDFLAGS="-m32" LDFLAGS_STATIC="-m32" UNICORN_QEMU_FLAGS="--cpu=i386"
|
||||
- PATH=$PATH:/usr/local/opt/binutils/bin
|
||||
script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DCMAKE_BUILD_TYPE=Release -DUNICORN_ARCH=x86 -DUNICORN_BUILD_SHARED=OFF .. && make -j8
|
||||
# temporarily disable test for static build
|
||||
# - cp libunicorn.* ../
|
||||
# - make -C ../tests/unit test && make -C ../tests/regress test
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- lib32ncurses5-dev
|
||||
- lib32z1-dev
|
||||
- libpthread-stubs0-dev
|
||||
- lib32gcc-4.8-dev
|
||||
- libc6-dev-i386
|
||||
- gcc-multilib
|
||||
- libcmocka-dev:i386
|
||||
|
||||
- name: "Linux Cmake Static 64bit"
|
||||
os: linux
|
||||
compiler: gcc
|
||||
env:
|
||||
- PATH=$PATH:/usr/local/opt/binutils/bin
|
||||
script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DCMAKE_BUILD_TYPE=Release -DUNICORN_BUILD_SHARED=OFF .. && make -j8
|
||||
# - cp libunicorn.* ../
|
||||
# - make -C ../tests/unit test && make -C ../tests/regress test
|
||||
|
||||
- name: "MacOSX brew"
|
||||
os: osx
|
||||
osx_image: xcode10.1
|
||||
python: 3.7
|
||||
before_cache:
|
||||
- brew cleanup
|
||||
- find /usr/local/Homebrew \! -regex ".+\.git.+" -delete;
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/Library/Caches/Homebrew
|
||||
- /usr/local/Homebrew
|
||||
before_install:
|
||||
- cd /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core && git stash && git clean -d -f
|
||||
script:
|
||||
- brew install --HEAD unicorn
|
||||
- brew test unicorn
|
||||
|
||||
- name: "Windows nmake 32bit"
|
||||
os: windows
|
||||
language: shell
|
||||
script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmd.exe //C 'C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat' x86 '&' cmd.exe //C '..\nmake.bat' x86
|
||||
|
||||
- name: "Windows nmake 64bit"
|
||||
os: windows
|
||||
language: shell
|
||||
script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmd.exe //C 'C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat' amd64 '&' cmd.exe //C '..\nmake.bat'
|
||||
|
||||
- name: "Windows MSVC 32bit"
|
||||
os: windows
|
||||
language: shell
|
||||
env:
|
||||
- MSBUILD_PATH="C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin"
|
||||
script:
|
||||
- PATH=$MSBUILD_PATH:$PATH
|
||||
- cmd.exe //C 'msbuild.exe msvc/unicorn.sln /m:2 /nologo /p:Configuration=Release /p:Platform=Win32'
|
||||
|
||||
- name: "Windows MSVC 64bit"
|
||||
os: windows
|
||||
language: shell
|
||||
env:
|
||||
- MSBUILD_PATH="C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin"
|
||||
script:
|
||||
- PATH=$MSBUILD_PATH:$PATH
|
||||
- cmd.exe //C 'msbuild.exe msvc/unicorn.sln /m:2 /nologo /p:Configuration=Release /p:Platform=x64'
|
||||
|
||||
- name: "Windows MSYS2/MinGW32"
|
||||
os: windows
|
||||
language: shell
|
||||
env:
|
||||
- PATH=/C/tools/msys64/mingw32/bin:$PATH
|
||||
before_install:
|
||||
- |
|
||||
if [[ ! -f /C/tools/msys64/msys2_shell.cmd ]]; then
|
||||
rm -rf /C/tools/msys64
|
||||
fi
|
||||
- choco uninstall -y mingw
|
||||
- choco upgrade --no-progress -y msys2
|
||||
- export msys2='cmd //C RefreshEnv.cmd '
|
||||
- export msys2+='& set MSYS=winsymlinks:nativestrict '
|
||||
- export msys2+='& C:\\tools\\msys64\\msys2_shell.cmd -defterm -no-start'
|
||||
- export shell="$msys2 -mingw32 -full-path -here -c \$\* --"
|
||||
- export msys2+=" -msys2 -c \$\* --"
|
||||
- $msys2 pacman --sync --noconfirm --needed \
|
||||
autoconf \
|
||||
automake \
|
||||
make \
|
||||
perl \
|
||||
python \
|
||||
mingw-w64-i686-libtool \
|
||||
mingw-w64-i686-toolchain \
|
||||
mingw-w64-i686-gcc \
|
||||
mingw-w64-i686-cmake \
|
||||
mingw-w64-i686-cmocka \
|
||||
mingw-w64-i686-python3-setuptools \
|
||||
unzip
|
||||
- export CPPFLAGS=-D__USE_MINGW_ANSI_STDIO=1
|
||||
- export CC=i686-w64-mingw32-gcc
|
||||
- export AR=gcc-ar
|
||||
- export RANLIB=gcc-ranlib
|
||||
- export CFLAGS="-m32"
|
||||
- export LDFLAGS="-m32"
|
||||
- export LDFLAGS_STATIC="-m32"
|
||||
- export UNICORN_QEMU_FLAGS="--cpu=i386"
|
||||
# before_cache:
|
||||
# - $msys2 pacman --sync --clean --noconfirm
|
||||
# cache:
|
||||
# timeout:
|
||||
# 1000
|
||||
# directories:
|
||||
# - $HOME/AppData/Local/Temp/chocolatey
|
||||
# - /C/tools/msys64
|
||||
script:
|
||||
- $shell make header; $shell make; cp unicorn.dll /C/Windows/SysWOW64/; $shell make test
|
||||
|
||||
- name: "Windows MSYS2/MinGW64"
|
||||
os: windows
|
||||
language: shell
|
||||
env:
|
||||
- PATH=/C/tools/msys64/mingw64/bin:$PATH
|
||||
before_install:
|
||||
- |
|
||||
if [[ ! -f /C/tools/msys64/msys2_shell.cmd ]]; then
|
||||
rm -rf /C/tools/msys64
|
||||
fi
|
||||
- choco uninstall -y mingw
|
||||
- choco upgrade --no-progress -y msys2
|
||||
- export msys2='cmd //C RefreshEnv.cmd '
|
||||
- export msys2+='& set MSYS=winsymlinks:nativestrict '
|
||||
- export msys2+='& C:\\tools\\msys64\\msys2_shell.cmd -defterm -no-start'
|
||||
- export shell="$msys2 -mingw64 -full-path -here -c \$\* --"
|
||||
- export msys2+=" -msys2 -c \$\* --"
|
||||
- $msys2 pacman --sync --noconfirm --needed \
|
||||
autoconf \
|
||||
automake \
|
||||
make \
|
||||
perl \
|
||||
python \
|
||||
mingw-w64-x86_64-libtool \
|
||||
mingw-w64-x86_64-toolchain \
|
||||
mingw-w64-x86_64-cmake \
|
||||
mingw-w64-x86_64-cmocka \
|
||||
mingw-w64-x86_64-python3-setuptools
|
||||
unzip
|
||||
- export CPPFLAGS=-D__USE_MINGW_ANSI_STDIO=1
|
||||
- export CC=x86_64-w64-mingw32-gcc
|
||||
- export AR=gcc-ar
|
||||
- export RANLIB=gcc-ranlib
|
||||
# before_cache:
|
||||
# - $msys2 pacman --sync --clean --noconfirm
|
||||
# cache:
|
||||
# timeout:
|
||||
# 1000
|
||||
# directories:
|
||||
# - $HOME/AppData/Local/Temp/chocolatey
|
||||
# - /C/tools/msys64
|
||||
script:
|
||||
- $shell make header; $shell make; cp unicorn.dll /C/Windows/System32/; $shell make test
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libpthread-stubs0-dev
|
||||
- libcmocka-dev
|
||||
homebrew:
|
||||
update: true
|
||||
brewfile: true
|
||||
2
ai_anti_malware/unicorn/unicorn-master/AUTHORS.TXT
Normal file
2
ai_anti_malware/unicorn/unicorn-master/AUTHORS.TXT
Normal file
@@ -0,0 +1,2 @@
|
||||
Nguyen Anh Quynh <aquynh -at- gmail.com>
|
||||
Dang Hoang Vu <dang.hvu -at- gmail.com>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user