A. 如何:使用「反匯編」窗口
默認情況下隱藏只有在「選項」對話框中的「調試」節點下啟用了地址級調試後,該功能才可用。
但對於腳本或
SQL
調試是不可用的。
「
反匯編
」窗口顯示與
編譯器
所創建的指令對應的匯編代碼。
如果正在調試
託管代碼
,則這些
匯編指令
對應於由實時
(JIT)
編譯器創建的本機代碼,而不是由
Visual
Studio
編譯器生成的
Microsoft
中間語言
(MSIL)。
除匯編指令外,
「反匯編」窗口還可顯示如下可選信息:
每條指令所在的
內存地址
對於本機應用程序,這是實際內存地址。
對於
Visual
Basic、C#
或託管代碼,這是距離函數開頭的偏移量。
程序集
代碼派生於的源代碼。
代碼位元組
—
實際計算機或
MSIL
指令的位元組表示形式。
內存地址的符號名。
對應於源代碼的行號。
匯編語言指令由
助記符
(指令名稱的縮寫)和代表變數、寄存器以及常量的符號所組成。
每一條
機器語言
指令由一個匯編語言助記符代表,通常其後還跟有一個或多個變數、寄存器或常量。
如果您無法閱讀匯編語言但又想充分利用「反匯編」窗口,請參考有關匯編語言編程的好書。
匯編語言編程超出了我們對「反匯編」窗口進行簡單介紹的討論范圍。
匯編語言代碼在很大程度上依賴處理器的寄存器(對託管代碼而言,依賴公共語言運行時寄存器),您將發現協同使用「反匯編」窗口和「寄存器」窗口將很有用,可以允許您檢查寄存器內容。
您很可能願意使用匯編語言,而從來不會願意或需要查看原始的、數字形式的
機器代碼
指令。
不過,如果願意的話,可以利用「內存」窗口或從「反匯編」窗口的
快捷菜單
中選取「代碼位元組」來查看。
注意顯示的對話框和菜單命令可能會與「幫助」中的描述不同,具體取決於您現用的設置或版本。
若要更改設置,請在「工具」菜單上選擇「導入和導出設置」。
有關更多信息,請參見使用設置。
B. 嵌入式ARM STM32 反匯編 代碼分析
RCC寄存器組的基地址放在PC+156位置處,所以LDR r1,[pc,#156] 指令的意思是在當前地址加上156的位置取得一個32位的數字放在r1。
C. 怎樣反匯編bzImage-platinum-ChinaUnix博客
具體步驟如下:
#! /bin/sh
set -x
#
# 一般gzip壓縮包的magic值為0x8b1f後跟0x0008,或者。
# 這里就是要找出這個偏移。
# 119116,就是這個偏移,這個偏移在不同的bzImage里是不同的,所以,這里需要手動調整一下。
# 解壓後的文件即vmlinux.bin
od -h -A d bzImage | grep --color -m 3 -A 1 -i 8b1f
dd if=bzImage bs=1 skip=11916 | gunzip > vmlinux.bin
# 調用我寫的一個python腳本,生成gnu linker script。
./genlds.py > vmlinux.elf.lds
# 構造 ELF 信息,結果文件為vmlinux.elf
ld -m elf_x86_64 --format binary --oformat elf64-x86-64 -T vmlinux.elf.lds vmlinux.bin -o vmlinux.elf
# 如果是32位系統,可以用以下命令
#ld -m elf_i386 --format binary --oformat elf32-i386 -T vmlinux.elf.lds vmlinux.bin -o vmlinux.elf
# 刪除在上一步生成的多餘符號。
obj --strip-symbol _binary_vmlinux_bin_start --strip-symbol _binary_vmlinux_bin_end --strip-symbol _binary_vmlinux_bin_size vmlinux.elf
# 設置 .text section標志,否則objmp -d不能正常工作,只能用objmp -D。
obj --set-section-flag .text=alloc,readonly,code vmlinux.elf
# 以後只是出於驗證目的。
# 以schele函數作為一個樣本,檢查在vmlinux.elf文件里是不是包括了正確的偏移。
grep --color "[tT] schele$" System.map
readelf -s vmlinux.elf | grep " schele$" --color
genlds.py內容如下:
#! /usr/bin/python
import sys
#將 形如 fffffff8989 的字元串轉換為數字形式。
def to_no(hexstr):
ret = 0
start = -1
len_hexstr = len(hexstr)
while start>=-len_hexstr:
c = hexstr[start]
if c in "0123456789":
n = ord(c) - ord('0')
elif c in "abcdef":
n = ord(c) - ord('a') + 0xa
elif c in "ABCDEF":
n = ord(c) - ord('A') + 0xa
ret |= long(n<<((-start-1)*4))
start -= 1
return ret
# 計算addr-base
def sym_offset(addr, base):
if base == "missing-base":
return "missing-offset"
addr = to_no(addr)
base = to_no(base)
return hex(int(addr-base))
lines = file("System.map").readlines()
result=""
# 求.text的開始地址
base="missing-base"
for line in lines:
line = line.strip()
addr, type, sym = line.split(" ")
if type in "tT":
if sym in ("startup_64", "startup_32"):
base = addr
break
# 生成lds中的符號行。
for line in lines:
line = line.strip()
addr, type, sym = line.split(" ")
if type in "tT":
offset = sym_offset(addr, base)
result+="\t%s = %s; /* orig: 0x%s */\n" % (sym, offset, addr)
# 生成需要的腳本
template="""
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
SECTIONS
{
. = 0x%s;
.text . : {
*(.data)
%s}
}
"""
print template % (base, result)
以下是反匯編的出來部分結果:
ffffffff80466ca0 <interruptible_sleep_on>:
ffffffff80466ca0: 55 push %rbp
ffffffff80466ca1: 48 ba ff ff ff ff ff mov $0x7fffffffffffffff,%rdx
ffffffff80466ca8: ff ff 7f
ffffffff80466cab: be 01 00 00 00 mov $0x1,%esi
ffffffff80466cb0: 48 89 e5 mov %rsp,%rbp
ffffffff80466cb3: c9 leaveq
ffffffff80466cb4: e9 c7 fe ff ff jmpq ffffffff80466b80 <__sched_text_start>
ffffffff80466cb9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
ffffffff80466cc0 <schele>:
ffffffff80466cc0: 55 push %rbp
ffffffff80466cc1: 48 c7 c0 80 ef 62 80 mov $0xffffffff8062ef80,%rax
ffffffff80466cc8: 48 c7 c2 00 b4 62 80 mov $0xffffffff8062b400,%rdx
ffffffff80466ccf: 48 89 e5 mov %rsp,%rbp
ffffffff80466cd2: 41 57 push %r15
ffffffff80466cd4: 41 56 push %r14
ffffffff80466cd6: 41 55 push %r13
ffffffff80466cd8: 41 54 push %r12
ffffffff80466cda: 53 push %rbx
ffffffff80466cdb: 48 81 ec 98 00 00 00 sub $0x98,%rsp
ffffffff80466ce2: 48 c7 85 78 ff ff ff movq $0xffffffff8062ef80,-0x88(%rbp)
ffffffff80466ce9: 80 ef 62 80