Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет nancygold ([info]nancygold)
@ 2024-07-02 20:04:00


Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Настроение: amused
Entry tags:computing

Using Ghidra's Decompiler with IDA
Since IDA doesn't support decompiling the 16bit x86 code, people are using Ghidra's decompiler with it:
https://github.com/airbus-cert/Yagi

That Yagi BTW adds decompilation support even to freeware IDA.

Still that decompiler uses Ghidra's analyzer, which tends to fail on a few specific cases of 16 bit code.
For example, when the IP-relative near call jumps to a NULL pointer, yet IDA's analyzer handles that without issues.
So it makes little sense to use it. Easier would be patching Ghidra to do analysis properly.
IDA is just obsolete nowadays. Especially when Ghidra got LLM integration.

ChatGPT outperforms any decompiler. In fact it can even do disassembly half-reliably.
Or 100% reliably if you run it in an agent mode, allowing to "proofread" its generation.
I.e. ChatGPT doesn't even need any analysis environment, outside of a simple database.

During my work, I asked ChatGPT to make me Ghidra python scripts, and it always succeeded with minor errors.
I.e. it forgot that Java bytes are signed, and therefore the Python code should accommodate for that.
Then again, it reliably fixes such bugs if in run in a loop.
So the future of reversing is just running ChatGPT repeatedly until it identifies all symbols,
and then dumps the C code.



(Добавить комментарий)


(Анонимно)
2024-07-03 00:12 (ссылка)
IDA прекрасно дизасмит 16-битный код.
Что за ерунду ты несешь? Причем и EXE, и COM, и даже COFF с OBJ и LIB. Может и в более редкие форматы может, типа TPU, нет не может в TPU. Проверил.

(Ответить) (Ветвь дискуссии)


[info]nancygold
2024-07-03 00:56 (ссылка)
>IDA прекрасно дизасмит 16-битный код.
Yes. But it doesn't decompile the 16bit x86.
So if your goal is to recover huge executable, Ghidra is the only option.

Yet Ghidra has a few analysis related issues.
These can be fixed by either patching it or by running Python scripts.
Yet you can't patch IDA, which is closed source and its API is limited.

Here is the Python script I wrote to fix the Ghidra's near call references.
#### This script fixes misgenerated near call references ####
from ghidra.program.model.symbol import RefType, SourceType

# Required to add references
reference_manager = currentProgram.getReferenceManager()

def ubytes(bs):
  return map(lambda b: b & 0xff, bs)

def fix_near_calls():
  instructions = currentProgram.getListing().getInstructions(True)
  while instructions.hasNext():
      instruction = instructions.next()
      if instruction.getMnemonicString() == "CALL" and instruction.getDefaultOperandRepresentation(0).startswith("0x"):
        ibs = ubytes(instruction.getBytes())
        if ibs[0] == 0xE8:
          call_address = instruction.getAddress()
          cseg = call_address.getSegment()
          cofs = call_address.getSegmentOffset()
          disp = ibs[2]*0x100 + ibs[1]
          proper_ofs = (cofs+3 + disp)&0xFFFF
          refs = getReferencesFrom(call_address)
          needs_fix = 0
          for ref in refs:
            if ref.getReferenceType().toString() == "UNCONDITIONAL_CALL":
              adr = ref.getToAddress()
              seg = adr.getSegment()
              ofs = adr.getSegmentOffset()
              fadr = ref.getFromAddress()
              fseg = fadr.getSegment()
              fofs = fadr.getSegmentOffset()
              if seg != cseg or ofs != proper_ofs: needs_fix = 1
          if needs_fix:
            # Likely all references are invalid
            for ref in refs: removeReference(ref)
            # Create the correct reference
            proper_adr = toAddr((cseg << 4) + proper_ofs)
            reference_manager.addMemoryReference(call_address, proper_adr, RefType.UNCONDITIONAL_CALL, SourceType.USER_DEFINED, 0)

fix_near_calls()

(Ответить) (Уровень выше) (Ветвь дискуссии)


(Анонимно)
2024-07-03 01:22 (ссылка)
IDA прекрасно все показывает, и CALL'ы и Jxx инструкции (если экзешник не пошифрован, что под DOS/Win3.x вообще-то редкость). Или тебе надо такое чудо, чтоб тебе не ассемблерный листинг, а сразу рабочий код на плюсах или поскакале? Ну у вас, батенька, и желания... Такое тебе даже инопланетяне не сделают.

Единственный минус анализа программ под DOS, IDA бывает довольно криво работает с оверлеями (.OVL), особенно если оверлей впихан в экзешник (тупо дописан в конец EXE-файла), как в одной из систем СКБ "Контур", ну и если экзешник упакован, то надо его предварительно распаковать, но тех упаковщиков под DOS было штук 20, с ними обычно UNEXE справлялся в автоматическом режиме.

А всяких VM под DOS я тоже не припомню, либо сразу в бинарь компилировали, либо это скрипт был на каком-нибудь бейсике (но тут и декомпилировать не надо).

Ах да, IDA иногда давилась, если была программа защищенного режима с расширителем типа DOS/4GW или Rational, но это вроде как пофиксили, хотя я просто не дизасмил такие программы, не надо было.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]nancygold
2024-07-03 01:33 (ссылка)
As I said, IDA can't decompile 16bit executables, and therefore useless.

(Ответить) (Уровень выше) (Ветвь дискуссии)


(Анонимно)
2024-07-03 01:39 (ссылка)
А что ты понимаешь под декомпиляцией? Получение исходного кода сразу на языке высокого уровня?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]nancygold
2024-07-03 02:05 (ссылка)
C code, which I can post into a .c file and compile.
Preferably with for loops and if/else statements.
Even better if recovery of template classes is possible.

(Ответить) (Уровень выше) (Ветвь дискуссии)


(Анонимно)
2024-07-03 02:33 (ссылка)
Ну такое, извините, сделать довольно сложно. Под винду можно, если компилятор компилировал не в бинарь, а в псевдокод, как у C#, Java, VB 6.0. Частично еще с Delphi такое можно было сделать - утилитой Delphi Decompiller, она стандартные функции распознавала и паттерны циклов и ветвлений, а вот для анализа DOS'ового софта такого и быть-то не может, если это не Paradox какой-нибудь, которая да, СУБД, предшественник VM, или не игра DOOM - где все в WAD-файле, а экзешник типа интерпретатор по сути дела.

Тут две проблемы - техническая, т.е. под DOS было вагон компиляторов, одних C было штук шесть (Watchcom, Borland, и т.д.), еще столько же Паскалей, три популярных ассемблера (FASM, TASM, MASM), развеселая тележка бейсиков (именно компиляторов). Так что чтобы восстановить код нужна база данных размером с галактику.

Вторая проблема - математическая, компилятор мог запускаться с разными опциями (это обычно у C), или вообще оптимизировать код не спрашивая программиста, как ему придет в голову, в зависимости от погоды на Юпитере и того, опохмелился автор компилятора, или в день релиза с бодуна пришел на работу.

Т.е. низкоуровневый код нельзя однозначно преобразовать (в большинстве случаев), в высокоуровневый. Это вообще-то на первом курсе детям говорят, когда они на ассемблере разве что хелловорлд пишут.

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

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]nancygold
2024-07-03 12:12 (ссылка)
IDA allows decompilation only for 32bit code.
But not 16bit or 8bit architectures.
Ghidra supports decompiling even Brainfuck.

(Ответить) (Уровень выше) (Ветвь дискуссии)


(Анонимно)
2024-07-04 01:00 (ссылка)
Да декомпиляция это вообще дело такое хитрое, моя IDA не умеет, может более новая версия и умеет что-то похожее, впрочем мне особо и не надо, так что я последнюю версию не покупал, ИМХО она испортилась после версии 5.0, потом Ильфак удалил консольную версию, да и пошел он к татарскому шайтану.

(Ответить) (Уровень выше)


[info]nancygold
2024-07-03 12:24 (ссылка)
Here, a Ghidra decompiled a 16bit RLE encoder routine, no idea if it was originally in assembly or C, but the segment it resides was used in the game mostly for ex .asm files. Although Borland C++ allowed really easy to use inline assembly (compared to say GCC). It messes up the ES segment, but I think that is trivial to fix, given enough decompiler knowledge.

int rle_line(uint8_t *src,uint8_t *dst,uint16_t npixels) {
  uint8_t *puVar1;
  int iVar2;
  uint8_t *end;
  uint8_t *puVar3;
  uint8_t *pps;
  uint c;
  uint8_t *ps;
  uint8_t *pd;
  undefined2 uVar4;
  undefined2 uVar5;
  
  uVar5 = (undefined2)((ulong)src >> 0x10);
  puVar3 = (uint8_t *)src;
  end = puVar3 + npixels;
  uVar4 = (undefined2)((ulong)dst >> 0x10);
  ps = puVar3;
  pd = (uint8_t *)dst;
LAB_2d63_0343:
  do {
    c = (int)end - (int)ps;
    if (0x7f < c) {
      c = 0x80;
    }
    pps = ps;
    do {
      pps = pps + 1;
      if (ps + c <= pps) break;
    } while (*ps == *pps);
    c = (int)pps - (int)ps;
    if (c < 3) {
      ps = ps + 1;
      iVar2 = (int)ps - (int)puVar3;
      if (((byte)iVar2 < 0x80) && (ps < end)) goto LAB_2d63_0343;
      *pd = (byte)iVar2 - 1;
      for (; pd = pd + 1, iVar2 != 0; iVar2 = iVar2 + -1) {
        puVar1 = puVar3;
        puVar3 = puVar3 + 1;
        *pd = *puVar1;
      }
    }
    else {
      if (puVar3 != ps) {
        iVar2 = (int)ps - (int)puVar3;
        *pd = (char)iVar2 + 0xff;
        for (; pd = pd + 1, ps = puVar3, iVar2 != 0; iVar2 = iVar2 + -1) {
          puVar1 = puVar3;
          puVar3 = puVar3 + 1;
          *pd = *puVar1;
        }
      }
      puVar3 = pd + 1;
      *pd = 0x1 - (char)c;
      pd = pd + 2;
      *puVar3 = *ps;
      puVar3 = ps + c;
    }
    ps = puVar3;
    if (end <= puVar3) {
      return (int)pd - (int)(uint8_t *)dst;
    }
  } while( true );
}

(Ответить) (Уровень выше) (Ветвь дискуссии)


(Анонимно)
2024-07-04 01:06 (ссылка)
Ну т.е. почитать сишный код можно, но отлаживать придется все равно ручками, копировать-вставить не получится, о чем я и говорил. Против математики не попрешь.

(Ответить) (Уровень выше)


[info]nancygold
2024-07-03 12:34 (ссылка)
Here is what ChatGPT did
#include <stdint.h>
#include <stddef.h>

size_t rle_line(const uint8_t *src, size_t src_len, uint8_t *dst) {
    const uint8_t *end = src + src_len;
    uint8_t *dst_start = dst;
    
    while (src < end) {
        const uint8_t *run_start = src;
        const uint8_t *run_end = src + (src_len < 0x80 ? src_len : 0x80);

        // Find the end of the run
        uint8_t first_byte = *src;
        ++src;
        while (src < run_end && *src == first_byte) {
            ++src;
        }

        size_t run_length = src - run_start;

        if (run_length >= 3) {
            // Write the RLE encoded bytes
            *dst++ = 0x80 | (run_length - 1);
            *dst++ = first_byte;
        } else {
            // Write the literal bytes
            if (dst - dst_start + run_length + 1 >= src_len) {
                break; // Prevent buffer overflow
            }

            *dst++ = run_length - 1;
            for (size_t i = 0; i < run_length; ++i) {
                *dst++ = *run_start++;
            }
        }
    }

    return dst - dst_start;
}





PROMPT:
Please convert the below routine to clean literate programming style C99.

 rle_line
   PUSH          BP
   MOV           BP,SP
   PUSH          SI
   PUSH          DI
   PUSH          DS=>DAT_0000_2410
   PUSH          ES
   PUSH          BP
   CLD
   LDS           SI,[BP + 0x6]
   MOV           BX,SI
   MOV           DX,word ptr [BP + 0xe]
   ADD           end,SI
   LES           DI,[BP + 0xa]
 LAB_2d63_0343
   MOV           BP,SI
   MOV           CX,DX
   SUB           CX,SI
   CMP           CX,0x80
   JC            LAB_2d63_0352
   MOV           CX,0x80
 LAB_2d63_0352
   ADD           CX,SI
   MOV           AL,byte ptr [SI]
 LAB_2d63_0356
   INC           pps
   CMP           SI,CX
   JNC           LAB_2d63_035f
   CMP           AL,byte ptr [SI]
   JZ            LAB_2d63_0356
 LAB_2d63_035f
   SUB           c,BP
   XCHG          BP,SI
   CMP           BP,0x3
   JC            LAB_2d63_038d
   CMP           BX,SI
   JZ            LAB_2d63_037b
   MOV           CX,SI
   SUB           CX,BX
   MOV           AL,CL
   DEC           AL
   STOSB         ES:DI
   MOV           SI,BX
   MOVSB.REP     ES:DI,SI
   MOV           BX,SI
 LAB_2d63_037b
   MOV           AL,0x1
   SUB           AX,BP
   STOSB         ES:DI
   MOV           AL,byte ptr [SI]
   STOSB         ES:DI
   ADD           SI,BP
   MOV           BX,SI
   CMP           SI,DX
   JC            LAB_2d63_0343
   JMP           LAB_2d63_03aa
 LAB_2d63_038d
   INC           ps
   MOV           CX,SI
   SUB           CX,BX
   CMP           CL,0x80
   JNC           LAB_2d63_039b
   CMP           SI,DX
   JC            LAB_2d63_0343
 LAB_2d63_039b
   MOV           AL,CL
   DEC           AL
   STOSB         ES:DI
   MOV           SI,BX
   MOVSB.REP     ES:DI,SI
   MOV           BX,SI
   CMP           SI,DX
   JC            LAB_2d63_0343
 LAB_2d63_03aa
   MOV           AX,DI
   POP           BP
   SUB           AX,word ptr [BP + 0xa]
   POP           ES
   POP           DS
   POP           DI
   POP           SI
   POP           BP
   RETF

(Ответить) (Уровень выше) (Ветвь дискуссии)


(Анонимно)
2024-07-04 01:01 (ссылка)
И оно работает? Или так, кому-то сложно читать ассемблерный листинг?

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]nancygold
2024-07-04 01:36 (ссылка)
Yes.

(Ответить) (Уровень выше) (Ветвь дискуссии)


(Анонимно)
2024-07-04 03:29 (ссылка)
К сожалению, ваши слова проверить не могу, т.к. не сишник. Я по ассемблеру или СУБД, ну или Поскакалю, но верю - помогло, так помогло, видимо, этот самый чат что-то может, чего бы и нет, это большой словарь с ускоренным поиском, который крутится на суперкомпьютере.

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]nancygold
2024-07-04 11:06 (ссылка)
ChatGPT makes less errors than a human.
And corrects itself successfully if provided with debugging result.

So it is already super human in a few dimensions.

>это большой словарь с ускоренным поиском, который крутится на суперкомпьютере.

You can say the same about your brain, if you discard emotions.

(Ответить) (Уровень выше) (Ветвь дискуссии)


(Анонимно)
2024-07-04 16:00 (ссылка)
>And corrects itself successfully if provided with debugging result.
What model do you use? Gpt-4 turbo or 4o?

(Ответить) (Уровень выше)


(Анонимно)
2024-07-04 03:34 (ссылка)
Но все равно, проверяйте все ручками, аккуратно отлаживайте, а то можно нарваться на какой-нибудь подводный камень, автоматический анализ - хорошо, потому что делает рутинную работу за нас, но и голову включать надо.

(Ответить) (Уровень выше)


[info]ololo
2024-07-04 16:47 (ссылка)
"Да. На оба вопроса - да". Великий философ умел быть лаконичным.

(Ответить) (Уровень выше)


(Анонимно)
2024-07-03 02:45 (ссылка)
Т.е. проблема не в IDA или Гидре, проблема в математике и технике, лыжи, они, знаете ли, довольно плохо едут по асфальту.

(Ответить) (Уровень выше)


[info]nancygold
2024-07-03 00:58 (ссылка)
>нет не может в TPU. Проверил.

Surprising given the popularity of Delphi in Russia.

(Ответить) (Уровень выше) (Ветвь дискуссии)


(Анонимно)
2024-07-03 01:30 (ссылка)
Та это еще даже не Дельфи, формат с Трупопоскакаля тянется. Впрочем, я так полагаю, просто никому не надо было - обычно к TPU-шке документация шла, или исходник. Хотя, возможно, какие-то другие инструменты для анализа TPU и были, но на практике я не сталкивался, хоть и довольно старый дед, который еще ЕС и БК помнит.

(Ответить) (Уровень выше)