HyperDbg Debugger
Loading...
Searching...
No Matches
AssembleData Class Reference

#include <assembler.h>

Public Member Functions

 AssembleData ()=default
 
VOID ParseAssemblyData ()
 tries to solve the symbol issue with Keystone, which apparently originates from LLVM-MC.
 
INT Assemble (UINT64 StartAddr, ks_arch Arch=KS_ARCH_X86, INT Mode=KS_MODE_64, INT Syntax=KS_OPT_SYNTAX_INTEL)
 

Public Attributes

std::string AsmRaw {}
 
std::string AsmFixed {}
 
size_t StatementCount {}
 
size_t BytesCount {}
 
unsigned char * EncodedBytes {}
 
vector< UINT64EncBytesIntVec {}
 
ks_err KsErr {}
 

Constructor & Destructor Documentation

◆ AssembleData()

AssembleData::AssembleData ( )
default

Member Function Documentation

◆ Assemble()

INT AssembleData::Assemble ( UINT64 StartAddr,
ks_arch Arch = KS_ARCH_X86,
INT Mode = KS_MODE_64,
INT Syntax = KS_OPT_SYNTAX_INTEL )
120{
121 ks_engine * Ks;
122
123 KsErr = ks_open(Arch, Mode, &Ks);
124 if (KsErr != KS_ERR_OK)
125 {
126 ShowMessages("err, failed on ks_open()");
127 return -1;
128 }
129
130 if (Syntax)
131 {
132 KsErr = ks_option(Ks, KS_OPT_SYNTAX, Syntax);
133 if (KsErr != KS_ERR_OK)
134 {
135 ShowMessages("err, failed on ks_option() with error code = %u\n", KsErr);
136 }
137 }
138
139 //
140 // as long as symbols are parsed before passing asm code, SymResolver is not needed, for now.
141 //
142 KsErr = ks_option(Ks, KS_OPT_SYM_RESOLVER, 0); // null SymResolver
143 if (KsErr != KS_ERR_OK)
144 {
145 ShowMessages("err, failed on ks_option() with error code = %u\n", KsErr);
146 }
147
148 if (ks_asm(Ks, AsmFixed.c_str(), StartAddr, &EncodedBytes, &BytesCount, &StatementCount))
149 {
150 KsErr = ks_errno(Ks);
151 ShowMessages("err, failed on ks_asm() with count = %lu, error code = %u\n", (int)StatementCount, KsErr);
152 }
153 else
154 {
155 if (BytesCount == 0)
156 {
157 ShowMessages("err, the assemble operation returned no bytes, most likely due to incorrect formatting of assembly snippet\n");
158 }
159 else
160 {
161 ShowMessages("generated assembly: %lu (decimal) bytes, %lu (decimal) statements ==>> ", (int)BytesCount, (int)StatementCount);
162
163 size_t i;
164 ShowMessages("%s = ", AsmFixed.c_str());
165 for (i = 0; i < BytesCount; i++)
166 {
167 ShowMessages("%02x ", EncodedBytes[i]);
168 EncBytesIntVec.push_back(static_cast<UINT64>(EncodedBytes[i]));
169 }
170 ShowMessages("\n");
171
172 ks_close(Ks);
173 return 0;
174 }
175 }
176 ks_close(Ks);
177 return -1;
178}
unsigned __int64 UINT64
Definition BasicTypes.h:21
std::string AsmFixed
Definition assembler.h:19
vector< UINT64 > EncBytesIntVec
Definition assembler.h:23
size_t BytesCount
Definition assembler.h:21
size_t StatementCount
Definition assembler.h:20
ks_err KsErr
Definition assembler.h:24
unsigned char * EncodedBytes
Definition assembler.h:22
KEYSTONE_EXPORT ks_err ks_errno(ks_engine *ks)
@ KS_ERR_OK
Definition keystone.h:112
KEYSTONE_EXPORT ks_err ks_close(ks_engine *ks)
KEYSTONE_EXPORT ks_err ks_option(ks_engine *ks, ks_opt_type type, size_t value)
KEYSTONE_EXPORT int ks_asm(ks_engine *ks, const char *string, uint64_t address, unsigned char **encoding, size_t *encoding_size, size_t *stat_count)
KEYSTONE_EXPORT ks_err ks_open(ks_arch arch, int mode, ks_engine **ks)
struct ks_struct ks_engine
Definition keystone.h:38
@ KS_OPT_SYM_RESOLVER
Definition keystone.h:178
@ KS_OPT_SYNTAX
Definition keystone.h:177
VOID ShowMessages(const char *Fmt,...)
Show messages.
Definition libhyperdbg.cpp:96

◆ ParseAssemblyData()

VOID AssembleData::ParseAssemblyData ( )

tries to solve the symbol issue with Keystone, which apparently originates from LLVM-MC.

Returns
VOID
21{
22 std::string RawAsm = AsmRaw;
23
24 //
25 // remove all "\n" instances
26 //
27 RawAsm.erase(std::remove(RawAsm.begin(), RawAsm.end(), '\n'), RawAsm.end());
28
29 //
30 // remove multiple spaces
31 //
32 std::regex MultipleSpaces(" +");
33 RawAsm = std::regex_replace(RawAsm, MultipleSpaces, " ");
34
35 //
36 // split assembly line by ';'
37 //
38 std::vector<std::string> AssemblyInstructions;
39 size_t Pos = 0;
40 std::string Delimiter = ";";
41 while ((Pos = RawAsm.find(Delimiter)) != std::string::npos)
42 {
43 std::string Token = RawAsm.substr(0, Pos);
44 if (!Token.empty())
45 {
46 AssemblyInstructions.push_back(Token);
47 }
48 RawAsm.erase(0, Pos + Delimiter.length());
49 }
50 if (!RawAsm.empty())
51 {
52 AssemblyInstructions.push_back(RawAsm);
53 }
54
55 //
56 // process each assembly instruction
57 //
58 for (auto & InstructionLine : AssemblyInstructions)
59 {
60 std::string Expr {};
61 UINT64 ExprAddr {};
62 size_t Start {};
63
64 while ((Start = InstructionLine.find('<', Start)) != std::string::npos)
65 {
66 size_t End = InstructionLine.find('>', Start);
67 if (End != std::string::npos)
68 {
69 std::string Expr = InstructionLine.substr(Start + 1, End - Start - 1);
70 if (!SymbolConvertNameOrExprToAddress(Expr, &ExprAddr) && ExprAddr == 0)
71 {
72 ShowMessages("err, failed to resolve the symbol [ %s ].\n", Expr.c_str());
73 Start += Expr.size() + 2;
74 continue;
75 }
76
77 std::ostringstream Oss;
78 Oss << std::hex << std::showbase << ExprAddr;
79 InstructionLine.replace(Start, End - Start + 1, Oss.str());
80 }
81 else
82 {
83 //
84 // No matching '>' found, break the loop
85 //
86 break;
87 }
88 Start += Expr.size() + 2;
89 }
90 }
91
92 //
93 // Append ";" between two std::strings
94 //
95 auto ApndSemCln = [](std::string a, std::string b) {
96 return std::move(a) + ';' + std::move(b);
97 };
98
99 //
100 // Concatenate each assembly line
101 //
102 AsmFixed = std::accumulate(std::next(AssemblyInstructions.begin()), AssemblyInstructions.end(), AssemblyInstructions.at(0), ApndSemCln);
103
104 if (!AsmFixed.empty() && AsmFixed.back() == ';')
105 {
106 //
107 // remove the last ";" for it will be counted as a statement by Keystone and a wrong number would be printed
108 //
109 AsmFixed.pop_back();
110 }
111
112 while (!AsmFixed.empty() && AsmFixed.back() == ';')
113 {
114 AsmFixed.pop_back();
115 }
116}
std::string AsmRaw
Definition assembler.h:18
BOOLEAN SymbolConvertNameOrExprToAddress(const string &TextToConvert, PUINT64 Result)
check and convert string to a 64 bit unsigned integer and also check for symbol object names and eval...
Definition symbol.cpp:360

Member Data Documentation

◆ AsmFixed

std::string AssembleData::AsmFixed {}
19{};

◆ AsmRaw

std::string AssembleData::AsmRaw {}
18{};

◆ BytesCount

size_t AssembleData::BytesCount {}
21{};

◆ EncBytesIntVec

vector<UINT64> AssembleData::EncBytesIntVec {}
23{};

◆ EncodedBytes

unsigned char* AssembleData::EncodedBytes {}
22{};

◆ KsErr

ks_err AssembleData::KsErr {}
24{};

◆ StatementCount

size_t AssembleData::StatementCount {}
20{};

The documentation for this class was generated from the following files: