|
|
|
[原创]PE 文件格式启发式学习(以hello.exe 为例)(5.15更新)
接问题2.20后的第21个问题 问:3.21 上回说到loader 为了使程序正常运行,偷偷的把.rdata 节中的某些数据给改了,能再讲清楚一些吗? 答:3.21 加载器未改之前,我们用hiew 看文件有如下数据 .00402000: 76 20 00 00-00 00 00 00-5C 20 00 00-00 00 00 00 加载器改动之后,我们可以用ollydbg 看一下,这是加载器完成修改后的结果 具体操作是用ollydbg 加载hello.exe,点击数据窗口,按ctrl-G,输入地址402000 然后看到如下数据 00402000 >DA CD 81 7C 00 00 00 00 8A 05 D5 77 00 00 00 00 谕亅....?誻.... 这就说明,加载器把2076 改成了7c81cdda, 把205c 改成了 77d5d58a 问:3.22 呦,还藏着这等玄机呢! 不过,加载器也是一段程序,它总不能乱改吧?咱就以后面 的205c 为例,它凭什么要把205c 改成77D5058A呢?这个可是我们要call 的MessageBox的地址呢。 答:3.22 连接器知道你要CALL MessageBox, 但MessageBox 是USer32.dll 的函数,连接器不知道 MessageBox 在哪里,只有操作系统才知道USer32.dll 在哪里。loader 也是通过调用系统 函数才知道的。由于link 的时候文件还没有运行,所以它不知道MessagBox 的具体地址。 好,这个问题讲清了,连接器不知道DLL及其函数的具体地址。 但连接器也会尽其所能,告诉加载器一些信息,他对加载器说,运行前你要帮我把USer32.dll 的MessageBox 地址给填好!拜托了! 用计算机来描述是这样的。 他往402008处填了一个205c, 这个205c 是什么,是一个RVA, 它指向一个数据结构,该结构 实现linker 向 loader 的信息传递, loader 来完成linker 未完成的使命。 如果你要想看看linker 向 loader 说了什么,咱还得先看看这个数据结构的地址。 问:3.23 就已hello.exe 为例吧,看看205c 怎么找到那个数据结构地址的。 答:3.23 loader 拿到了数据205c, 知道这是一个RVA, 加上影像基地址0x400000,或者说叫module 地址吧。 得到了一个虚地址0x40205c,你从ollydbg 的数据窗口中看0x40205c 地址。是如下内容: 0040205C 9D 01 4D 65 73 73 61 67 65 42 6F 78 41 00 75 73 ?MessageBoxA.us 0040206C 65 72 33 32 2E 64 6C 6C 00 00 80 00 45 78 69 74 er32.dll..€.Exit 0040207C 50 72 6F 63 65 73 73 00 6B 65 72 6E 65 6C 33 32 Process.kernel32 0040208C 2E 64 6C 6C 00 00 00 00 00 00 00 00 00 00 00 00 .dll............ 它指向一个WORD 数据019D, 后跟MessageBoxA 0字终结字符串,其后再跟USER32.dll。 这个结构有一个学名,叫 IMPORT_BY_NAME,如下定义: // // Import Format // typedef struct _IMAGE_IMPORT_BY_NAME { WORD Hint; BYTE Name[1]; } IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; Hint, 就是那个019d 了,BYTE Name[1], 这个变量定义看起来很奇怪,是吗? 代学生: 是的,我很少见到这种定义。 通常我们会定义 char buffer[256], BYTE data[8]; 等类型。 BYTE Name[1], 只包含一个元素的数组,它也装不下后面的"MessageBoxA"字符串啊。 代老师:这种定义是一种指针的变通用法。 如果你真要定义成数组来包含后面的字符串,你定义成多大呢?定义成100,短字符串浪费, 长字符串可能就真能碰到一个101个字符的名字,你定义的还是占不下。 所以说,这个Name[1], 不是要你往里面装东西的,C 语言里,你可以借助这个Name 变量访问到它对应的地址。 这种用法通常是很少用的。因为它毛病很多,例如结构后面不能再定义其它变量了,必须是最后一个,定义了 数组又不用它装东西,也不符合数组的初衷. 所以你只有明白这个道理就可以了。 代学生:既然它那么不好用,为什么还那样定义呢。 代老师:还是那句话,是变通。 你看,它简洁,它完成了使命。否则你就要把结构变一变,例如按常规估计应该是这样子。 WORD Hint; BYTE *pName; 然后你要求微软说,Hint 后面不要跟字符串,要跟一个地址。这样C语言好写。 好比说大部分人沿着盘山路往山上走,也有人愿意盘着荆棘往山上爬,后者绕了近路,但风险也大。 代学生:讲了这么多,其实我看一个word 后面跟着一个0字终结符字符串,还是很好理解的吗。 代老师:C 语言以其简洁,高效,使我们受益良多。但在某些特殊的情况下,它也会力不从心。有时刻当你看着一堆堆 结构套结构,一堆堆宏套宏令你头晕时,而看看它最终的list 表或二进制输出反而能令你豁然开朗。 哦,有点扯远了。 我还是最喜欢C的。 问: 3.24 找到了这个 IMPORT BY Name 结构, loader 是怎样根据这些信息修改地址的呢? 答:3.24 loader 在加载时,是要先收集信息的,不过这部分还没有讲,收集好后,以MessageBoxA为例 loader询问系统,USER32.dll 加载了吗?没有我要先加载它啦。哦,加载了,告诉我MessageBoxA 函数地址是多少?系统返回一个地址 77d5d58a, loader 就把这个地址覆盖了原来存储的 0x205c 。 这样就把MessageBoxA 的内存地址给拧上了。 注意了,这个 77d5d58a 是我机器上的MessageBoxA 内存地址, 到了你的机器上,它就变成别的啦。 这正是DLL 存在的妙处。 意思表达很明确,不是吗? 问:3.25 对,它肯定能表达明确。不过目前我还有很多问题要问,别嫌麻烦呦。我问得可是很细致的。 答:3.25 难得你精神可嘉,咱们也是互相促进的。能走到这里,也可以说是渐入佳境了。 问:3.26 弱弱得问一下,3.23 提到的那个module 地址0x400000, 是固定死的吗? 答:3.26 module 加载地址,是loader 将应用程序加载到内存时的起始地址,loader 是从Option header 结构中的Image Base 项得到这个地址的,由于exe 文件不存在地址冲突问题,所以loader 总能 把程序加载到Option header 中Image Base 指定的位置,这个位置通常都是0x400000. 问:3.27 刚才没顾上问,MessageBoxA 前面那个WORD 019d, 就是hint, 是干什么的。 答:3.27 那个东东是loader 向系统询问函数地址的另外一种方式,它可以向系统询问user32.dll 第019d 个 导出函数是多少 ? 系统回答 77d5d58a 。 这种导入方式叫ordinal. DLL 中有名称的导出函数都可以 用名称访问,也可以用ordinal 访问,而有的导出函数没有名,只能用ordinal方式导入。 问:3.28 刚才你是用ollydbg 来讲解的,我们不是一直用ultraedit 打开这个文件,直接分析它的二进制 结构的吗。能用ultraedit 再讲一讲linker 向 loader 说了什么吗? 答:3.28 这主要是因为动态链接的数据是一个RVA, 所以用ollydbg 讲的方便。同时由于在ollydbg中已经完 成了动态连接,跟utraedit 静态分析正好有个对照。现在我们再来看从ultraedit 中怎样找到 ???结构 loader 拿到了数据205c, 哦, 不对,是我们拿到了205A,知道这是一个RVA.需要把它转成文件偏移 好看看它到底对我们说了什么。 从RVA 到 OFFSET, 我们好像还没有讲呢,就在这里补上吧。 从RVA 到 OFFSET 没有一个简单的公式,唯一的办法就是查表。 查什么表,查section header 表。 已hello.exe 为例,我们查表,看到205c 落入.rdata 节,该节的虚拟地址(就是内存地址)0x2000 对应文件偏移0600,那么205c, 则对应文件偏移的065c. 用ultraedit 观看,如下图示。跟ollydbg看到的内容一样。 0000650: 0000 0000 5c20 0000 0000 0000 9d01 4d65 ....\ ........Me 0000660: 7373 6167 6542 6f78 4100 7573 6572 3332 ssageBoxA.user32 0000670: 2e64 6c6c 0000 8000 4578 6974 5072 6f63 .dll....ExitProc 0000680: 6573 7300 6b65 726e 656c 3332 2e64 6c6c ess.kernel32.dll 代学生:顺便问一下,那些查虚拟地址到文件偏移转换的工具是这样查的吗? 代老师:是的。 问3.29 .rdata 节中大部分数据都明白了,但从610-65d 那一段数据是干什么的? 答3.29 这段数据,当然也是动态加载用的。 前面讲的link 与 loader 对话,确实如上所说,但那只是问题的一半,还有一半就是,当loader 把程序 加载到内存,它要修改数据,它怎样找到修改数据的地址,也就是说,那个存储着RVA 205c 的地址 00402008 loader 是怎样得到的?还有,它怎么知道MessageBoxA在user32.dll 里面? 问3.30 平时都是我问,现在忽然被反问。翻翻前面讲的 。。。 啊! 是2.18 时提出来的,程序要call 41c, 41c 要向402008 地址所装的内容处跳。 哦,这是我们的读法。loader 是不会这么读的,loader 是死的,loader 是一段程序,它只会干机械的事。 它怎么找到402008的,它怎么知道MessageBoxA在user32.dll 里面? 还是听你讲吧。 答3.30 讲清这个问题,我们还要再看option header. 坚持住,动态加载导入部分也就差这一点点了。 在1.2中提到option header 的数据结构,在他的底部有一个成员。 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; 看着眼晕,还不如写简单点,它的数组就是16个元素 IMAGE_DATA_DIRECTORY DataDirectory[16]; 前面那个结构叫数据目录,如下定义 // // Directory format. // typedef struct _IMAGE_DATA_DIRECTORY { DWORD RelativeVirtualAddress; DWORD Size; } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; 挺简单的,其实就是8个字节。 16个目录吗,就是16*8 = 108 字节。占8整行 别担心,大部分没有用,微软在这里搞捉迷藏。我们只关心几个就行了。 这里首先介绍的一个叫导入表(import table)。 0000130: 0000 0000 0000 0000 ................ 0000140: 1020 0000 3c00 0000 0040 0000 a003 0000 . ..<....@...... 0000150: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000160: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000170: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000180: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000190: 0000 0000 0000 0000 0020 0000 1000 0000 ......... ...... 00001a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00001b0: 0000 0000 0000 0000 2e74 6578 7400 0000 .........text... 为什么还留下那个.text, 一看就知道,.text 代表的是section header table 的开始地址 其上的8个整行就是16 个目录了。真要让你像计算机一样从上到下数偏移,我们还真不行, 找ascii 字,我们还在行。 第一个目录叫导出表,这里为空 第二个目录叫导入表,这里虚拟地址是0x2010, 大小是3c. 2010 RVA 对应的文件偏移是610 (算法我想你已经掌握了,看3.28) 第三个目录叫资源表。RVA=0x4000, size=0x3a0 (暂时先不讨论) 第十三个目录叫IAT 表,英文全称为:Import Address Table. RVA=0x2000,size=0x10 其它的目录都是空的,没用,不理它们。 代老师:哦,是不是讲的有点多了? 代学生: 还行,反正讲得挺清楚的。想不到这个小小的hello.exe 还有这么多事情。 不过再看看hello.exe文件,大部分内容都讲了,我想也不会有太多东西了。 代老师:正是,坚持一下就是胜利。 |
|
[求助]终于可以发帖子了,请教问题高手请进。谢谢
建议你先脱upx 壳,最好练练手脱,好像有个脱壳天书的教程印象不错 然后去除时间限制,因为是25分钟限制,估计是timer 在起作用,找到settimer 函数,在它的前面合适的地方跳过去,使它不能起到作用。 另一种方法,既然可以注册,想办法注册成功,找不到注册码 爆破也行啊。具体操作还是看你自己了。 不要破太难的软件,有的软件保护是很完善的。 |
|
[原创]PE 文件格式启发式学习(以hello.exe 为例)(5.15更新)
灌水10篇,才能贴附件,我的hello world 附件就贴这吧,方便大家对照 |
|
[原创]PE 文件格式启发式学习(以hello.exe 为例)(5.15更新)
接问题1.10后的第11个问题 问:2.11 干脆就把位置问题先问到底吧。PE标识符 54 45 00 00 总是在文件偏移00c0 处吗。 答:2.11 基本上可以这么说,主要是因为前面的部分是dos 头部和dos 体 dos 头部 IMAGE_DOS_HEADER 的结构我就不贴了,因为dos 已经离我们远去,它 已经失掉了意义,dos 体也几乎是固定不变的了。这部分的作用是当你拿这个 PE程序到dos 系统上运行时,dos 执行会在控制台上打印一行提示信息, "this program cannot be run in DOS mode" 然后停在哪。总比你一运行,DOS 就hang 机强多了。如果拿PE代码在DOS 下直接执行,不用说那肯定hang 机。 微软就是怕这个事情发生才用了这么一个措施。 现在你只需要记住一件事,文件头两个字母是MZ标记,在3c偏移地址,00 00 00 c0 指的是NT header 的文件偏移,如果这个偏移处的标识正好是PE. 可以肯定,这个文件 就是PE 文件了。 如果在3c偏移地址处存其它DWORD 地址,那就到所指定的地址去找 如果该处正好ASCII "PE",此处就是NT的header 。 问:2.12 怎么有这么多header, 能否概要总结一下: 答:2.12 好的。在文件开头部分是 _IMAGE_DOS_HEADER ,小名MZ header, 我们已经不用关心它了。 只要关心地址偏移0x3c 处,该处存有 _IMAGE_NT_HEADER 的偏移。在dos header 和 NT header 之间是dos 体,我们也不用关心它了。 _IMAGE_NT_HEADER 到底是什么样呢?它实际是PE00标识+ NT_FILE_HEADER+NT_OPTION_HEADER 以下是它的结构声明。 typedef struct _IMAGE_NT_HEADERS { DWORD Signature; //这里的标记是 PE00 IMAGE_FILE_HEADER FileHeader; //NT header 包含FILE header 和Option header IMAGE_OPTIONAL_HEADER32 OptionalHeader; } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; 问: 2.13 这样对header有了一个总体认识,它占据着文件开始部分。反正它是死的,而且每个文件只有 一个,有上面各个header 的结构定义,无非是存储这一些数据,指针。估计详细分析一下, 它也跑不了了。我们还是抓主要的,主要的分析清了,可能顺便就把头中的相关结构变量分析了。 还是回到节表上来。上次已经找到了节表头,前面说是在OptionalHeader下面,现在也可以 说是在NT header下面。其中以.text 居首,根据节表头结构,从.text 偏移一个节表结构, 我们看到了第二个ascii 字符 “.rdata", 不远的地方还要一个”.data", 正好也偏移一个节表头结构“, 还有一个".rsrc",再往后就是全0了,那么这是否是说,这个结构数组含有4个结构元素呢? 答: 2.13 正是如此,在_IMAGE_FILE_HEADER 中有一项定义了该数值 WORD Machine; //x86 的machine代码是 01 4c (hello.exe 中00c4处) WORD NumberOfSections; // hello.exe 中 是 00 04 与你数的完全一致。对照一下问题1.9的_IMAGE_FILE_HEADER 和 hello.exe 的,你会很容易辨别的。 问: 2.14 我对照过了,知道了它在文件中的位置。干脆把NT FILE Header结构中的其他数据也分析一下吧。反正也不多。 答: 2.14 好,我再把该结构抄过来: typedef struct _IMAGE_FILE_HEADER { WORD Machine; //答2.12已经说了,x86 总是01 4c WORD NumberOfSections; //hello.exe 是00 04 DWORD TimeDateStamp; //时戳。表示你的文件是何时生成的。不过这个DWORD是用秒数表示的。 DWORD PointerToSymbolTable; //调试信息,hello 中为全0 DWORD NumberOfSymbols; //调试信息,hello 中为全0 WORD SizeOfOptionalHeader; //答1.9已经说了,OptionalHeader 大小总是0xe0 WORD Characteristics; // hello.exe 是010F, 看标志有5个bit 是1,那就是说5个属性为真了。 } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; NT FileHeader其它项都好理解,没有什么关键的东西,只有这个属性稍微麻烦一点,最多也不超过16个属性。 顺便问一下,你在ultraedit 中看着这个FILE_HEADER 吗? 代学生:哦哦,看着呢,我的光标就停在这个010F 标志处呢。 代老师: 好,继续。16个属性一下都说出来也太多,先学习hello.exe 的这5个吧。 bit0: 文件不包含重定位信息。 bit1: 文件可以运行。 bit2: 文件不包含行号信息 bit3: 文件不包含符号信息。 bit8: 32bit 机器上运行。 怎样,这你个属性很好理解吧,可执行文件不需要重定位,行号及符号信息。在32bit机器上运行。 代学生: 说了半天原来没有一个关键性东西,我还以为有多神秘呢! 代老师: 是的,搞懂了它有时也觉得失望,其实,懂了也就这么简单。 问:2.15 再问一个关键性问题,看起来有点菜。我以为,有text段,有data段就可以了, 那么.rdata, .rsrc 是干什么用的呢 答:2.15 这个问题确实很关键,这正是PE 文件与以往文件的差别所在。 其实只有text段,data段,pe文件是不可以运行的,因为PE文件的运行总是要调用 系统文件,而系统文件都是以DLL 文件格式存在的,所以你必须要在文件中有动态链接 信息。 问:2.16 太复杂了,什么是动态连接信息,什么是动态连接库,听说过但没有真正理解。 答:2.16 动态连接是多进程操作系统引进的一个概念。在DOS时代,单任务是没有动态连接的。 在DOS 时代,连接器总是把库文件直接连接到可执行文件中。叫静态连接。这种做法 在单任务时是可以接受的,无非是每个连接的文件都包含一个库文件,造成磁盘空间 的一点浪费。 但静态连接在多任务时代不可以接受。例如每个进程都会调用 kernel32.Dll 如果采用静态连接,造成磁盘空间浪费不说,假若系统有20个进程,系统中就将会 有20份kernel32.dll, 内存的浪费将是不可容忍的,动态连接的概念就是保证系统中 只有一份DLL,同时各个进程又都能够很好的运行。好在动态连接是加载器的功能, 我们程序不用刻意去做什么,所以用起来也不是太复杂。 问:2.17 哦!是这样,我原来以为链接程序都把事情处理好了,原来还没有,多进程中还要由 加载器进行动态连接。那我们怎样使用动态连接呢? 答:2.17 当我们用汇编语言或C C++或者其它语言开发是,生成的PE文件对系统库的调用都是 动态连接。我们并没有做什么。 当你想调用自己生成的DLL(第三方DLL),可以采用隐含动态连接或者显示动态连接来 加载DLL. 听起来很炫用起来很简单,隐含链接就跟使用系统dll 一样,你只要在文件 中包含第三方头文件(好引用它的函数啊。)在连接选项里设置第三方的lib,dll位置 链接程序就帮你搞定了。 显示动态连接是在你的程序里用loadlibrary 加载DLL, 用getprocess 获取DLL中函数 地址,然后用函数指针调用第三方函数。 问:2.18 哦. 听你的意思看来使用DLL 也是很简单的。系统DLL使用我们不用管,怎样使用第三方 DLL以后再说吧,我现在的重点是想搞明白PE 的文件格式。 那么既然它调用了 kernel32.Dll 中的函数。而这个函数的地址连接程序不知道,只能由加载器在运行时动态加载。 那么,加载器是怎么知道要加载那个DLL, 要执行DLL中的那个程序呢? 答: 2.18 这个问题问到点子上去了。搞清了这个问题,PE 格式就可以说入门了。 我们还是结合hello.exe 实例说吧。 有HIEW 软件吗,准备一下。 好: 1. 用hiew 打开hello.exe 2. 按F4, 选Decode. 3. 按F5, 敲入偏移400(我们上面分析过,text 段在400) 干脆我把代码贴过来吧, 双// 是我注释的。 00000400: 6A00 push 000 00000402: 6800304000 push 000403000 ;" @0 " 00000407: 680C304000 push 00040300C ;" @0♀" 0000040C: 6A00 push 000 0000040E: E809000000 call 00000041C //hiew 分析出,这是MessageBoxA 00000413: 90 nop 00000414: 90 nop 00000415: 6A00 push 000 00000417: E806000000 call 000000422 //hiew 分析出,这是ExitProcess 0000041C: FF2508204000 jmp d,[00402008] 00000422: FF2500204000 jmp d,[00402000] ; --------------------------------------------------------------------------- 我们分析 call Messagebox 吧。 40e 处: call 41c, 41c 处: jmp ds:[00402008] 00402008. 这是虚拟内存地址。我们用hiew 找到它。具体操作如下: 1. 按F4, 选hex. 要看数据,选hex 合适 2. 按F5, 敲入偏移600. 在hiew 中看到了下一行。 .00402000: 76 20 00 00-00 00 00 00-5C 20 00 00-00 00 00 00 问:2.19 喂,慢点,打扰一下,我这个人就喜欢刨根问底。你怎么知道要敲入600呢? 答:2.19 是这样,调用DLL采用动态连接,动态连接信息是放在.rdata 段,叫只读数据段。 你刚才不是问.rdata, .rsrc 是干什么的吗? 我现在才讲到了.rdata 段 要想知道.rdata 在哪,你的问.rdata 的节表头。我们已经讲过所有节表头组成一个 数组,紧跟在NT Header(总header)之后。.rdata 是第二项节表头,其名字是ascii码 很明显的。 我把它copy 到这啦。 00001e0: 2e72 6461 7461 0000 9200 0000 0020 0000 .rdata....... .. 00001f0: 0002 0000 0006 0000 0000 0000 0000 0000 ................ 0000200: 0000 0000 4000 0040 2e64 6174 6100 0000 ....@..@.data... 这里根据 答1.6中 section header 的结构,可以知道.rdata 的如下信息 名字:.rdata, 虚拟大小:0x92, RVA:0x2000, 文件中大小0x200, 文件偏移0x600 属性,40000040,看来有两个属性有效。bit6 -- 包含初始化数据。bit30 -- 可读属性。 问:2.20 再回到刚才的问题吧。本来想call Messagebox, 由于Messagebox 是user32.dll 中的函数。 汇编器,链接器不知道Messagebox 地址在哪里,PE 文件里翻译的是代码要call 41c, 而41c 处向 402008 地址单元处存储的地址跳跃。由于402008 从文件看来存的是0x205c 看样子要跳到 0x205c 处执行了。 答:2.20 你前面的分析都是对的,但最后一句结论却错了,如果程序真要跳到0x205c 处,肯定会被系统 判你一个操作地址非法,强制你关闭程序。其实这个地方的205c,要被替换成另外的一个数据 这就是Messagebox 在内存的真正地址。谁替换的? 当然就是loader 了,加载器知道你想要 call MessageBox, 就帮你偷偷的把这个链条给拧上了。 代学生: 呀!讲的正精彩呢,怎么又下课了... 代老师: 好了,我们下一课再接着讲。 |
|
[原创]PE 文件格式启发式学习(以hello.exe 为例)(5.15更新)
哟!这么多人支持,感谢大家的厚爱。正好这两天有时间,我的第二篇就贴这里啦! |
|
[原创]PE 文件格式启发式学习(以hello.exe 为例)(5.15更新)
问答的方式...怎么确定你的问题就是别人感兴趣的? 呦,是版主啊,晚上好! 从一个假设对方不懂的地方开始,同时又是问题的关键所在,围绕这一点开始逐步剖析,一步步提出问题,解答问题,直到至少从逻辑上看没有问题为止。那么我认为从最初关键引发点所引发的一系列问题也就基本解决了。而且这里面的所提出的各种问题,正是初学者所碰到的。所以比较贴近他们的口味。我的目的是通过这个简单的hello world 开始,解释清楚每一个细节,那么学习者以后无论从 那一个问题入手,都应该从这个问题链中找到较满意答案。如果跟着教程试一下,进步会更快。 全面理解了这一系列问题对话,(把一个大问题分成了许多小问题),那么PE格式也就掌握了。 另: 对应的hello world参考程序等我发够了10个贴,我会把它贴上去。 这只是开头,该问答系列后面还会有续集,直到完全解释清PE 格式 |
|
[讨论]问个菜鸟级的问题:双机调试有啥特别的好处?
现在很多工具都支持双机调试,甚至连WinDBG以前的版本根本就是以双机调试为主的。 双机调试的好处,一边调试,一边同时看程序的输出,尤其是显示信息,互不干扰。 如果在一个屏幕上,debug的那么多窗口我们只会嫌屏幕小,想看看程序的输出, 按任务条上用户程序按钮,呀,死的,弹不起来,被dbg 挂这呢。如果你非要走到能 弹起来,那已经在运行消息循环了。 |
|
《已解决》《求助》windbg 用户态双机调试问题
该贴解决了windbg 用户态双机调试问题: 不解决windbg 用户态双机调试问题,对不起楼主也对不起读贴的朋友。 点击开始 - 程序 - debugtools for windows - debug help 阅读debugers 章节,当你读啊读,一章章,一篇篇忽然明白它在说什么时 再review 一下相关章节,就可以动手操作了。它不仅可以帮你解决这个文题 还能帮助你解决其它问题。 MS help 文档,我恨它也爱它...,建议你有时间要好好读一读。 言归正转,下面说windbg 用户态双机调试步骤。 有很多方法可以实现用户态双机调试,这只是方法之一。 1. 点击dbg_x86_6.9.3.113.msi安装debug tool,这恨简单,对,两台 机器都安装。我的操作系统都是windows xp,将网络ping 通。 2. 服务器端开启服务进程,运行以下命令。 a: 开启cmd 命令行窗口,进入c:\program files\debuggin tools for windows <x86> b: 执行命令: dbgsrv -t tcp:port=1025 3. 服务器端查看被调试程序的进程ID. 这是方法之一: 右键点击任务条空白处弹出菜单,点击”任务管理器“项。 点击任务管理器窗口菜单”查看“-”选择列“ 选中PID 进程标识符,点击”确定“ 窗口中显出了各进程的”PID", 启动要调试的hello.exe, 查看其PID 为4060,记下这个数字。 4. 客户端启用调试进程windbg,运行以下命令。 a: 开启cmd 命令行窗口,进入c:\program files\debuggin tools for windows <x86> b: 启用windbg,敲入命令: windbg -premote tcp:server="服务器主机名",port=1025 -p 4060 说明一下: -premote, 意思是说,客户端要建立一个smartclientport, 它能于dbgsrv 进程相连接。 tcp 是tcp 协议 ”服务器主机名“,不要逐字敲,要换成你的服务器名字,例如我的是hjj-test,你的是别的名字。 port=1025 是端口号,与服务器的端口号要一样 -p 4060 指要调试的远程端的进程ID, 就是在服务器端查看的那个,记得要修改这个值啊。 当你敲入回车之后,windbg 启动,在它的cmd 窗口里滚过一堆信息,是它在加载dll,然后提示你符号文件没有发现,,我这个运行程序无符号,这里不谈符号问题。然后是 ntdll!DbgBreakPoint: 7c921230 cc int 3 debugger 已经成功断下被调试进程,下面你就可以开始调试拉。 总结一下:你要理解命令行各参数的意义,做相应替换 1. 服务器端:dbgsrv -t tcp:port=“端口号值” 2. 客户端: windbg -premote tcp:server="服务器主机名",port=“端口号值” -p “被调试进程ID" 区区两条命令,搞定windbg 用户态双机调试。这真是会者不难,难者不会,为这两条命令,我可找你好苦啊! 糟啦, 这两天只顾搞调试,都耽误我工作了,赶紧忙去吧。 |
|
《已解决》《求助》windbg 用户态双机调试问题
本帖并没有解决windbg 双机调试问题,但解决了VS2005双机调试问题。 我一定要搞定双机调试问题,还好,首先搞定了VC6 Visual Studio 双机调试。颇有一番曲折,可惜只能调试有代码的程序,不能attatch 上远端的进程,没有源码,VC6的远端调试就不灵了。 听说VS2005 能attatch 远端进程,就转攻VS2005.。 VS2005 双机调试也搞定了,也有一番曲折,相比VC6 要容易一些,由于VS2005 能attatch 远端进程,就把它贴出来吧。 令遇到相同问题的朋友少花点时间。 由于权限不够,我就不贴图了。 (1) 本地: 安装VS2005, 很顺利,不会有问题 启动vs2005, 选菜单tools->attatch to process 在对话框中qualifier(限制)中填入远端主机名例如: pc-test 结果出现错误框,大意是远端服务器msvsmon.exe 没有远行,要我看帮助。 这是意料之中的事。 不过微软的帮助我可不想看。 第二步,我们解决调试服务器的事 (2) 远程端: 运行调试服务器 将本地端的"Program Files\Microsoft Visual Studio 8\Common7\IDE\Remote Debugger\x86\msvsmon.exe" 拷贝到远程端随便一个位置,用u盘, 网络随你便了。要是vc6, 除了远行文件还有一大堆dll要copy 运行msvsmon.exe, 弹出一个警告框,告诉你debug moniter 不能debug 程序,问是否继续, 那就继续吧,果然,进去后,从本地端无论如何也连不上远程端。 看来必须要解决警告框问题。 仔细看一下警告内容,英文不好,猜其大意,是说本地安全策略是"guest only",请求都是 guest,所以必须要解决权限问题。 (3) 远程端:系统权限问题-解除警告框 一大堆的安全选项,到底找谁呢? 结合这提示找吧。这时我在想,如果用英文windows 会好一点,中文还要翻译呀。 最后,将“本地安全策略 - 安全选项 - 网络访问:本地帐户的共享和安全模式”改为:经典-本地用户以自己的身份验证。 这时运行调试服务器,没有警告框了。 但是从本地端还是连接不上,错误提示仍然是:远端服务器msvsmon.exe 没有远行,这就有点奇怪了。 观察Remote debuger monitor 输出,说它启动了一个服务器叫hjj@pc-test, 在本地对话框中qualifier中填入 服务器名hjj@pc-test,出来了另一个错误提示,拒绝访问。 这个错误说明它已经知道服务器再运行,只是服务器拒绝了它。看来还是权限问题 在服务器的tools -- option -- permission 中,折腾一个遍居然加不进本地的机器名。 几乎没有办法了,看帮助文档,昏昏然也没有理解,查百度,也没查清楚。只差最后一步了。。。看来 再看帮助security help, 有一个 windows authentication mode 和 No authentication mode. 看其意思是说 windows authentication mode安全,千万千万别用No authentication mode。 难道就此打住吗? 我相信已经有很多人解决了这个问题了,一定可以解决。剩下的是goole 和help 文档及test了。 微软的帮助确实有点shit, 他要写成象我这样,用不了长篇大论就能让你搞定了。或者至少要有这么一份文档。 (4)远程端: 服务器权限问题,令所有用户访问。 回到服务器,查其option 选项,果然看到默认选择是windows authentication, 我也没办法了,选No authentication mode 还有一个选择框,勾选allow any user to debug. 谁连都欢迎,连不上,安全有什么用! 点ok, 服务器窗口还提示警告 不安全,不安全。。。甭离它。 (5) 本地端:最后的成功,还有点曲折。 在VS2005中,“工具”--“附加到进程”,传输选“远程”, tranport: Default qualifier: 远端主机名(例如pc-test) 或者远端服务器名pc-test:4015 还是连不上,但是出来了新的错误框,前两条是废话,后一条可以借鉴,要求我们把transport 改为 Remote(native only with no authentication), 按它的意思改吧,把qualifier填入远端主机名。 呀!远端进程列表出来了。 欲哭无泪,大半天过去了,5步乃是4步陷阱。帮助文档写得不好,报错机制还可以借鉴。 总结一下: 1. copy msvsmon.exe 到远程机 2. 远程机修改本地安全策略为 “经典-本地用户以自己的身份验证” 3. 远程机msvsmon.exe运行,修改其连接选项为No authentication mode,enable all user 4. 本地机trasport 改为Remote(native only with no authentication)。 5. 本地机qualifier 填写远端主机名。 要是MS 的作品什么都不改,填好远端主机名,端口号,一连就通,拿酒好了。 |
|
[原创] 算法分析入门教程实战篇及应用篇---NBA2005新春大奉送
【软件名称】: CRACK ME 2007之Splish 【软件大小】: 232KB 【下载地址】: PEDIY CRACK ME 2007 序列号 爱在天涯之Splish 下载地址不对头,CRACK ME 2007之Splish 怎样下载呀? |
|
[转帖] 逆向工程初步
OllyDbg 不支持远程调试,显示与调试不能兼而得之,还是觉得不足! |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值