Сейчас на форуме: UniSoft, zds, ManHunter, rmn (+5 невидимых)

 eXeL@B —› Программирование —› Дизассемблер
<< . 1 . 2 .
Посл.ответ Сообщение

Ранг: 112.9 (ветеран), 186thx
Активность: 0.090.01
Статус: Участник

Создано: 24 апреля 2011 11:03 · Поправил: vden
· Личное сообщение · #1

Добрый день.

Я планирую написать небольшой дизассемблер + gui, с подключением плагинов через dll. Это велосипед, но всё таки хотелось бы иметь свой дизасм, который я смогу при желании править.

Составляя диздок, наткнулся на спорные моменты, которые вы возможно поможете мне решить.

1. основная проблема: как хранить исследуемую базу, учитывая что должны поддерживаться стат. браузинг и браузинг памяти (при отладке), с сохранением имён локаций и возможно др. метаданных.
у меня 2 варианта:
1а. на каждый байт свой дескриптор, (т.е. описывает код,данные,др) идеально для стат. браузера, но при браузинге памяти как-то cложно т.к. памяти может занять очень много
1б. на каждый регион памяти свой дескриптор, идеально для браузинга памяти, для стат. бр. но при больших регионах. При маленьких регионах опять сложность: (попробуйте например в ida создать мегабайт однотипных оч. маленьких структур)

т.к. обычно не бывает оч.много мелких структур, я склоняюсь ко второму варианту, плюс он экономнее по объёмам памяти в общих случаях, но всё-таки хочется узнать мнение кодеров со скиллом возможно есть что-то проще и эффективнее?
думал над гибридным методом, но мне кажется это плохая идея.

решено

2. на чём писать? определённые наработки есть и на C и на Pascal, пытаюсь решить к чему-то одному это привести.
штука довольно узкопрофильная, тут думаю не так важно на чём. ядро планирую в виде dll (msvc или delphi/fpc), gui либо delphi/fpc, либо qt, кросплатформенность мне не нужна, поэтому тут пока остановился на delphi, т.к. gui контролы пишутся очень легко и быстро. если у кого есть опыт создания виджетов в qt, просветите насколько это проще/сложнее чем delphi.

решено.




Ранг: 990.2 (! ! !), 380thx
Активность: 0.680
Статус: Модератор
Author of DiE

Создано: 25 апреля 2011 17:08
· Личное сообщение · #2

как-то так
Code:
  1. hbase     := myLoadLibrary(ppath);
  2. pPEHeader := PImageNtHeaders(hbase + PImageDosHeader(hbase)._lfanew);


-----
[nice coder and reverser]





Ранг: 355.4 (мудрец), 55thx
Активность: 0.320
Статус: Uploader
5KRT

Создано: 25 апреля 2011 17:11 · Поправил: Coderess
· Личное сообщение · #3

Помоему так, аналогично в делфи
Code:
  1. var
  2. pdh: PIMAGE_DOS_HEADER;
  3. pNt: PIMAGE_NT_HEADERS;
  4. begin
  5. pdh := PIMAGE_DOS_HEADER(pImage.hModule);
  6. pNt := PIMAGE_NT_HEADERS(Longint(pdh) + pdh.e_lfanew);


// сори, опередили

-----
Gutta cavat lapidem. Feci, quod potui. Faciant meliora potentes




Ранг: 112.9 (ветеран), 186thx
Активность: 0.090.01
Статус: Участник

Создано: 25 апреля 2011 17:17 · Поправил: vden
· Личное сообщение · #4

DenCoder пишет:
vden пишет:Кстати, ещё вопрос как вы считаете макс. 65536 типов данных в одной базе будет достаточно или избыточно? Не понимаю, о чём Вы. Вы знаете, что такое динамические структуры данных?

Я говорю о тех типах, что вы накапливаете когда реверсите довольно большой проект. У меня больше 1000 никогда не получалось. Приаттачил небольшой пример дескриптора.
Там Data Identifier определяет какому типу принадлежит данный байт. Так скорость выборки из базы будет ограничена только временем подрузки с hdd в память текущего куска базы.
Но это хорошо только если рассматриваемый байт в базе, а не замаппен из памяти.
Вообще мне кажется можно сделать проще и универсальней, пока не понял как.

Пока наверно, это всё выглядит ересью. Позже составлю простой док, его можно будет уже поанализировать.

PS не стоит ЯП меряться, оба сойдут, вопрос в том, что для С кодобаза больше, хотя в данном случае это не играет большой роли.

В любом случае проектировать нужно так чтобы заголовки были доступны и для C и для Pascal.

539e_25.04.2011_EXELAB.rU.tgz - Flags.htm



Ранг: 112.9 (ветеран), 186thx
Активность: 0.090.01
Статус: Участник

Создано: 25 апреля 2011 18:00 · Поправил: vden
· Личное сообщение · #5

UPD. Удалил, т.к. много мусора.




Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 25 апреля 2011 19:21 · Поправил: PE_Kill
· Личное сообщение · #6

Си
Code:
  1. IMAGE_DOS_HEADER* pdh;
  2. IMAGE_NT_HEADERS* pNt;
  3.  
  4. pdh = (IMAGE_DOS_HEADER*)pImage->hModule;
  5. pNt = (IMAGE_NT_HEADERS*)(pImage->hModule + pdh->e_lfanew);


Delphi
Code:
  1. var
  2.   pdh: PIMAGE_DOS_HEADER;
  3.   pNt: PIMAGE_NT_HEADERS;
  4. begin
  5.   pdh := PIMAGE_DOS_HEADER(pImage^.hModule);
  6.   pNt := PIMAGE_NT_HEADERS(pImage^.hModule + pdh^.e_lfanew);
  7. end;


Найди отличия.

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

-----
Yann Tiersen best and do not fuck





Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 25 апреля 2011 19:57 · Поправил: DenCoder
· Личное сообщение · #7

vden пишет:
Там Data Identifier определяет какому типу принадлежит данный байт

Какому типу принадлежат 2-ой байт в инструкции mov eax, 0x01000000 и 3-ий байт в инструкции mov edx, [ecx * 2 + edi + 0x01004580]?

Вы собираетесь выделить под все возможные типы место сразу. Еще раз - Вы знаете, что такое динамические структуры данных? Типы и их описание в структурах можно динамически создавать, используя односвязный список. Адрес объекта типа как ключ в мапе, значением ключа - указатель на стуктуру-описатель типа. При хранении же типов в файле идеально было бы указать хэдер, в котором размер блока типов, смещение к нему, а блок типов в свою очередь может начинаться со своего хэдера, в котором число типов и массив смещений к ним в файле. Ничего нового - всё от IMAGE_DIRECTORY_ENTRY_IMPORT, IMAGE_IMPORT_DESCRIPTOR, этого вполне достаточно!

О, что бы было с виндой, если б в PE-формате тоже отвели место под весь возможный экспорт и импорт...

PE_Kill пишет:
Найди отличия.

ОК ОК...
Найди отличия

Дельфи
Code:
  1. var
  2.   pdh: PIMAGE_DOS_HEADER;
  3.   pNt: PIMAGE_NT_HEADERS;
  4. begin
  5.   pdh := PIMAGE_DOS_HEADER(pImage^.hModule);
  6.   pNt := PIMAGE_NT_HEADERS(pImage^.hModule + pdh^.e_lfanew);
  7. end;


Си
Code:
  1. IMAGE_DOS_HEADER* pdh = (IMAGE_DOS_HEADER*)pImage->hModule;
  2. IMAGE_NT_HEADERS* pNt = (IMAGE_NT_HEADERS*)(pImage->hModule + pdh->e_lfanew);



Ладно, в общем PE_Kill вроде прав, сдаюсь.

-----
IZ.RU





Ранг: 355.4 (мудрец), 55thx
Активность: 0.320
Статус: Uploader
5KRT

Создано: 25 апреля 2011 20:31 · Поправил: Coderess
· Личное сообщение · #8

PE_Kill Код немного поправленный из \Borland\Delphi6\Demos\ResXplor\ExeImage.pas

Code:
  1. { TExeImage }
  2.  
  3. constructor TExeImage.CreateImage(AOwner: TComponent; const AFileName: string);
  4. begin
  5.   inherited Create(AOwner);
  6.   FFileName := AFileName;
  7.   FFileHandle := CreateFile(PChar(FFileName), GENERIC_READ, FILE_SHARE_READ,
  8.     nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  9.   if FFileHandle = INVALID_HANDLE_VALUE then ExeError('Couldn''t open: '+FFileName);
  10.     FFileMapping := CreateFileMapping(FFileHandle, nil, PAGE_READONLY, 0, 0, nil);
  11.   if FFileMapping = 0 then ExeError('CreateFileMapping failed');
  12.     FFileBase := MapViewOfFile(FFileMapping, FILE_MAP_READ, 0, 0, 0);
  13.   if FFileBase = nil then ExeError('MapViewOfFile failed');
  14.     FDosHeader := PIMAGE_DOS_HEADER(FFileBase);
  15.   if not FDosHeader.e_magic = IMAGE_DOS_SIGNATURE then
  16.     ExeError('unrecognized file format');
  17.   FNTHeader := PIMAGE_NT_HEADERS(Longint(FDosHeader) + FDosHeader.e_lfanew);
  18.   if IsBadReadPtr(FNTHeader, sizeof(IMAGE_NT_HEADERS)) or
  19.      (FNTHeader.Signature <> IMAGE_NT_SIGNATURE) then
  20.     ExeError('Not a PE (WIN32 Executable) file');
  21.  end;


-----
Gutta cavat lapidem. Feci, quod potui. Faciant meliora potentes





Ранг: 793.4 (! !), 568thx
Активность: 0.740
Статус: Участник
Шаман

Создано: 25 апреля 2011 20:54
· Личное сообщение · #9

Это явно не в борланде кодили, т.к. хедер не борландовский используется. Я когда то изучал работу с ресурсами на этой демке.

-----
Yann Tiersen best and do not fuck




Ранг: 251.3 (наставник), 81thx
Активность: 0.140.11
Статус: Участник

Создано: 25 апреля 2011 22:13
· Личное сообщение · #10

Насчёт приведения типов - согласен с PE_Kill, разницы нет.
Но лично моё мнение - писать надо на Си, и не из-за синтаксиса.
Покажите мне Delphi, который в x64 умеет собирать к примеру.




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 25 апреля 2011 22:36
· Личное сообщение · #11

Заканчивали бы языками меряться, тема не туда идёт. И тестирование х64 версии дельфей начато было уже несколько недель назад. Другой вопрос, что язык да, менее гибкий.
Посты не по теме стирать буду.



Ранг: 39.6 (посетитель), 21thx
Активность: 0.020
Статус: Участник

Создано: 26 апреля 2011 06:03
· Личное сообщение · #12

Jupiter пишет:
Вот примеры инструкций для теста:mediana/files/tests.bin

маразм это, а не тест

vden пишет:
У меня больше 1000 никогда не получалось.

а что ты вообще подразумеваешь под типами ?

по моему скромному мнению есть код, есть данные (в трюках могут быть использованы данные как код, код как данные, но это отдельная песня)

типы данных стандартны: byte (sign/unsign), word(s/u), .и т.д. + структуры (= надстройка над стандартными типами), + массивы ( = надстройка над типами / структурами)
итого получается некая иерархическая система

но откуда 1000 штук ? каждая структура/массив считается за отдельный тип ?
с таким подходом для кода можно за тип считать функцию, тогда и 0xFFFF штук может не хватить

это похоже на примеры тестов от Юпитера - сделать ох*ый файл на все-все-всевозможные команды вместо тестирования опкодов и адресации.




Ранг: 605.2 (!), 341thx
Активность: 0.470.25
Статус: Модератор
Research & Development

Создано: 26 апреля 2011 08:04
· Личное сообщение · #13

Sen
Я дал ссылку на пример инструкций, отвечая на фразу Usulgurt: "Я офигел когда увидел, что он проходит тест на 4000 разношорстные инструкции. Вплоть до криптоинструкций и использования регистра tr0, о которых в мануале интела не написано что-то"

это похоже на примеры тестов от Юпитера
Ты так говоришь, будто это мои тесты ;) Ссылка на сайт хиева не делает хиев моим :D

Sen, так ты выложи свои тесты для проверки движка дизассемблера, у тебя же немалый опыт в этой области.

-----
EnJoy!




Ранг: 112.9 (ветеран), 186thx
Активность: 0.090.01
Статус: Участник

Создано: 26 апреля 2011 16:37 · Поправил: vden
· Личное сообщение · #14

sen пишет:
а что ты вообще подразумеваешь под типами ?

подразумеваю стандартный набор (intы/uintы/floatы) + пользовательские структуры.

Jupiter пишет:
по моему скромному мнению есть код, есть данные (в трюках могут быть использованы данные как код, код как данные, но это отдельная песня)

с этим не поспоришь)

sen пишет:
но откуда 1000 штук ? каждая структура/массив считается за отдельный тип ?с таким подходом для кода можно за тип считать функцию, тогда и 0xFFFF штук может не хватить

структура да, массив нет. массив считается просто вектором одного типа. но структура может содержать элементы одного типа идущие подряд. это может быть не оптимально, но по усмотрению пользователя.

сам код можно считать подвидом данных с переменной длиной

за тип считать функцию идея хорошая) что-то вроде appcall в иде.
но функции сюда лучше не включать

1000 я взял условно, пусть максимум 2^16, исследую к примеру игрушку на win32+d3d8+ws32, импортирую нужные типы, создаю свои, в итоге кол-во типов в базе небольшое.




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 26 апреля 2011 17:36 · Поправил: DenCoder
· Личное сообщение · #15

vden пишет:
пусть максимум 2^16

Вам он нужен? В редких случаях сами ограничиваете себя, в большинстве - слишком много места.

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

--> Списки <--
--> Ассоциативные массивы(деревья) <--
--> Множества <--

--> std::map(англ) <--

-----
IZ.RU




Ранг: 17.4 (новичок)
Активность: 0.020
Статус: Участник

Создано: 26 апреля 2011 19:06 · Поправил: Usulgurt
· Личное сообщение · #16

Вот ссылка на тест, которые можно погонять в дизасме:
AES инструкции там тоже есть, но повторюсь, что разношёрстных тестовых строчек там 4148 Как для x86_32 так и для x86_64.

http://beye.cvs.sourceforge.net/viewvc/beye/biew/testlab/disasm/x86/

И ещё вот нашёл инструкции, о которых даже Гугл не особо распространяется.

public padlock:
L0000056B: xstore-rng ; 0FA7C0
L0000056E: xstore-rng ; 0FA7C0
L00000571: rep; xcryptecb ; F30FA7C8
L00000575: rep; xcryptcbc ; F30FA7D0
L00000579: rep; xcryptctr ; F30FA7D8
L0000057D: rep; xcryptcfb ; F30FA7E0
L00000581: rep; xcryptofb ; F30FA7E8
L00000585: rep; montmul ; F30FA6C0
L00000589: rep; xsha1 ; F30FA6C8
L0000058D: rep; xsha256 ; F30FA6D0
L00000591: leave ; C9
L00000592: retn ; C3



Ранг: 112.9 (ветеран), 186thx
Активность: 0.090.01
Статус: Участник

Создано: 26 апреля 2011 19:54
· Личное сообщение · #17

Ок, ребята, спасибо за подсказки. Пока буду прорабатывать свой замысел.
Тему пока, не закрываю. Думаю ещё будет что обсудить.




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 26 апреля 2011 20:51
· Личное сообщение · #18

Usulgurt
Добавлю, что поддержка AES не у всех процессоров. В основном это некоторые ксеоны, Core i5 и Core i7. VMWare 7 не поддерживает их. Не имея поддержку, дизасм написать можно, но проверить анализатор будет очень трудно.

-----
IZ.RU




Ранг: 112.9 (ветеран), 186thx
Активность: 0.090.01
Статус: Участник

Создано: 04 марта 2012 01:50 · Поправил: vden
· Личное сообщение · #19

Почти нет времени нормально заняться дизасмом.
Пока заморожено.


<< . 1 . 2 .
 eXeL@B —› Программирование —› Дизассемблер
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати