Дошли руки стартовать небольшой проект на sourceforge:
Diana Disassembler.
Цель проекта - иметь под рукой максимально удобный, переносимый и быстрый инструмент для получения доступа к интересным частям ядра.
Важные для меня вкусности:
- ядро написано на чистом C, никаких dll, OS-зависимых частей, минимальные требования к рантайму;
- часть ядра сгенерирована автоматически из Intel'овской спецификации (в два этапа html->xml->diana_gen.c);
- данные для дизассемблирования передаются через С-style streams;
- код покрыт юнит тестами;
Недостатки:
- маловато комментариев и документации;
- пока нет поддержки x64;
- 16 bit режим есть, но тестами пока не покрыт;
- не поддерживаются всякие расширения: FPU, SIMD, MMX - не было необходимости, пока;
Код написан в свободное от основной работы время, и выложен под BSD лицензией, вдруг кому еще пригодится.
Пример использования:
/* TEST 1
8195e9d7 f00fb116 lock cmpxchg [esi],edx 81881dc5 c1e902 shr ecx,0x2 81881db0 f3a5 rep movsd */
unsigned char buf[] = {0xf0, 0x0f, 0xb1, 0x16, 0xc1, 0xe9, 0x02, 0xf3, 0xa5};
DianaParserResult result; DianaGroupInfo * pGroupInfo = 0; size_t cmdSize = 0; int iRes = 0;
DianaContext context; DianaMemoryStream stream;
Diana_InitContext(&context, DIANA_MODE32);
// init stream over memory Diana_InitMemoryStream(&stream, buf, sizeof(buf));
iRes = Diana_ParseCmd(&context, Diana_GetRootLine(), // all database &stream.parent, // OOP in C :) &result); cmdSize = stream.curSize - context.iReadedSize;
TEST_ASSERT_IF(!iRes) { TEST_ASSERT(result.iLinkedOpCount==2); TEST_ASSERT(result.pInfo->m_operandCount ==2); TEST_ASSERT(pGroupInfo = Diana_GetGroupInfo(result.pInfo->m_lGroupId)); TEST_ASSERT(strcmp(pGroupInfo->m_pName, "cmpxchg")==0); TEST_ASSERT(result.linkedOperands[0].type == diana_index); TEST_ASSERT(result.linkedOperands[0].value.rmIndex.seg_reg == reg_DS); TEST_ASSERT(result.linkedOperands[0].value.rmIndex.reg == reg_ESI); TEST_ASSERT(result.linkedOperands[0].value.rmIndex.indexed_reg == reg_none); TEST_ASSERT(result.linkedOperands[0].value.rmIndex.index == 0); TEST_ASSERT(result.linkedOperands[0].value.rmIndex.dispSize == 0); TEST_ASSERT(result.linkedOperands[0].value.rmIndex.dispValue == 0);
TEST_ASSERT(result.linkedOperands[1].type == diana_register); TEST_ASSERT(result.linkedOperands[1].value.recognizedRegister == reg_EDX);
TEST_ASSERT(result.iPrefix == DI_PREFIX_LOCK); }
|
_Winnie C++ Colorizer |
No comments:
Post a Comment