auto
buildFunctionMaps(pe64* pe) -> std::vector<std::shared_ptr<_functionDetail>> {
std::vector<std::shared_ptr<_functionDetail>> functionList;
cs_insn* insn =
nullptr
;
size_t
disasmCount = 0;
do
{
auto
textSection = pe->get_section(
".text"
);
const
auto
codeAddressInMemory =
reinterpret_cast
<uint64_t>(
pe->get_buffer()->data() + textSection->VirtualAddress);
disasmCount =
cs_disasm(capstone_handle,
reinterpret_cast
<
const
uint8_t*>(codeAddressInMemory),
textSection->Misc.VirtualSize, 0, 0, &insn);
if
(disasmCount == 0) {
break
;
}
std::vector<std::string> backTrackCodeList;
bool
isEnterFunction =
false
;
bool
isFirst =
true
;
size_t
currentFunctionSize = 0;
uint64_t currentFuncAddress = 0;
size_t
offset = 0;
for
(
size_t
index = 0; index < disasmCount; index++) {
const
auto
code = insn[index];
const
auto
codeMnemonic = std::string(code.mnemonic);
const
auto
opCode = std::string(code.op_str);
if
(backTrackCodeList.size() > 3) {
backTrackCodeList.erase(backTrackCodeList.begin());
}
backTrackCodeList.push_back(codeMnemonic);
if
((codeMnemonic !=
"int3"
&& codeMnemonic !=
"nop"
) &&
((backTrackCodeList.size() > 2) &&
(backTrackCodeList[0] ==
"int3"
||
backTrackCodeList[0] ==
"nop"
) &&
(backTrackCodeList[1] ==
"int3"
||
backTrackCodeList[1] ==
"nop"
) &&
(backTrackCodeList[2] ==
"int3"
||
backTrackCodeList[2] ==
"nop"
)) &&
isEnterFunction ==
false
) {
currentFuncAddress = codeAddressInMemory + offset;
isEnterFunction =
true
;
backTrackCodeList.clear();
}
else
if
((codeMnemonic ==
"int3"
|| codeMnemonic ==
"nop"
) &&
((backTrackCodeList.size() > 2) &&
(backTrackCodeList[0] !=
"int3"
&&
backTrackCodeList[0] !=
"nop"
)) &&
isEnterFunction) {
auto
func = _functionDetail{ .start_address = currentFuncAddress,
.end_address = codeAddressInMemory + code.address,
.size = (codeAddressInMemory + code.address) - currentFuncAddress };
functionList.push_back(std::make_shared<_functionDetail>(func));
isFirst =
false
;
isEnterFunction =
false
;
currentFunctionSize = 0;
currentFuncAddress = 0;
}
currentFunctionSize += code.size;
offset += code.size;
}
if
(isFirst) {
functionList.push_back(
std::make_shared<_functionDetail>(_functionDetail{
.start_address =
static_cast
<uint64_t>(codeAddressInMemory),
.end_address =
static_cast
<uint64_t>(
codeAddressInMemory + textSection->Misc.VirtualSize),
.size = textSection->Misc.VirtualSize }));
}
}
while
(
false
);
cs_free(insn, disasmCount);
return
functionList;
}