असेंबली कोड प्राप्त करने के लिए लिनक्स में एक द्विआधारी निष्पादन योग्य कैसे अलग करें?


86

मुझे एक डिस्सेम्बलर का उपयोग करने के लिए कहा गया था। क्या gccकुछ भी में बनाया गया है? ऐसा करने का सबसे आसान तरीका क्या है?


और इसके बाद फिर से इकट्ठा करें: stackoverflow.com/questions/4309771/…
Ciro Santilli 病 after after after

संबंधित: जीसीसी / क्लैंग असेंबली आउटपुट से "शोर" कैसे निकालें? - यदि आप वास्तव में सिर्फ यह देखना चाहते हैं कि कंपाइलर ने क्या किया, तो आपको हमेशा + लिंक + डिसएम्बल को संकलित करने की आवश्यकता नहीं है।
पीटर कॉर्ड्स

जवाबों:


138

मुझे नहीं लगता कि gccइसके लिए कोई ध्वज है, क्योंकि यह मुख्य रूप से एक संकलक है, लेकिन एक अन्य GNU विकास उपकरण करता है। objdumpलेता है एक -d/ --disassembleध्वज:

$ objdump -d /path/to/binary

Disassembly इस तरह दिखता है:

080483b4 <main>:
 80483b4:   8d 4c 24 04             lea    0x4(%esp),%ecx
 80483b8:   83 e4 f0                and    $0xfffffff0,%esp
 80483bb:   ff 71 fc                pushl  -0x4(%ecx)
 80483be:   55                      push   %ebp
 80483bf:   89 e5                   mov    %esp,%ebp
 80483c1:   51                      push   %ecx
 80483c2:   b8 00 00 00 00          mov    $0x0,%eax
 80483c7:   59                      pop    %ecx
 80483c8:   5d                      pop    %ebp
 80483c9:   8d 61 fc                lea    -0x4(%ecx),%esp
 80483cc:   c3                      ret    
 80483cd:   90                      nop
 80483ce:   90                      nop
 80483cf:   90                      nop

9
इंटेल-सिंटैक्स के लिए objdump -Mintel -d:। या एग्नर फॉग के ओब्स्कॉन डिस्सेम्बलर सबसे अच्छा एक है जिसे मैंने अभी तक कोशिश की है (मेरा उत्तर देखें)। शाखा-लक्ष्यों में गिने हुए लेबल जोड़ना वास्तव में बहुत अच्छा है।
पीटर कॉर्डेस

5
उपयोगी विकल्प: objdump -drwC -Mintel-rप्रतीक तालिका से स्थानांतरण दिखाता है। -Cसी + + नाम demangles। -Wलंबे निर्देशों के लिए लाइन रैपिंग से बचा जाता है। यदि आप इसे अक्सर उपयोग करते हैं, तो यह आसान है alias disas='objdump -drwC -Mintel':।
पीटर कॉर्ड्स

2
-SDisassembly के साथ रुक-रुक कर स्रोत कोड प्रदर्शित करने के लिए जोड़ें । (जैसा कि एक अन्य उत्तर में बताया गया है ।)
अलेक्जेंडर पोज़नवीव

47

Objdump का एक दिलचस्प विकल्प gdb है। आपको बाइनरी को चलाने या डिबगिनोफ़ करने की आवश्यकता नहीं है।

$ gdb -q ./a.out 
Reading symbols from ./a.out...(no debugging symbols found)...done.
(gdb) info functions 
All defined functions:

Non-debugging symbols:
0x00000000004003a8  _init
0x00000000004003e0  __libc_start_main@plt
0x00000000004003f0  __gmon_start__@plt
0x0000000000400400  _start
0x0000000000400430  deregister_tm_clones
0x0000000000400460  register_tm_clones
0x00000000004004a0  __do_global_dtors_aux
0x00000000004004c0  frame_dummy
0x00000000004004f0  fce
0x00000000004004fb  main
0x0000000000400510  __libc_csu_init
0x0000000000400580  __libc_csu_fini
0x0000000000400584  _fini
(gdb) disassemble main
Dump of assembler code for function main:
   0x00000000004004fb <+0>:     push   %rbp
   0x00000000004004fc <+1>:     mov    %rsp,%rbp
   0x00000000004004ff <+4>:     sub    $0x10,%rsp
   0x0000000000400503 <+8>:     callq  0x4004f0 <fce>
   0x0000000000400508 <+13>:    mov    %eax,-0x4(%rbp)
   0x000000000040050b <+16>:    mov    -0x4(%rbp),%eax
   0x000000000040050e <+19>:    leaveq 
   0x000000000040050f <+20>:    retq   
End of assembler dump.
(gdb) disassemble fce
Dump of assembler code for function fce:
   0x00000000004004f0 <+0>:     push   %rbp
   0x00000000004004f1 <+1>:     mov    %rsp,%rbp
   0x00000000004004f4 <+4>:     mov    $0x2a,%eax
   0x00000000004004f9 <+9>:     pop    %rbp
   0x00000000004004fa <+10>:    retq   
End of assembler dump.
(gdb)

पूर्ण डिबगिंग जानकारी के साथ यह और भी बेहतर है।

(gdb) disassemble /m main
Dump of assembler code for function main:
9       {
   0x00000000004004fb <+0>:     push   %rbp
   0x00000000004004fc <+1>:     mov    %rsp,%rbp
   0x00000000004004ff <+4>:     sub    $0x10,%rsp

10        int x = fce ();
   0x0000000000400503 <+8>:     callq  0x4004f0 <fce>
   0x0000000000400508 <+13>:    mov    %eax,-0x4(%rbp)

11        return x;
   0x000000000040050b <+16>:    mov    -0x4(%rbp),%eax

12      }
   0x000000000040050e <+19>:    leaveq 
   0x000000000040050f <+20>:    retq   

End of assembler dump.
(gdb)

objdump का एक समान विकल्प (-S) है


12

यह उत्तर x86 के लिए विशिष्ट है। पोर्टेबल उपकरण जो AArch64, MIPS, या जो भी मशीन कोड शामिल हैं objdumpऔर जुदा कर सकते हैं llvm-objdump


Agner कोहरा के disassembler , objconvकाफी अच्छा है। यह प्रदर्शन समस्याओं के लिए disassembly आउटपुट में टिप्पणियां जोड़ देगा (जैसे 16bit तत्काल स्थिरांक के साथ निर्देशों से खतरनाक LCP स्टाल)।

objconv  -fyasm a.out /dev/stdout | less

(यह -स्टडआउट के लिए शॉर्टहैंड के रूप में पहचान नहीं करता है , और इनपुट फ़ाइल के समान नाम की फ़ाइल में आउटपुट करने के लिए डिफॉल्ट .asmकरता है।

यह कोड में शाखा लक्ष्य भी जोड़ता है। अन्य डिस्सेम्बलर्स आमतौर पर सिर्फ एक न्यूमेरिक डेस्टिनेशन के साथ जम्प निर्देशों को डिसाइड करते हैं, और लूप्स वगैरह के शीर्ष को खोजने में आपकी मदद करने के लिए ब्रांच टारगेट पर कोई मार्कर नहीं रखते हैं।

यह अन्य डिसेबल्लर की तुलना में एनओपी को अधिक स्पष्ट रूप से इंगित करता है (यह स्पष्ट करते हुए कि पैडिंग के बजाय, यह केवल एक अन्य निर्देश के रूप में डिसाइड करने की बजाय है।)

यह खुला स्रोत है, और लिनक्स के लिए संकलन करना आसान है। यह NASM, YASM, MASM या GNU (AT & T) सिंटैक्स में डिसाइड कर सकता है।

नमूना उत्पादन:

; Filling space: 0FH
; Filler type: Multi-byte NOP
;       db 0FH, 1FH, 44H, 00H, 00H, 66H, 2EH, 0FH
;       db 1FH, 84H, 00H, 00H, 00H, 00H, 00H

ALIGN   16

foo:    ; Function begin
        cmp     rdi, 1                                  ; 00400620 _ 48: 83. FF, 01
        jbe     ?_026                                   ; 00400624 _ 0F 86, 00000084
        mov     r11d, 1                                 ; 0040062A _ 41: BB, 00000001
?_020:  mov     r8, r11                                 ; 00400630 _ 4D: 89. D8
        imul    r8, r11                                 ; 00400633 _ 4D: 0F AF. C3
        add     r8, rdi                                 ; 00400637 _ 49: 01. F8
        cmp     r8, 3                                   ; 0040063A _ 49: 83. F8, 03
        jbe     ?_029                                   ; 0040063E _ 0F 86, 00000097
        mov     esi, 1                                  ; 00400644 _ BE, 00000001
; Filling space: 7H
; Filler type: Multi-byte NOP
;       db 0FH, 1FH, 80H, 00H, 00H, 00H, 00H

ALIGN   8
?_021:  add     rsi, rsi                                ; 00400650 _ 48: 01. F6
        mov     rax, rsi                                ; 00400653 _ 48: 89. F0
        imul    rax, rsi                                ; 00400656 _ 48: 0F AF. C6
        shl     rax, 2                                  ; 0040065A _ 48: C1. E0, 02
        cmp     r8, rax                                 ; 0040065E _ 49: 39. C0
        jnc     ?_021                                   ; 00400661 _ 73, ED
        lea     rcx, [rsi+rsi]                          ; 00400663 _ 48: 8D. 0C 36
...

ध्यान दें कि यह आउटपुट एक ऑब्जेक्ट फ़ाइल में वापस इकट्ठा होने के लिए तैयार है, इसलिए आप मशीन कोड पर हेक्स-एडिटर के बजाय कोड को asm स्रोत स्तर पर ट्विक कर सकते हैं। (इसलिए आप चीजों को समान आकार तक सीमित रखने के लिए सीमित नहीं हैं।) बिना किसी बदलाव के, परिणाम लगभग समान होना चाहिए। हालांकि, यह सामान की तरह disassembly के बाद से नहीं हो सकता है

  (from /lib/x86_64-linux-gnu/libc.so.6)

SECTION .plt    align=16 execute                        ; section number 11, code

?_00001:; Local function
        push    qword [rel ?_37996]                     ; 0001F420 _ FF. 35, 003A4BE2(rel)
        jmp     near [rel ?_37997]                      ; 0001F426 _ FF. 25, 003A4BE4(rel)

...    
ALIGN   8
?_00002:jmp     near [rel ?_37998]                      ; 0001F430 _ FF. 25, 003A4BE2(rel)

; Note: Immediate operand could be made smaller by sign extension
        push    11                                      ; 0001F436 _ 68, 0000000B
; Note: Immediate operand could be made smaller by sign extension
        jmp     ?_00001                                 ; 0001F43B _ E9, FFFFFFE0

यह सुनिश्चित करने के लिए स्रोत में कुछ भी नहीं है कि यह लंबे एन्कोडिंग के लिए कोडांतरण करता है जो कि एक 32 वें ऑफसेट के साथ इसे फिर से लिखने के लिए स्थानांतरित करने के लिए जगह छोड़ देता है।


यदि आप इसे objconv स्थापित नहीं करना चाहते हैं, तो GNU Binutils objdump -Mintel -dबहुत उपयोग करने योग्य है, और यदि आपके पास सामान्य लिनक्स gcc सेटअप है, तो यह पहले ही स्थापित हो जाएगा।


6

वहाँ भी ndisasm है, जिसमें कुछ quirks हैं, लेकिन यदि आप nasm का उपयोग करते हैं तो यह अधिक उपयोगी हो सकता है। मैं माइकल Mrozek के साथ सहमत हूँ कि objdump शायद सबसे अच्छा है।

[बाद में] आप अल्बर्ट वैन डेर होर्स्ट के सियाडिस की भी जांच कर सकते हैं: http://home.hccnet.nl/awmvan.der.horst/forthassembler.html । यह समझना मुश्किल हो सकता है, लेकिन कुछ दिलचस्प विशेषताएं हैं जो आपको संभवतः कहीं और नहीं मिलेंगी।


2
विशेष रूप से: home.hccnet.nl/awmvan.der.horst/ciasdis.html में "नवीनतम घटनाक्रम" एक डेबियन पैकेज है, जिसे आप आसानी से स्थापित कर सकते हैं। उचित निर्देशों के साथ (यह स्क्रिप्टिंग करता है) यह एक स्रोत फ़ाइल उत्पन्न करेगा जो फिर से उसी बाइनरी में फिर से इकट्ठा होगा। मैं किसी भी पैकेज के बारे में नहीं जानता जो ऐसा कर सकता है। निर्देशों का उपयोग करना कठिन हो सकता है, मैं व्यापक उदाहरणों के साथ जीथब में प्रकाशित करने का इरादा रखता हूं।
अल्बर्ट वैन डेर होर्स्ट

4

इसके लिए आईडीए थोड़ा अधिक लगता है, विशेष रूप से यह महंगा है पर विचार
माइकल Mrozek

1
लिनक्स के लिए मुफ्त संस्करण उपलब्ध नहीं है, केवल सीमित डेमो संस्करण है। (बहुत बुरा है क्योंकि, खिड़कियों पर, यह सबसे अच्छा disassembler है जो मैंने कभी इस्तेमाल किया है)
एड्रियन प्लिसन

आईडीए अच्छा है, लेकिन आईडीए की समस्या आप आलसी हो जाते हैं यदि आप छोटे कार्यों के लिए उपयोग करते हैं .. तो क्या जीडीबी अधिकांश कामों के लिए काम करता है, जीडीबी आसान है? नहीं, लेकिन संभव है।
cfernandezlinux

4

आपको ODA उपयोगी लग सकता है। यह एक वेब-आधारित डिस्सेम्बलर है जो टन के आर्किटेक्चर का समर्थन करता है।

http://oniltisassembler.com/


1
महान विचार। सर्वर त्रुटि (500) onlineisassembler.com/odaweb को प्राप्त करना - आशा है कि यह क्षणिक है।
जूल

3

आप बहुत ही करीब आ सकते हैं (लेकिन कोई सिगार नहीं) विधानसभा उत्पन्न करने के लिए जो फिर से इकट्ठा करेगा, यदि आप ऐसा करने का इरादा कर रहे हैं, तो कच्चे और tediously लंबी पाइपलाइन चाल का उपयोग करें (फ़ाइल के साथ / बिन / बैश करें जिसे आप जुदा करना चाहते हैं और bash.S जिसे आप आउटपुट भेजने का इरादा रखते हैं):

objdump --no-show-raw-insn -Matt,att-mnemonic -Dz /bin/bash | grep -v "file format" | grep -v "(bad)" | sed '1,4d' | cut -d' ' -f2- | cut -d '<' -f2 | tr -d '>' | cut -f2- | sed -e "s/of\ section/#Disassembly\ of\ section/" | grep -v "\.\.\." > bash.S

ध्यान दें कि यह कितना लंबा है। मैं वास्तव में चाहता हूं कि एक बेहतर तरीका था (या, उस बात के लिए, कोड को आउटपुट करने में सक्षम एक डिस्सेम्बलर जिसे एक कोडांतरक पहचान लेगा), लेकिन दुर्भाग्य से वहां नहीं है।


वाह! यह शानदार है। Btw, आपकी समस्या के बारे में, आप इसके लिए एक उपनाम का उपयोग क्यों नहीं करते ताकि इस विशाल कमांड को टाइप किया जा सके?
चमगादड़

1

ht संपादक कई स्वरूपों में बायनेरिज़ को अलग कर सकता है। यह एचवाईई के समान है, लेकिन खुला स्रोत है।

जुदा करने के लिए, एक बाइनरी खोलें, फिर F6 दबाएं और फिर योगिनी / छवि का चयन करें।


0

मान लीजिए कि आपके पास है:

#include <iostream>

double foo(double x)
{
  asm("# MyTag BEGIN"); // <- asm comment,
                        //    used later to locate piece of code
  double y = 2 * x + 1;

  asm("# MyTag END");

  return y;
}

int main()
{
  std::cout << foo(2);
}

Gcc का उपयोग करके आप असेंबली कोड प्राप्त कर सकते हैं:

 g++ prog.cpp -c -S -o - -masm=intel | c++filt | grep -vE '\s+\.'

c++filt प्रतीकों को तोड़ता है

grep -vE '\s+\.' कुछ बेकार की जानकारी निकालता है

अब यदि आप टैग किए गए भाग की कल्पना करना चाहते हैं, तो बस उपयोग करें:

g++ prog.cpp -c -S -o - -masm=intel | c++filt | grep -vE '\s+\.' | grep "MyTag BEGIN" -A 20

अपने कंप्यूटर से मुझे मिलता है:

    # MyTag BEGIN
# 0 "" 2
#NO_APP
    movsd   xmm0, QWORD PTR -24[rbp]
    movapd  xmm1, xmm0
    addsd   xmm1, xmm0
    addsd   xmm0, xmm1
    movsd   QWORD PTR -8[rbp], xmm0
#APP
# 9 "poub.cpp" 1
    # MyTag END
# 0 "" 2
#NO_APP
    movsd   xmm0, QWORD PTR -8[rbp]
    pop rbp
    ret
.LFE1814:
main:
.LFB1815:
    push    rbp
    mov rbp, rsp

एक अधिक अनुकूल दृष्टिकोण का उपयोग करना है: कंपाइलर एक्सप्लोरर


यह केवल अनुकूलन अक्षम के साथ विश्वसनीय है, अन्यथा क्षेत्र के अंदर संचालन के कुछ हिस्सों को बाहर सामान में अनुकूलित किया जा सकता है, या दूर अनुकूलित किया जा सकता है। तो आप केवल clunky -O0asm देख सकते हैं ।
पीटर कॉर्ड्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.