Capstone cs_disasm разборка только небольшой части кода

Я экспериментирую с http://www.capstone-engine.org на MacOS и MacOS x86_64 бинарный. Это более или менее работает, однако у меня есть 2 проблемы.

Я загружаю тестовый dylib

[self custom_logging:[NSString stringWithFormat:@"Module Path:%@",clientPath]];
NSMutableData *ModuleNSDATA = [NSMutableData dataWithContentsOfFile:clientPath];
[self custom_logging:[NSString stringWithFormat:@"Client Module Size: %lu MB",(ModuleNSDATA.length/1024/1024)]];
[ModuleNSDATA replaceBytesInRange:NSMakeRange(0, 20752) withBytes:NULL length:0];
uint8_t *bytes = (uint8_t*)[ModuleNSDATA bytes];
long size = [ModuleNSDATA length]/sizeof(uint8_t);
[self custom_logging:[NSString stringWithFormat:@"UInt8_t array size: %lu",size]];
ModuleASM = [NSString stringWithCString:disassembly(bytes,size,0x5110).c_str() encoding:[NSString defaultCStringEncoding]];
  1. Поскольку я провел свое исследование, мне кажется, что мне нужно обрезать «первые» байты из двоичного кода, чтобы удалить заголовок и метаданные, пока он не встретит реальные инструкции. Однако я не совсем уверен, если Capstone действительно предоставляют API для того или иного мне нужно сканировать по байтовым образцам и найти первый адрес инструкции.

Фактически я применил простой обходной путь, я нашел безопасный адрес, который наверняка будет содержать инструкции по большинству модулей, которые я загружу, однако я бы хотел применить правильное решение.

  1. Я успешно загрузил и разобрал часть кода модуля, используя описанный мной обходной путь. Однако, к сожалению, cs_disasm возвращает в основном не более 5000-6000 инструкций, что вводит в заблуждение, кажется, что оно нарушает обычные инструкции, к которым не следует прибегать. Я не совсем уверен, что я делаю не так. Модуль содержит более 15 МБ кода, поэтому для разборки требуется более 5 000 инструкций.

Ниже приведена функция, которую я основал на примере Документов Capstone.

string disassembly(uint8_t *bytearray, long size, uint64_t startAddress){
csh handle;
cs_insn *insn;
size_t count;
string output;
if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) == CS_ERR_OK){
count = cs_disasm(handle, bytearray, size, startAddress, 0, &insn);
printf("\nCOUNT:%lu",count);
if (count > 0) {
size_t j;
for (j = 0; j < count; j++) {
char buffer[512];
int i=0;
i = sprintf(buffer, "0x%" PRIx64":\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic,insn[j].op_str);
output += buffer;
}
cs_free(insn, count);
} else {
output = "ERROR: Failed to disassemble given code!\n";
}
}
cs_close(&handle);
return output;
}

Я буду очень признателен за любую помощь в этом.
Тепло,
Дэвид

1

Решение

Anwser просто использовать режим SKIPDATA. Capstone великолепен, но их документы очень плохие.

Рабочий пример ниже. Этот режим все еще сильно прослушивается, поэтому предпочтительно, чтобы при обнаружении секторов данных использовался пользовательский код. Для меня это прекрасно работает только с небольшими кусками кода. Тем не менее, это действительно разборка до конца файла.

string disassembly(uint8_t *bytearray, long size, uint64_t startAddress){
csh handle;
cs_insn *insn;
size_t count;
string output;
cs_opt_skipdata skipdata = {
.mnemonic = "db",
};
if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) == CS_ERR_OK){
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);
cs_option(handle, CS_OPT_SKIPDATA_SETUP, (size_t)&skipdata);
count = cs_disasm(handle, bytearray, size, startAddress, 0, &insn);
if (count > 0) {
size_t j;
for (j = 0; j < count; j++) {
char buffer[512];
int i=0;
i = sprintf(buffer, "0x%" PRIx64":\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic,insn[j].op_str);
output += buffer;
}
cs_free(insn, count);
} else {
output = "ERROR: Failed to disassemble given code!\n";
}
}
cs_close(&handle);
return output;
}

Позор тем троллям, которые проголосовали против этого вопроса.

0

Другие решения

Других решений пока нет …