Дизассемблированная программа кардинально отличается от исходника?

Тема в разделе "WASM.HEAP", создана пользователем device, 8 ноя 2007.

  1. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    Сегодня откомпилил такой код:

    Код (Text):
    1. segment "main"
    2. STATS db "I am first GNU JAVA APPLICATION with assembler code!!!"  
    3. st_length db $-STATS
    4. main:
    5.     lea eax, [STATS]
    6.     push eax
    7.     mov ebx, 1
    8.     mov edx, st_length
    9.     int 32h
    10.     ret
    11. section "header"
    12.  
    13.  
    14.  
    15.  
    16. section "EntryPoint"
    17.  
    18.     jmp main
    19.    
    20. segment "ClassLoader"
    Раздизасмил его и получил ЭТО:
    Код (Text):
    1. 00000000  49                dec cx
    2. 00000001  20616D            and [bx+di+0x6d],ah
    3. 00000004  206669            and [bp+0x69],ah
    4. 00000007  7273              jc 0x7c
    5. 00000009  7420              jz 0x2b
    6. 0000000B  47                inc di
    7. 0000000C  4E                dec si
    8. 0000000D  55                push bp
    9. 0000000E  204A41            and [bp+si+0x41],cl
    10. 00000011  56                push si
    11. 00000012  41                inc cx
    12. 00000013  204150            and [bx+di+0x50],al
    13. 00000016  50                push ax
    14. 00000017  4C                dec sp
    15. 00000018  49                dec cx
    16. 00000019  43                inc bx
    17. 0000001A  41                inc cx
    18. 0000001B  54                push sp
    19. 0000001C  49                dec cx
    20. 0000001D  4F                dec di
    21. 0000001E  4E                dec si
    22. 0000001F  207769            and [bx+0x69],dh
    23. 00000022  7468             jmp 0x0c
    24. 00000024  206173            and [bx+di+0x73],ah
    25. 00000027  7365              jnc 0x8e
    26. 00000029  6D                insw
    27. 0000002A  626C65            bound bp,[si+0x65]
    28. 0000002D  7220              jc 0x4f
    29. 0000002F  636F64            arpl [bx+0x64],bp
    30. 00000032  652121            and [gs:bx+di],sp
    31. 00000035  2136668D          and [0x8d66],si
    32. 00000039  06                push es
    33. 0000003A  0000              add [bx+si],al
    34. 0000003C  6650              push eax
    35. 0000003E  66BB01000000      mov ebx,0x1
    36. 00000044  66BA36000000      mov edx,0x36
    37. 0000004A  CD32              int 0x32
    38. 0000004C  C3                ret
    39. 0000004D  0000              add [bx+si],al
    40. 0000004F  00E9              add cl,ch
    41. 00000051  E4FF              in al,0xff
    Я так понял, что самое интересное начинается с 0000003A.
    До этого идет db.... Все бы ничего... но посмотрите на строку 0x22 -- там же безусловный переход на 0x0c! странно, но код работает... хотя на строки 22 он должен по идее зациклиццо.... или чего то не понимаю?
     
  2. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    С нулевого смещения начинается символьная строка, а отнюдь не выполняемый машинный код. Просто примитивный дизассемблер не способен одно от другого отличить (а умный, вроде ИДА Про, не всегда способен). А собственно код программы main начинается вроде с 36.
     
  3. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    device
    по идее зациклиццо
    Разве? А как же
    Код (Text):
    1. section "EntryPoint"
    2.     jmp main
    3. ...
    4. 00000050 E9  FFE4 ;; jmp main
    device > самое интересное начинается с 0000003A
    SII > А собственно код программы main начинается вроде с 36
    Imho в строке STATS 54 байта + 1 байт st_length итого 55, т.е. 000037h.
    Код (Text):
    1. 00000037 66 8D 06 0000   lea eax, [STATS]
    66h потому что сегмент кода 16-тибитный, а регистр 32-ухбитный.
     
  4. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    .... кстати, чем сегмент отличается от секции, и зачем они бывают нужны? В доках GCJ этого нет - там конкретные примеры кода (типо разбирайтесь сами). Просто ради интереса.
     
  5. nitrotoluol

    nitrotoluol New Member

    Публикаций:
    0
    Регистрация:
    5 сен 2006
    Сообщения:
    848
    Сегмент - это область памяти, используемая при логической адресации,
    секция сегмента - это часть кода, описывающая сегмент, принадлежащий программе (code, data, stack), а сегментные регистры (cs, ds, es, ss, fs, gs) - это хранители селекторов
     
  6. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    Как это выглядит в проге?
    После дизассемблирования, я не увидел мест, где могли бы находится EntryPoint, Main, ClassLoader и др.

    [​IMG]
     
  7. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    device
    В доках GCJ этого нет - там конкретные примеры кода
    Ссылку на докуменацию, пожалуйста.
     
  8. halyavin

    halyavin New Member

    Публикаций:
    0
    Регистрация:
    13 май 2005
    Сообщения:
    252
    Адрес:
    Russia
    А GCJ что, JNI не поддерживает? Если нет, то в топку его.
     
  9. reverser

    reverser New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2004
    Сообщения:
    615
    Емнимс, GCJ компилирует в нативный код, а не байткод.
     
  10. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    GCJ для связи с другими приложениями использует CNI (Compiled Native Interface)
    Но я нашел еще один способ.
    Я беру на себя ответственность продемонстрировать, как можно
    средствами GCJ вставлять ассемблерный код в Java-программы.
    И так, по порядку.

    1. Создадим программу на Java

    Код (Text):
    1. public class ATest{
    2.  
    3. public static void main (String[] args){
    4.  
    5. // 3. Вызовем этот метод
    6.  
    7. new ATest().EXEC_ASSEMBLER_CODE();
    8.  
    9. }
    10.  
    11. public void EXEC_ASSEMBLER_CODE(){
    12. // 2. Создадим метод с интригующим названием, но оставим его пустым.
    13.  
    14. }
    15.  
    16. }
    В принципе, такая программа не делает ничего.

    Как же вставить код на ASM в JAVA?
    Вызовем GCJ с параметром -S, чтобы заставить его распечатать в файл ассемблерный листинг программы
    Получим ATest.s
    Если внимательно посмотреть на листинг, то кроме изобилия коментариев, можно найти вызовы разных функций.
    Давайте отыщем нашу функцию "EXEC_ASSEMBLER_CODE" (Я специально обозвал её БОЛЬШИМИ БУКВАМИ).
    Код (Text):
    1. globl _ZN9checktool19EXEC_ASSEMBLER_CODEEv
    2.     .type   _ZN9checktool19EXEC_ASSEMBLER_CODEEv, @function
    3. _ZN9checktool19EXEC_ASSEMBLER_CODEEv:
    4. /** ТУТ НАЧИНАЕТСЯ ТЕЛО **/
    Товарищи дзенствующие, я думаю, что дальнейшие действия можно предугадать.

    Попробуем вывести на экран текстовую строку.
    Отыщем секцию .text (она на 1-2 строки выше и должна быть ПУСТОЙ)
    Впишем в эту секцию наше PREVED JAVA!:
    Код (Text):
    1. .text
    2. msg: .asciz "PREVED JAVA!\n"
    А теперь просто распечатаем ее на консоль.
    Для этого отыщем вход в тело функции и пропишем там ЭТО:) :
    Код (Text):
    1. pushl $msg
    2. call puts
    ВСЕ!
    теперь компилим
    > as ATest.s
    gcj -fmain=ATest -o atest -lc a.out //Мы не указали ассемблеру какой файл на выходе, но думаю что клиенты WASM исправят это...
    Запускаем прогу!
    Получаем
    >PREVED JAVA!

    >
    Пока не знаю, где это можно применять на практике, но буду исследовать дальше...
     
  11. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    только что удалось связать Java с паскалем...
     
  12. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    Вот более наглядный пример.

    Я написал его, чтобы дать возможность разобраться.
     
  13. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    я думал, будут отзывы....
     
  14. Guest

    Guest Guest

    Публикаций:
    0
    битый аттач.

    По поводу секций - если про секции PE то это просто области виртуальной памяти, нужны для разделения данных/кода по правам доступа к памяти, может еще чего-то.
     
  15. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    Да.... битый
     
  16. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    еще часть
     
  17. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    создайте каталог src/
     
  18. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    Ассемблерный код с впендюренной инструкцией
    (from Java (GNU) )
     
  19. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    Прога на паскале, которая вызывается из Java-программы вызовом call (AT&T Assembler)
     
  20. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    Сама Java-программа.

    Теперь выполните autoconf, потом ./configure, потом войдите в каталог src и выполните там make lib-compile, чтобы скомпилировать либу, lib-install, чтоб ее установить, app-compile, чтоб откомпилить прогу

    запустите ./gcjasm и вы увидите результат