Skip to content
This repository has been archived by the owner on Dec 14, 2024. It is now read-only.

Commit

Permalink
Initial support for arm64 capstone disassembly
Browse files Browse the repository at this point in the history
  • Loading branch information
riverar committed Dec 14, 2020
1 parent 73d0179 commit 85fadaa
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 21 deletions.
1 change: 1 addition & 0 deletions mach2.sln
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Global
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6279929A-C965-460A-B53A-8388D2BE47A0}.Debug|ARM64.ActiveCfg = Debug|ARM64
{6279929A-C965-460A-B53A-8388D2BE47A0}.Debug|ARM64.Build.0 = Debug|ARM64
{6279929A-C965-460A-B53A-8388D2BE47A0}.Debug|ARM64.Deploy.0 = Debug|ARM64
{6279929A-C965-460A-B53A-8388D2BE47A0}.Debug|x64.ActiveCfg = Debug|x64
{6279929A-C965-460A-B53A-8388D2BE47A0}.Debug|x64.Build.0 = Debug|x64
{6279929A-C965-460A-B53A-8388D2BE47A0}.Debug|x86.ActiveCfg = Debug|Win32
Expand Down
13 changes: 7 additions & 6 deletions mach2.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>NOMINMAX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NOMINMAX;WIN32;X86;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpp17</LanguageStandard>
Expand All @@ -196,7 +196,7 @@ copy /y "$(CurrentVsInstallRoot)\DIA SDK\bin\msdia140.dll" "$(OutDir)"</Command>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>NOMINMAX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NOMINMAX;WIN32;X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<LanguageStandard>stdcpp17</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
Expand All @@ -218,7 +218,7 @@ copy /y "$(CurrentVsInstallRoot)\DIA SDK\bin\amd64\msdia140.dll" "$(OutDir)"</Co
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>NOMINMAX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NOMINMAX;WIN32;ARM64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<LanguageStandard>stdcpp17</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
Expand All @@ -242,7 +242,7 @@ copy /y "$(CurrentVsInstallRoot)\DIA SDK\bin\arm64\msdia140.dll" "$(OutDir)"</Co
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NOMINMAX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NOMINMAX;WIN32;X86;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<LanguageStandard>stdcpp17</LanguageStandard>
Expand All @@ -268,7 +268,7 @@ copy /y "$(CurrentVsInstallRoot)\DIA SDK\bin\msdia140.dll" "$(OutDir)"</Command>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NOMINMAX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NOMINMAX;WIN32;X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard>stdcpp17</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
Expand All @@ -294,7 +294,7 @@ copy /y "$(CurrentVsInstallRoot)\DIA SDK\bin\amd64\msdia140.dll" "$(OutDir)"</Co
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NOMINMAX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NOMINMAX;WIN32;ARM64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard>stdcpp17</LanguageStandard>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
Expand All @@ -314,6 +314,7 @@ copy /y "$(CurrentVsInstallRoot)\DIA SDK\bin\arm64\msdia140.dll" "$(OutDir)"</Co
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="src\capstone_helpers.h" />
<ClInclude Include="src\dia2_internal.h" />
<ClInclude Include="src\pdb.h" />
<ClInclude Include="src\mach2.h" />
Expand Down
2 changes: 1 addition & 1 deletion src/mach2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
int main(int argc, char *argv[], char *)
{
std::wcout
<< L"mach2 0.6 - Feature Control Multi-tool" << std::endl
<< L"mach2 0.7 - Feature Control Multi-tool" << std::endl
<< L"Copyright (c) Rafael Rivera" << std::endl
<< std::endl
<< L"This program comes with ABSOLUTELY NO WARRANTY." << std::endl
Expand Down
52 changes: 39 additions & 13 deletions src/scanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "dia2_internal.h"
#include <diacreate.h>
#include <capstone/capstone.h>
#include "capstone_helpers.h"
#include <DbgHelp.h>

const std::vector<mach2::Scanner::FeatureStage> mach2::Scanner::FeatureStages
Expand Down Expand Up @@ -141,7 +142,7 @@ void mach2::Scanner::GetFeaturesFromSymbolAtPath(std::wstring const &path, mach2
CComPtr<IDiaSession> session;
ThrowIfFailed(data_source->openSession(&session));

PDB1* raw_pdb;
PDB1* raw_pdb = nullptr;
ThrowIfFailed(data_source->getRawPDBPtr(reinterpret_cast<void**>(&raw_pdb)));

GUID signature;
Expand Down Expand Up @@ -360,7 +361,10 @@ void mach2::Scanner::GetMissingFeatureIdsFromImageAtPath(std::wstring const& ima
if (!IsEqualGUID(signature, GUID{}))
{
csh handle;
ThrowIf(cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK);
SYSTEM_INFO system_info{};
GetNativeSystemInfo(&system_info);

ThrowIf(cs_open(CapstoneHelpers::GetArchitectureForSystemArchitecture(system_info.wProcessorArchitecture), CapstoneHelpers::GetModeForSystemArchitecture(system_info.wProcessorArchitecture), &handle) != CS_ERR_OK);
ThrowIf(cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON) != CS_ERR_OK);

for (auto feature : features.FeaturesByGetterSymbolSignature[signature])
Expand All @@ -369,53 +373,75 @@ void mach2::Scanner::GetMissingFeatureIdsFromImageAtPath(std::wstring const& ima
{
auto function_ptr = ImageRvaToVa(headers, file_view, getter_relative_address, nullptr);
const auto CODE_SAMPLE_SIZE = 512;
const auto VELOCITY_ID_MINIMUM = 10000;
if (function_ptr == nullptr || IsBadReadPtr(function_ptr, CODE_SAMPLE_SIZE))
{
continue;
}
cs_insn* instructions;
auto instruction_count = cs_disasm(handle, static_cast<uint8_t*>(function_ptr), CODE_SAMPLE_SIZE, 0, 0, &instructions);
std::int64_t ecx = 0;
std::int64_t probable_id = 0;
for (int i = 0; i < instruction_count; i++)
{
#if X64
auto x86 = instructions[i].detail->x86;
if (std::string(instructions[i].mnemonic) == "mov" && x86.operands[0].reg == X86_REG_ECX && x86.operands[1].type == X86_OP_IMM)
{
auto immediate_value = instructions[i].detail->x86.operands[1].imm;
if (immediate_value >= VELOCITY_ID_MINIMUM)
probable_id = instructions[i].detail->x86.operands[1].imm;
}
if (std::string(instructions[i].mnemonic) == "call" && probable_id != 0)
{
break;
}
#elif ARM64
auto arm64 = instructions[i].detail->arm64;
auto reg = arm64.operands[0].reg;
if (std::string(instructions[i].mnemonic) == "ldr" && reg == std::clamp(reg, ARM64_REG_W0, ARM64_REG_W30) && arm64.operands[1].type == ARM64_OP_IMM)
{
auto effective_addr = static_cast<std::uint8_t*>(function_ptr) + instructions[i].detail->arm64.operands[1].imm;
probable_id = *(reinterpret_cast<std::uint32_t*>(effective_addr));
}
if (std::string(instructions[i].mnemonic) == "movz" && reg == std::clamp(reg, ARM64_REG_W0, ARM64_REG_W30) && arm64.operands[1].type == ARM64_OP_IMM)
{
auto working_value = instructions[i].detail->arm64.operands[1].imm;
auto working_register = reg;

arm64 = instructions[i+1].detail->arm64;
reg = arm64.operands[0].reg;
if (std::string(instructions[i+1].mnemonic) == "movk" && reg == working_register && arm64.operands[1].type == ARM64_OP_IMM)
{
ecx = immediate_value;
probable_id = working_value | (arm64.operands[1].imm << arm64.operands[1].shift.value);
}
}
if (std::string(instructions[i].mnemonic) == "call" && ecx != 0)
if (std::string(instructions[i].mnemonic) == "bl" && probable_id != 0)
{
break;
}
#endif
if (std::string(instructions[i].mnemonic) == "ret")
{
break;
}
}
cs_free(instructions, instruction_count);

if (ecx >= VELOCITY_ID_MINIMUM)
const auto VELOCITY_ID_MINIMUM = 10000;
if (probable_id >= VELOCITY_ID_MINIMUM)
{
if (feature->Id != 0 && feature->Id != ecx)
if (feature->Id != 0 && feature->Id != probable_id)
{
if (HasDuplicateFeatureWithId(ecx, feature->Name, features))
if (HasDuplicateFeatureWithId(probable_id, feature->Name, features))
continue;

auto unique_name = GetUniqueNameForDuplicateFeature(*feature, features);
auto& new_feature = features.FeaturesByName[unique_name];
features.FeaturesByStage[FeatureStage::Unknown][unique_name] = &new_feature;
new_feature.Name = unique_name;
new_feature.Id = ecx;
new_feature.Id = probable_id;
new_feature.Symbols = feature->Symbols;
}
else
{
feature->Id = ecx;
feature->Id = probable_id;
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion vcpkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
{
"name": "capstone",
"default-features": false,
"features": [ "x86" ]
"features": [ "x86", "arm64" ]
},
{
"name": "cli11",
Expand Down

0 comments on commit 85fadaa

Please sign in to comment.