访问作为结构一部分的内存地址的数据

逆向工程 吉德拉
2021-06-27 20:16:02

问题

我有一个某种类型的结构,比如典型 PE 文件开头的 DOS 标头:

/DOS/IMAGE_DOS_HEADER
pack(disabled)
Structure IMAGE_DOS_HEADER {
   0   char[2]   2   e_magic   "Magic number"
   2   word   2   e_cblp   "Bytes of last page"
   4   word   2   e_cp   "Pages in file"
   6   word   2   e_crlc   "Relocations"
   8   word   2   e_cparhdr   "Size of header in paragraphs"
   10   word   2   e_minalloc   "Minimum extra paragraphs needed"
   12   word   2   e_maxalloc   "Maximum extra paragraphs needed"
   14   word   2   e_ss   "Initial (relative) SS value"
   16   word   2   e_sp   "Initial SP value"
   18   word   2   e_csum   "Checksum"
   20   word   2   e_ip   "Initial IP value"
   22   word   2   e_cs   "Initial (relative) CS value"
   24   word   2   e_lfarlc   "File address of relocation table"
   26   word   2   e_ovno   "Overlay number"
   28   word[4]   8   e_res[4]   "Reserved words"
   36   word   2   e_oemid   "OEM identifier (for e_oeminfo)"
   38   word   2   e_oeminfo   "OEM information; e_oemid specific"
   40   word[10]   20   e_res2[10]   "Reserved words"
   60   dword   4   e_lfanew   "File address of new exe header"
   64   byte[64]   64   e_program   "Actual DOS program"
}
Size = 128   Actual Alignment = 1

在地址00400000在存储器中被初始化为装载机的一部分,并具有一定的固定值。它已经在 Ghidra 中定义为一个结构,例如通过一些自动分析。

在此处输入图片说明

现在我想获得例如e_cp“文件中的页面”的值,在这种情况下3,理想情况下作为适当的 Ghidra 数据类型,以防它是指针、地址或更复杂的数据类型。理想情况下,我想通过名称“e_cp”而不是通过对偏移量进行硬编码来访问它。

尝试

getDataAt(currentProgram.imageBase + 4), 返回null, etDataContaining(currentProgram.imageBase + 4)返回整个IMAGE_DOS_HEADER结构的 DataDB 对象

如何在已知地址(即结构的一部分)处获取内存中的实际值?

2个回答

我想获得 e_cp 的值,“文件中的页面”,在这种情况下为 3,理想情况下作为适当的 Ghidra 数据类型,以防它是指针、地址或更复杂的数据类型

您必须使用该getComponent方法访问结构(或数组)的成员,例如在 Kotlin 代码中(很容易更改为 Python 或 Java):

var struct: DataDB = getDataAt(currentProgram.imageBase)
struct.getComponent(2)

这将返回结构的第三个(零索引)组件的值IMAGE_DOS_HEADERdw 3h

理想情况下,我想通过名称“e_cp”而不是通过对偏移量进行硬编码来访问它。

似乎没有直接的方法可以访问结构体我的成员名称。关于成员名称、类型和大小的信息包含在struct.dataType是否Structure可以使用getComponent(与上面不同的方法!):

import ghidra.program.model.data.Structure
var struct: Data = getDataAt(currentProgram.imageBase)
var structType: Structure = struct.dataType as Structure
structType.getComponent(2)

将导致DataTypeComponent对象呈现为: 2 4 word 2 e_cp "Pages in file"

该对象具有fieldName包含该成员名称“e_cp”的属性您可以使用structType.components属性来查找您想要的名称的字段,然后获取对象.ordinal属性DataTypeComponent以获取正确的索引以传递给struct.getComponent

为方便起见,仅在 Kotlin 中您可以定义扩展方法

operator fun Data.get(name: String): Data? {
    if (this.dataType is Structure){
        val s = (this.dataType as Structure)
        val idx = s.components.firstOrNull { it.fieldName == name }?.ordinal
        return idx?.let(this::getComponent)
    }
    return null
}

允许Data使用字符串索引对象,这将在组件中搜索与传递的字符串匹配的字段,并返回适当的组件:

In [1]: getDataAt(currentProgram.imageBase)["e_cp"]
Out[1]: dw 3h

正如我评论的,这就是你要找的吗?

>>> base = getDataContaining(currentProgram.imageBase)
>>> base
IMAGE_DOS_HEADER 
>>> for i in range (0,base.length,1):
...     print ( base.baseDataType.getComponentAt(i).toString() , base.getComponentAt(i))
... 
(u'  0  0  char[2]  2  e_magic  "Magic number"', char[2] "MZ")
(u'  0  0  char[2]  2  e_magic  "Magic number"', char[2] "MZ")
(u'  1  2  word  2  e_cblp  "Bytes of last page"', dw 90h)
(u'  1  2  word  2  e_cblp  "Bytes of last page"', dw 90h)
(u'  2  4  word  2  e_cp  "Pages in file"', dw 3h)
(u'  2  4  word  2  e_cp  "Pages in file"', dw 3h)
(u'  3  6  word  2  e_crlc  "Relocations"', dw 0h)
(u'  3  6  word  2  e_crlc  "Relocations"', dw 0h)
(u'  4  8  word  2  e_cparhdr  "Size of header in paragraphs"', dw 4h)
(u'  4  8  word  2  e_cparhdr  "Size of header in paragraphs"', dw 4h)
(u'  5  10  word  2  e_minalloc  "Minimum extra paragraphs needed"', dw 0h)
(u'  5  10  word  2  e_minalloc  "Minimum extra paragraphs needed"', dw 0h)
(u'  6  12  word  2  e_maxalloc  "Maximum extra paragraphs needed"', dw FFFFh)
(u'  6  12  word  2  e_maxalloc  "Maximum extra paragraphs needed"', dw FFFFh)
(u'  7  14  word  2  e_ss  "Initial (relative) SS value"', dw 0h)
(u'  7  14  word  2  e_ss  "Initial (relative) SS value"', dw 0h)
(u'  8  16  word  2  e_sp  "Initial SP value"', dw B8h)
(u'  8  16  word  2  e_sp  "Initial SP value"', dw B8h)
(u'  9  18  word  2  e_csum  "Checksum"', dw 0h)
(u'  9  18  word  2  e_csum  "Checksum"', dw 0h)
(u'  10  20  word  2  e_ip  "Initial IP value"', dw 0h)
(u'  10  20  word  2  e_ip  "Initial IP value"', dw 0h)
(u'  11  22  word  2  e_cs  "Initial (relative) CS value"', dw 0h)
(u'  11  22  word  2  e_cs  "Initial (relative) CS value"', dw 0h)
(u'  12  24  word  2  e_lfarlc  "File address of relocation table"', dw 40h)
(u'  12  24  word  2  e_lfarlc  "File address of relocation table"', dw 40h)
(u'  13  26  word  2  e_ovno  "Overlay number"', dw 0h)
(u'  13  26  word  2  e_ovno  "Overlay number"', dw 0h)
(u'  14  28  word[4]  8  e_res[4]  "Reserved words"', dw[4] )
(u'  14  28  word[4]  8  e_res[4]  "Reserved words"', dw[4] )
(u'  14  28  word[4]  8  e_res[4]  "Reserved words"', dw[4] )
(u'  14  28  word[4]  8  e_res[4]  "Reserved words"', dw[4] )
(u'  14  28  word[4]  8  e_res[4]  "Reserved words"', dw[4] )
(u'  14  28  word[4]  8  e_res[4]  "Reserved words"', dw[4] )
(u'  14  28  word[4]  8  e_res[4]  "Reserved words"', dw[4] )
(u'  14  28  word[4]  8  e_res[4]  "Reserved words"', dw[4] )
(u'  15  36  word  2  e_oemid  "OEM identifier (for e_oeminfo)"', dw 0h)
(u'  15  36  word  2  e_oemid  "OEM identifier (for e_oeminfo)"', dw 0h)
(u'  16  38  word  2  e_oeminfo  "OEM information; e_oemid specific"', dw 0h)
(u'  16  38  word  2  e_oeminfo  "OEM information; e_oemid specific"', dw 0h)
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  17  40  word[10]  20  e_res2[10]  "Reserved words"', dw[10] )
(u'  18  60  dword  4  e_lfanew  "File address of new exe header"', ddw 108h)
(u'  18  60  dword  4  e_lfanew  "File address of new exe header"', ddw 108h)
(u'  18  60  dword  4  e_lfanew  "File address of new exe header"', ddw 108h)
(u'  18  60  dword  4  e_lfanew  "File address of new exe header"', ddw 108h)
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )
(u'  19  64  byte[64]  64  e_program  "Actual DOS program"', db[64] )