- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我们的计算机体系结构教授给了我们一个示例程序,要求输入密码。任务是在比较输入的密码并决定是否正确后更改跳转操作码。我编写了一个程序,可以更改给定二进制文件中特定位置的任何字节。
这是密码程序的代码:
int main(int argc, char* argv[]){
char *pw = "12441233";
char pass[32];
printf("Enter password:\n");
scanf("%s", pass);
if(strncmp(pass,pw,8))
{
printf("Password wrong\n");
exit(-1);
}
printf("Welcome\n");
}
所以我在控制台输入 $ objdump -d task
得到了这个:
...
400703: || 48 8b 5d e8 || mov -0x18(%rbp),%rbx
400707: || 64 48 33 1c 25 28 00 || xor %fs:0x28,%rbx
40070e: || 00 00
400710: || 74 05 || je 400717
400712: || e8 29 fe ff ff || callq 400540 <__stack_chk_fail@plt>
400717: || 48 83 c4 58 || add $0x58,%rsp
40071b: || 5b || pop %rbx
...
74
是 je 的字节,我想将其更改为 75
以表示 jne。如何获取我的 74
字节在相应二进制文件中的确切位置,以便我可以将其更改为新值?
最佳答案
正如 Hans 指出的那样,内存位置与它无关。您需要做的是找到字节(或多个字节)在文件中的位置。为此,一个非常好的反汇编器(这将是 IDA-Pro)让你生活得非常轻松。遗憾的是,IDA 的价格曲线陡峭,因此我们将坚持使用您可以轻松获得的工具。
以下是在 Linux 机器上完成的,使用在 Ubuntu 14.04 上运行的 gcc 版本 4.8.2 和 gdb 7.7
使用 gcc -g -ansi -pedantic -Wall
编译代码。不是真正的问题,但是 main
应该有一个返回值。
将程序加载到 gdb 中,在 main 处设置一个断点,然后运行程序。当我到达断点时,我使用了 gdb 的 disass
命令来获得反汇编列表,如下所示:
(gdb) disass
Dump of assembler code for function main:
0x000000000040067d <+0>: push %rbp
0x000000000040067e <+1>: mov %rsp,%rbp
0x0000000000400681 <+4>: push %rbx
0x0000000000400682 <+5>: sub $0x58,%rsp
0x0000000000400686 <+9>: mov %edi,-0x54(%rbp)
0x0000000000400689 <+12>: mov %rsi,-0x60(%rbp)
=> 0x000000000040068d <+16>: mov %fs:0x28,%rax
0x0000000000400696 <+25>: mov %rax,-0x18(%rbp)
0x000000000040069a <+29>: xor %eax,%eax
[ ... ]
0x00000000004006cc <+79>: mov $0x8,%edx
0x00000000004006d1 <+84>: mov %rcx,%rsi
0x00000000004006d4 <+87>: mov %rax,%rdi
0x00000000004006d7 <+90>: callq 0x400520 <strncmp@plt>
0x00000000004006dc <+95>: test %eax,%eax
0x00000000004006de <+97>: je 0x4006f4 <main+119>
0x00000000004006e0 <+99>: mov $0x4007c0,%edi
0x00000000004006e5 <+104>: callq 0x400530 <puts@plt>
[ ... ]
0x0000000000400718 <+155>: retq
End of assembler dump.
我知道这看起来很不祥,但请花点时间环顾四周,注意一些事情;A。尖括号中的数字(即 <+97>)给出了指令从函数开始处算起的字节数。在您的情况下,您需要的操作码是从函数开头算起的 97 个字节。
b.前 9 个字节(前四个指令)通常看起来像我们这里的内容,它们是函数的序言,它们正在为函数设置激活(或堆栈)帧。
现在,我们需要找到 main 在您的可执行文件中的位置。这往往是特定于操作系统和编译器的。就我而言,在 Linux 主机上工作,我知道代码存储在文件的 .text 部分,我可以使用工具 readelf
来获取它位置如下图;
readelf --wide -S task
There are 35 section headers, starting at offset 0x1478:
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 0000000000400238 000238 00001c 00 A 0 0 1
[ 2] .note.ABI-tag NOTE 0000000000400254 000254 000020 00 A 0 0 4
[ 3] .note.gnu.build-id NOTE 0000000000400274 000274 000024 00 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0000000000400298 000298 00001c 00 A 5 0 8
[ 5] .dynsym DYNSYM 00000000004002b8 0002b8 0000c0 18
[ .... ]
[13] .text PROGBITS 0000000000400590 000590 000202 00 AX 0 0 16
[14] .fini PROGBITS 0000000000400794 000794 000009 00 AX 0 0 4
[15] .rodata PROGBITS 00000000004007a0 0007a0 000037 00
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
从上面我们可以看出,.text 部分将从内存位置 0x400590 开始,结束位置为 0x400792(基于 0x202 的大小)。此外,我们可以看到 .text 部分在文件中有一个偏移量 0x590。回顾我们的反汇编,我们可以看到 main
从 0x0040067d 开始,它在 .text 的范围内(只是完整性检查)。
我们现在有了应用程序的入口点(.text 部分的起始内存地址,如果我们从中减去 main
的起始点入口点,我们应该获取main
相对于代码映射位置的偏移量(在内存中)。最后将此值添加到可执行文件中代码的偏移量应该给我们main
的文件位置:
000067d: 5548 89e5 5348 83ec 5889 7dac 4889 75a0 UH..SH..X.}.H.u.
000068d: 6448 8b04 2528 0000 0048 8945 e831 c048 dH..%(...H.E.1.H
000069d: c745 b8a4 0740 00bf ad07 4000 e882 feff .E...@....@.....
00006ad: ff48 8d45 c048 89c6 bfbd 0740 00b8 0000 .H.E.H.....@....
00006bd: 0000 e8ac feff ff48 8b4d b848 8d45 c0ba .......H.M.H.E..
00006cd: 0800 0000 4889 ce48 89c7 e844 feff ff85 ....H..H...D....
00006dd: c074 14bf c007 4000 e846 feff ffbf ffff .t....@..F......
00006ed: ffff e88c feff ffbf cf07 4000 e832 feff ..........@..2..
00006fd: ff48 8b5d e864 4833 1c25 2800 0000 7405 .H.].dH3.%(...t.
000070d: e82e feff ff48 83c4 585b 5d .....H..X[]
作为一个快速的完整性检查,记得我提到过 main 的前几个字节是相当样板的,如果我们查看它们并将它们组装到我们的机器中,我们会得到:
push %rbp 0x55
mov %rsp,%rbp 0x48 0x89 0xe5
push %rbx 0x53
sub $0x58,%rsp 0x48 0x83 0xec 0x58
mov %edi,-0x54(%rbp) 0x89 0x7d 0xac
鉴于上述字节序列与第 5 步中的起始字节序列相匹配,可以相当安全地假设我们已在可执行文件中找到 main
的位置。现在剩下要做的就是将偏移量为 0x6de 的字节从 0x74 修改为 0x73。
注意IDA 确实有一个免费版本,但有一些限制,所以值得您花时间捕获它并使用它。
希望这有帮助,
关于c - 获取二进制文件中特定 OpCode 的确切位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29865801/
我正在尝试获取从过去的 startposition/location 到当前移动的 currentposition/location 的距离(以米为单位)。 我确实有工作正常的currentposit
所以我有一堆绝对覆盖的 div。用户通过在叠加层上拖动来创建方形 div。如果您要创建一个 div,然后放大和缩小,div 会保持在同一位置,因为它对叠加层是绝对的,如前所述。 然而问题就出在这里。您
我想找到 View 在显示屏幕上的位置。 为此,我使用了 view.getLeft() 、view.getBottom() 、view.getRight() 等方法> , view.getTop()。
我有一个看起来像这样的 View 层次结构(基于其他答案和 Apple 的使用 UIScrollView 的高级 AutoLayout 指南): ScrollView 所需的2 个步骤是: 为 Scr
所以我有一个名为 MARKS 的表,我有这些列 STUDENT_ID, CLASSFORM_NAME, ACADEMIC_YEAR, TERM, SUBJECT_NAME, TOTAL_MARKS
我有一个问题我无法理解,请帮助: 我开发了带有图像的 html 页面,并使用 jQuery UI 帮助使它们可拖动,我将这些图像位置设置为相对位置并给出了左侧和顶部像素,这是页面的链接 http://
我正在尝试创建一个 CSS 动画,它在 sprite 表中循环播放 16 个图像,给人一种幽灵“漂浮”的错觉。动画通过在 background-position 位置之间移动以显示不同状态的幽灵来实现
我正在创建这个网站的 WebView https://nearxt.com/打开时询问位置但是当我使用此链接在 flutter 中创建 webview 时那么它就无法定位我还在应用程序中定义了位置,但
我正在以编程方式创建一个需要跨越 2 个屏幕的窗口。正在创建的窗口的大小是正确的,但窗口大约从第一个屏幕的一半开始。我可以将它拖回第一个屏幕的开头,NSWindow 非常适合。 我只需要知道在窗口的起
位置“/”的匹配叶路由没有元素。这意味着默认情况下它将呈现一个空值,从而导致一个“空”页面 //App.js File import { BrowserRouter as Router, Routes
我有一个运行 Ubuntu 和 Apache 的 VPS 例如,假设地址是:5.5.5.5 在 VPS 上,我有一个名为 eggdrop 的用户(除了我的 root 用户)。 用户 eggdrop 有
我有一个 JLabel与 ImageIcon ,我使用 setIcon() JLabel中的函数. ImageIcon然后上来,坐在我的JLabel 的文字左侧.是否有可能拥有 ImageIcon在文
我的图中有节点,它们的 xlabels 位于它们的左上方。我怎样才能改变这个位置?我希望 xlabels 正好位于节点本身的旁边。 最佳答案 xlp是你想要的属性,但它没有做任何事情。 你不能改变位置
我对基本的 VIM 功能有疑问:(我尝试谷歌搜索但找不到答案) 如何列出所有自定义功能。(我做了 :function 并且不能找到我的自定义函数) 如何获得自定义函数列表中的函数(或它们的存储位置)。
我是 PHP 的新手,虽然我一直在搜索,但我不知道该怎么做。 我知道可以使用 Location("some page") 进行重定向。我还读到,只要没有向用户显示任何内容,它就可以工作。 我想做的是:
如果在 jgrowl.css 中位置更改为“center”,我如何将其覆盖为默认值,即“top-right” $.jGrowl(data, { header: 'data', an
我需要根据用户是否滑动屏幕顶部、屏幕中间或屏幕底部来触发不同的事件。我正在尝试找出最好/最简单的方法来做到这一点,因为我很确定没有办法从 UISwipeGestureRecognizer 获取位置。
我需要枚举用delphi编写的外部应用程序中使用的类 ,因此我需要访问VMT表以获取该信息,但是我找不到任何有关如何在exe(由delphi生成)文件中找到VMT(虚拟方法表)的位置(地址)的文档。
在 D2010 (unicode) 中是否有像 Pos 这样不区分大小写的类似函数? 我知道我可以使用 Pos(AnsiUpperCase(FindString), AnsiUpperCase(Sou
我正在尝试为我的reveal.js 演示文稿制作一个标题,该标题会粘贴在屏幕顶部。标题中的内容在每张幻灯片的基础上都是动态的,因此我必须将标记放在 section 标记中。 显然,如果标记在 sect
我是一名优秀的程序员,十分优秀!