|
这两行十六进制转成汇编语言是什么?
ollydbg 的强项是调试,做内存copy 还不太方便。winhex 在这方面功能很强,像楼上所说先用 winhex 把你要反汇编内容构造成一个二进制文件。如果想看它的反汇编码,建议你用hiew 吧。 打开该文件,你可以text,hex,及代码三种模式切换。 不明白你取到16进制hex码后的具体意图,做个参考吧。 |
|
[求助]以下汇编代码何解?(很短,就几行)
该代码中关于SEH 部分注释: SEH 链基于如下结构 _EXCEPTION_REGISTRATION struc prev dd ? handler dd ? _EXCEPTION_REGISTRATION ends 就是说,前面一个Double word 是旧的Exeption Handle, 后面一个是新的Execption Handle Exeption Handle 的链头存在FS:[0] 位置处。 注意,在栈中,先入栈在高地址,故handler 被先入栈,旧handler 后入栈。 现在标注一下代码 push -1 push eax ;新handler mov eax, dword ptr fs:[0] push eax ;旧handler mov eax, dword ptr [esp+C] mov dword ptr fs:[0], esp ;重设Exception 链表头, 至此exception 链表更改完成 mov dword ptr [esp+C], ebp lea ebp, dword ptr [esp+C] push eax 其它未标注部分,与Exception 无关, 与你的编译语言有关,像是对栈帧的操作,它把[ebp+c]内容存入栈顶,而把ebp存入[esp+c]处,不具有通用性。 |
|
|
|
[求助]怎样用OD查找基地址
百折不挠 mov dword ptr [eax+38],ecx //比如:eax此时为00751F58 在该处按shift-F2, 在弹出的窗口中输入条件eax=0x00751f58 希望这个能救你的眼睛! 呵呵! |
|
[讨论]WIN32 API 函数除了wsprintf需要调用者平衡椎栈外,还有printf,sprintf这些也是吧?
这里只说一下方法,具体结果需要实验确定。 1. #define PASCAL __stdcall, 首先要确定该宏是否有效, VC 的宏经常被一些条件编译选项包围着 所以当你看到一个宏时,它并不一定能起作用。 2. 你可以写个小程序实验一下,把它那句话屏蔽掉, 或者放到自己的头文件等, 预祝你能成功得到答案! 3. pascal 和 _stdcall 调用肯定是不一样的,要不为啥起两个名字呢。 |
|
[原创]PE 文件格式启发式学习2(以count.dll为例)
再传一次,不知为什么没传上。 |
|
[求助]问一个关于PE文件格式的问题
7604 是RVA 值, 6A04 是OFFSET 值 对于notepad 而言,它的RVA 到offset 的转换是这样的 节表中指定 RVA 1000 对应file OFFSET 400 故: RVA 7604 = 0x7604 - 0x1000 +0x400 = 0x6a04 |
|
[原创]PE 文件格式启发式学习2(以count.dll为例)
传上附件供参考 |
|
[原创]PE 文件格式启发式学习2(以count.dll为例)
问5.7: dll 和 exe 文件都是PE 文件, 在PE 文件中是怎样区分的呢? 答5.7:有一些小差别。 例如, exe 通常被加载到0x400000, 而dll 默认加载是0x10000000 exe 通常不含reloc 段,而dll 包含。 exe 通常不含export 段, 而dll 包含。 exe 属性010f, 最后1bit 说它没有重定位信息 dll 属性210e. 最高位的2 说它是dll, 这个好像是最关键差别了吧。 问5.8:exe 的 entrypoint 是程序执行的起始点,dll 的 entrypoint 是什么呢? 答5.8:这个地方是dll 的入口函数地址,它是不可以省略的。 dll 在加载,卸载以及线程加载,卸载时都会 到这里执行程序。 它的通用结构是这样的。 BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpReserved) { switch(fswReason) case DLL_PROCESS_ATTACH ...... case DLL_THREAD_ATTACH ..... case DLL_THREAD_DETACH ..... case DLL_PROCESS_DETACH .... return (TRUE or False) // true , 成功,false 失败, loader 会把它从内存卸掉。 } count.dll 中没有按这种结构,它只是简单的返回一个TRUE,因为它不需要申请内存和释放内存等初始化操作。 count.dll entrypoint 是10001000, PE 标识后第10 DWORD 地址,记不住用工具查。 问5.9:前面说过dll 有入口函数, 导出函数和非导出函数。又回到上次未讲的问题 导出表是怎样把函数导出的。 答5.9:我们先猜一猜导出函数的关键要素吧。 1. 导出库名称 2. 函数导出序号。(提供序号导出) 3. 导出函数名 (提供函数名导出) 4. 序号或函数名对应的地址。 它向系统报告这些信息已经足够了。 问5.10: 结合例子和结构定义具体说一下吧。 答5.10: 看count.dll 目录项第一项 00000130 60 20 00 00 5C 00 00 00 ` ..\... 位置 RVA 2060 == offset 660 大小 0x5c 00000660 00 00 00 00 F6 34 EB 3C 00 00 00 00 9C 20 00 00 ....??....?.. 00000670 01 00 00 00 02 00 00 00 02 00 00 00 88 20 00 00 ............?.. 00000680 90 20 00 00 98 20 00 00 46 10 00 00 23 10 00 00 ?..?..F...#... 00000690 A8 20 00 00 B2 20 00 00 00 00 01 00 43 6F 75 6E ?..?......Coun 000006A0 74 65 72 2E 64 6C 6C 00 5F 44 65 63 43 6F 75 6E ter.dll._DecCoun 000006B0 74 00 5F 49 6E 63 43 6F 75 6E 74 00 t._IncCount. 那么这是一个什么样的数据结构呢?我们先猜猜看,这里也叫逆向学习方法吧。 首先函数名称:count.dll(offset 69c), 函数名称_DecCount(offset 6a8), _IncCount(6b2) 都已经看到了。 转换为RVA. offset 69c =RVA 209c offset 6a8 =RVA 20a8 offset 6b2 =RVA 20b2 很高兴在数据中找到了9c 20, a8 20, b2 20. 关注一下这些地址。 从660 在滤一下,感觉后面的00000002 可能是个数吧。 后边的2088, 2090,2098 RVA 2088 == offset 688 [688] == 46 10 00 00 23 10 00 00 // 像函数地址,赶紧确认一下(在上一篇),正是。 RVA 2090 == offset 690 [690] == A8 20 00 00 B2 20 00 00 // 函数名称地址 RVA 2098 == offset 690 [690] == 00 00 01 00 // 像hint 这样划分后,看不懂的就不多了,学习数据结构是时候了。 typedef struct _IMAGE_EXPORT_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Name; DWORD Base; DWORD NumberOfFunctions; DWORD NumberOfNames; DWORD AddressOfFunctions; // RVA from base of image DWORD AddressOfNames; // RVA from base of image DWORD AddressOfNameOrdinals; // RVA from base of image } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; 我们分析的是对的,那个base 是什么东西 ?是导出函数的基序号。所以导出函数序号不是0,1,而是1,2 了 很明显,1指的是1046地址,2指的是1023地址 问5.11 再总结一下导出表吧。 答5.11 导出表有两种导出方法,一种是按名称导出,一种是按序号导出。其中序号导出的个数总是大于等于名称导出的个数。 导出的函数地址按4字节一字排开。每一个函数索引号就是+Base 值就是导出序号。 序号不直观,所以有些函数用名称导出,名称导出最终还是要找到函数序号。所以把名称所在的名称数组的位置为索引 去从名称序号数组中拿到序号(此为索引号),由索引号取到函数地址。 问5.12 假如loader 要插桩本函数 _IncCount 地址,它是怎样操作的。 答5.12 1. 它首先要加载我们的dll. 用loadlibrary 2. 找到我们的导出表。 3. 再找到导出表中AddressOfNames。 4. 遍历该表找到_IncCount 函数,记下它的索引 5. 从AddressOfNameOrdinals数组中,取到该索引对应的函数地址序号 6. 从导出表中找到AddressOfFunctions, 用得到的序号去取到它的地址。 7. 将该地址去填充到IAT 的对应位置上。 这样插桩就完成了。哇!这个小插桩要经过这么多步骤哇,有没有办法简化一下啦... 等着你去实现呢! 问5.13 count.dll 中还有一个reloc 节,讲讲它是怎样构成的。 答5.13 reloc 也是为text 段服务的,前面说过,若dll 加载到它默认位置,可以不用reloc 段。 当不能加载到默认地址时, 某些于地址有关的指令需要重新定位。就是说要修改指令中地址 使其指向正确的地址。 看目录项中reloc 表,第6个表(索引号为5): 00000160 00 40 00 00 18 00 00 00 .@...... RVA 4000 = offset 800, size=0x18 哦,纵使不用reloc 目录项,直接目视也看见它了。这个程序很小,是这样的。 00000800 00 10 00 00 18 00 00 00 28 30 2E 30 3E 30 4B 30 ........(0.0>0K0 00000810 51 30 61 30 6C 30 00 00 00 00 00 00 00 00 00 00 Q0a0l0.......... 我们也像export 表一样,先猜猜reloc 结构应该有那些重要元素。 1. 内存地址, 4byte, 我们要知道对哪的指令进行重定位。即where 问题 2. 替换方法。 是替换一字节,2字节还是4字节, 是how 的问题,估计有几个bit 就够了。 3. 用什么替换。 是一个what 的问题。 这个问题就不用考虑了,这个what,就是加载地址与默认地址偏移。 这样看起来一个reloc 项至少也要 5 bytes 了。如果有很多项,那这很多项就构成一个数组。 我这里介绍的方法是一种逆向的学习方法,或者是原始的思考方法。因为我想最初设计这个PE 结构的人也会 这么想。 现在使用的PE 结构在这个想法的基础上进行了优化,使得reloc表占用较少的字节, 具体说是它让一个reloc 项占用2byte,下面看它的方法: 1. typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; DWORD SizeOfBlock; } IMAGE_BASE_RELOCATION; 它的意思是说,它要重定位VirtualAddress=1000这块区域, 该区域所占的重定位信息大小为SizeOfBlock=0x18 后面紧跟的每2 个bytes 构成一个重定位项, 其中低12 bit为重定位地址, 高4bits 为重定位类型。 我这里把重定位类型copy 过来,其中有的在x86 上是用不到的。 // // Based relocation types. // #define IMAGE_REL_BASED_ABSOLUTE 0 #define IMAGE_REL_BASED_HIGH 1 #define IMAGE_REL_BASED_LOW 2 #define IMAGE_REL_BASED_HIGHLOW 3 #define IMAGE_REL_BASED_HIGHADJ 4 #define IMAGE_REL_BASED_MIPS_JMPADDR 5 #define IMAGE_REL_BASED_SECTION 6 #define IMAGE_REL_BASED_REL32 7 #define IMAGE_REL_BASED_MIPS_JMPADDR16 9 #define IMAGE_REL_BASED_IA64_IMM64 9 #define IMAGE_REL_BASED_DIR64 10 #define IMAGE_REL_BASED_HIGH3ADJ 11 地址只有12为意味着你只能管理4K 范围,是的,如果超过了4K范围,我们重新定义一个IMAGE_BASE_RELOCATION 变量就可以了,它又能管理下一个4K的范围。后续没16bit 为一个reloc 项, 最尾部以0000 结尾。当然,由于 重定位块大小有定义,纵使不用0000标识结尾也没有问题,把这里的冗余姑且叫双保险吧,就是浪费了2bytes count.dll 中,我们先算算有几个重定位项。哦,不用算,有7个,一查就查出来了。 但当程序大的时候还是要计算的。(0x18-8)/2-1=7 个。 计算公式:(SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/2-1 问:5.14 那这7个重定位项到底是怎样重定位的呢?还是给出具体结果更彻底。 答:5.14 好,做事做到底,现在我们就开始吧。 第一项:28 30 其内容为 0x3028 重定位类型为3, 地址为0x28 其它重定位类型都是3, 地址不同而已。 #define IMAGE_REL_BASED_HIGHLOW 3 那么这个BASE_HIGHLOW 是什么意思呢?我们先看看0x28处的指令。 10001026 FF0500300010 inc [L10003000] 假如我们的dll 不是被加载到0x10000000,而是加载到0x30000000, 即向上提高了0x20000000 我们只要把0x28地址处也加上0x20000000,就可以了。这样这条指令就变成了 10001026 FF0500300030 inc [L30003000] 看明白了吧! 窗户纸就是这样被捅破的 好了,本帖就到这里结束吧! |
|
[求助]OD里面修改了代码后,找不到 《所有修改》 这个 功能
确实有这种情况,可能是ollydbg 的bug 这是需要记录下你的修改,用别的工具改文件了。 例如:ultraeidt, hiew,winhex 等,不过需要RVA 到offset 的转换 |
|
[原创]OllyDBG分析报告系列(5)---内存补丁
好贴! 顶,先赞后读。 |
|
[原创]PE 文件格式启发式学习(以hello.exe 为例)(5.15更新)
感谢各位的支持。 hello.exe 的PE 是讲完了,但只是涵盖了PE 的头文件,节表,导入表部分。再补充上导出表, 资源表就比较完善了,现在时间比较忙,抽空我会继续补上的。 |
|
[原创] cmd.exe 逆向分析
最初由 better 发布,改天你去试试explorer.exe,(好像OD会挂调,是线程太多了吧/),也是CreateProcessW 首先感谢各位朋友的支持,你们的支持是我动力的源泉。 然后回答上面问题: explore.exe 是系统关键进程,用ollydbg 调试挂起explore.相当于你中断了它的正常功能。 使原explore 的功能受到影响。 调试explore,调试全屏幕程序,调试内核等可以采用双机调试。windows系统下可以用windbg 可惜ollydbg 不支持双机调试,真希望它后续的版本中能加上。 windbg 环境建立我有一篇帖子,搜一下“windbg 用户态双机调试”可找到。只可惜我只是 建立了调试环境,windbg进一步的使用却没有时间进一步研究. 双机调试的经验我是从linux gdb 获得的。 所以才斗胆说上面的话。 |
|
|
|
[原创]PE 文件格式启发式学习(以hello.exe 为例)(5.15更新)
tycp 我想是这样的,正常的文件都是VirtualSize <= SizeOfRawData. 当然,你可以把VirtualSize 用PE loader 之类工具强制把它VirtualSize 改大,当然后面的节位置 可能都的移动。 这样做的目的肯定是别有用心的,例如你有XXX企图。 很多加壳的程序VirtualSize 》 SizeOfRawData ,它们是有企图的,所以它们的section 也跟正常的不一样。 |
|
[原创]PE 文件格式启发式学习(以hello.exe 为例)(5.15更新)
我有个小问题,一直是我迷惑的地方! 文件的大小是以块对齐的,512字节(0x200) 内存的大小是以页对齐的,4096字节(0x1000) 文件text 段节数据会全部映射到内存,所以内存至少也会占用4096bbytes text 段再内存中所占内存大小总是大于文件所占空间大小是对的。 此处的 VirtualSize 并没有按页对齐, 而是text 段中有效的数据, 即不包括后面的 一堆0 此处 SizeOfRawData 却是按块对齐的,即总是512字节的倍数 hello 是个很小的程序,所以其有效数据小于512字节 ,这就是你看到的现象 另外我有一个问题, 引用某人发言时, “最初由 *** 发布” 我怎么加不上呢? 不会是手工敲入的吧? |
|
[原创]PE 文件格式启发式学习(以hello.exe 为例)(5.15更新)
初级会员 我估计该贴的40% 都在讲这个问题,从第二讲末尾到第四讲结束 |
|
[原创]PE 文件格式启发式学习(以hello.exe 为例)(5.15更新)
接问题3.30后的第31个问题 问4.31: 上回谈到目录项,有两个目录项要关心。 1. 导入表:RVA=0x2010, size=0x3c 2. 导入地址表(俗称IAT): RVA=0x2000,size=0x10 具体什么用途呢? 答4.31: 先看IAT表,loader要做的工作是把RVA=0x2000,size=0x10这么大范围的DWORD 都要重新定址。如果是00 00 00 00 就不用了。 对hello.exe 而言文件偏移是:(今后RVA 和 OFFSET 的转换我就不再提了) 0000600: 7620 0000 0000 0000 5c20 0000 0000 0000 v ......\ ...... 再看导入表RVA=0x2010, offset=610. size=0x3c,内容如下: 0000610: 5420 0000 0000 0000 0000 0000 6a20 0000 T ..........j .. 0000620: 0820 0000 4c20 0000 0000 0000 0000 0000 . ..L .......... 0000630: 8420 0000 0020 0000 0000 0000 0000 0000 . ... .......... 0000640: 0000 0000 0000 0000 0000 0000 这里是一个结构数组。该结构叫导入表的描述符 typedef struct _IMAGE_IMPORT_DESCRIPTOR { union { DWORD Characteristics; // 0 for terminating null import descriptor DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA) }; DWORD TimeDateStamp; // 0 if not bound, DWORD ForwarderChain; DWORD Name; DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses) } IMAGE_IMPORT_DESCRIPTOR; 每个结构包含5个DWORD 成员,最后一个结构,成员全是0 结构中第二个TimeDateStamp,第三个成员ForwarderChain不用关心,它们总是0 name 变量: 第一个结构中为206A, 对应文件偏移66A, "user32.dll" 第二个结构中为2084, 对应文件偏移684 "kernel32.dll" FirstThunk 地址: 第一个结构中为2008, 对应文件偏移608, //我们看到这个就是IAT 表的内容了 第二个结构中为2000, 对应文件偏移600,//我们看到这个就是IAT 表的内容了 OriginalFirstThunk 地址: 第一个结构中为2054, 对应文件偏移654, //654与608 存储的内容是一样的 第二个结构中为204c, 对应文件偏移64c,//64c与600 存储的内容是一样的 怪不得一个叫first thunk, 一个叫OriginalFirstThunk,原来所指地址处包含的内容是一样的. 0000640: 0000 0000 0000 0000 0000 0000 7620 0000 ............v .. 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 导入描述符有2个,说明它有两个DLL 要导入,从Name 能看出来, 第一个叫"user32.dll", 第二个叫"Kernel32.dll" 描述符的 FirstThunk, 指向一个导入函数地址数组,就叫thunk data数组吧,该数组最后一项为00000000 描述符的 OriginalFirstThunk ,虽然与FirstThunk所指地址不同,但该地址所包含的内容却一样。 以第一个结构为例: 这个DWORD 数组为5c20 0000 0000 0000 ,这个数组只有两项,去掉末尾标志项,只有一项,说明 只有一个函数要导入。怎么导入,在这个地方,我们以0x205c 为例, 把3.23中叙述过的导入过程补充完整。 1. loader 从目录第二项得到 Import Table(导入表) 2. 导入表是一个导入描述符结构数组,以第一个结构为例 从名字项中它知道,这个动态库的名字叫 "user32.dll" 。 3. first thunk 指向thunnk data数组,是一个以全0结尾的DWORD 数组, 非全0 的元素或者是一个RVA(最高位为0),指向一个Import_BY_NAME结构, 或者是一个Ordinal(序号,(其最高位为1,使用时把最高位去掉就成序号啦)。 first thunk 指针属于IAT 表的地址范围。 hello.exe 中import第一个描述符 first thunk表偏移是608,608处存205c(RVA) 对应Import_BY_NAME MessageBoxA, 下一个DWORD=0数组就结束了 说明user32.dll 只导入了一个函数。 从上面分析可以看出。 目录项中的导入地址表:指向一个大的IAT。 目录项中的导入表: 指向一个导入描述符数组。每一个描述符,描述一个DLL。 而FirstThunk 指向那个大的IAT中的一个部分。我们称它为thunk data数组,数组最后一个元素DWORD为全0. 这样的一个设计结构,导入表和导入地址表的信息是有冗余的。我们不管它,知道就行了。 问:4.32 既然有了 FirstThunk, 还要 OriginalFirstThunk 干什么? 它们指向的IAT 内容都是一样的。 答:4.32 FirstThunk 所指向的IAT, 会在加载时被loader 修改为真实的函数地址。而OriginalFirstThunk 所指向的 IAT 是不会被修改的 。其实我也认为,留着这个 OriginalFirstThunk 没有用途,可能是微软认为那个IAT 已经被修改了, 万一你要再用你到拿找哇。 其实我看这是多虑了, 第一 ,IAT用完了我不会再用它。 第二, 万一被我们改了回头又要用,我们可以先把没改之前的备份一下呀。 不过,这都是个人意见,人家这么定义了,我们知道就行了。 问:4.33 从运行的角度来看,好像没有问题了,.text 段依靠.rdata段的帮助,由loader 修改为可执行代码。代码 执行时读取或存入数据段数据。hello 就可以运行了。 那.rsrc 段是什么呢 ? 是资源段吗? 答:4.33 是的。 本来我是没想加这个资源段的。可是不小心给加上了。这个其实你可以不用关心它的。 解开附件hello.rar, 图标是一个笑脸,这就是那个资源段的功能。如果没有那个资源段。默认的图标是一个WINDOWS ICON. 问:4.34 要想显示需要的图标,需要我们做什么呢? 答:4.34 你只要把ICON资源文件连进去就行了,代码并不需要做任何事情。在创建MessageBox 窗口时,系统发现你文件里有一个ICON 资源项,就替你把它画出来,如果你没有包含ICON 资源,它就把自己手边的那个叫默认ICON,画到MessagBox 左上角了。 问:4.35 hello.exe 文件都分析完了,只是option header 中还有一些项没有提到,它们重要吗? 大:4.35 有些项还是很重要的,例如程序入口点,但它们都已经很好理解了。 这里,我就把option 做一个标注,此时再浏览option header 的各个项,已经是时候了。 // // Optional header format. // typedef struct _IMAGE_OPTIONAL_HEADER { // // Standard fields. // WORD Magic; // NT HDR32 定义为010b BYTE MajorLinkerVersion; //link version 不重要 BYTE MinorLinkerVersion; DWORD SizeOfCode; //代码段大小 DWORD SizeOfInitializedData; //初始化数据大小 DWORD SizeOfUninitializedData; //未初始化数据大小 DWORD AddressOfEntryPoint; //程序入口点: 重要 DWORD BaseOfCode; //代码基址(RVA) DWORD BaseOfData; //数据基址(RVA) // // NT additional fields. // DWORD ImageBase; //模块基址 DWORD SectionAlignment; //内存对齐调整 DWORD FileAlignment; //文件对齐调整 WORD MajorOperatingSystemVersion; //版本信息,不重要 WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; //模块的大小 DWORD SizeOfHeaders; //header的大小 DWORD CheckSum; //未使用 WORD Subsystem; //02 为gui, 03 是console WORD DllCharacteristics; //dll 用 DWORD SizeOfStackReserve; //系统加载堆和栈初始化信息 DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags;z // 不重要 DWORD NumberOfRvaAndSizes; // 总是16 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; //16个目录,重要 } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; optionheader 重要的项是程序入口点,目录项。 optionheader 中标注不重要的就不用关心了。 下面的项重要程度中等,了解一下就可以了。 1.SizeOfHeaders 是文件头和节表大小之和。所以其后面紧跟段地址,该数值应与节表中第一节数值匹配。 2.BaseOfCode,SizeOfCode, 该数值与节表中代码节的文件大小也是一致的,有多余之嫌。 3.SizeOfInitializedData 已初始化的数据组成的块的大小.但我不知道它有什么用。 4. ”.bss" 段:给loader 参考的。 加载器在虚拟内存中申请空间,但在磁盘上的文件中并不占用空间的块的尺寸。 这些块在程序启动时不需要指定初值,因此术语名就是"未初始化的数据"。未初始化的数据通常在一个名叫 .bss 的块中。 BaseOfData,已载入映像的未初始化数据(“.bss”段)的相对偏移量 SizeOfUninitializedData。 申请的".bss" 空间的大小。当为0时,表示没有使用".bss"段 问:4.36 能总结一下PE 文件的重要项吗? 答:4.36 从运行的角度看,PE文件中重要的是程序入口点,节表,目录项。 代学生:感谢你为我们写了这么多东西。 代老师:大家共同提高。由于时间仓促,水平有限,有些观点未必正确,错误之处在所难免,希望海涵并欢迎指正。 全文完。 |
操作理由
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 }}
勋章
兑换勋章
证书
证书查询 >
能力值