汇编中结构参数的字段是如何排序的?
How fields of strucure arguments in assembly are ordered?
我有一个 excel 脚本,它从 DLL 文件调用一个函数。我已经打开了 DLL 文件,但我对它的了解不多。
excel脚本定义了以下结构:
Public Type Product
price As Double
size As Double
isExpensive As Boolean
isCheap As Boolean
isVerified As Boolean
isPacked As Boolean
isDelivered As Boolean
End Type
Public Type Pricing
value1 As Double
value2 As Double
value3 As Double
value4 As Double
End Type
Public Type Receipt
price As Double
location_x As Double
location_y As Double
time As Double
gross_weight As Double
special_weight As Double
discount As Double
dispatched As Boolean
paid As Boolean
End Type
Public Type Location
reputation As Double
id As Long
staffs As Long
location_x As Double
location_y As Double
working_weekends As Boolean
ventilated As Boolean
End Type
Public Type Output
future_week1 As Double
future_week2 As Double
future_week3 As Double
future_week4 As Double
future_week5 As Double
future_week6 As Double
future_week7 As Double
future_week8 As Double
future_week9 As Double
future_week10 As Double
future_week11 As Double
future_week12 As Double
future_week13 As Double
future_week14 As Double
future_week15 As Double
future_week16 As Double
future_week17 As Double
future_week18 As Double
End Type
并调用以下函数
EstimateFuture myProduct, pricing1, pricing2, receipt1, location, myoutput
此函数接收 myProduct
、pricing1
、pricing2
、receipt1
和 location
作为输入,并将输出放入 myoutput
.
不管这些结构设计得好不好。我需要了解每个字段在内存中的顺序。
估算函数的汇编开头如下:
EstimateFuture:
push ebp
mov ebp,esp
and esp,FFFFFFF8h
sub esp,000000A0h
push esi
mov esi,[ebp+08h]
push edi
mov ecx,0000000Ch
mov edi,L1000F198
rep movsd
mov esi,[ebp+0Ch]
mov ecx,00000008h
mov edi,L1000F250
rep movsd
mov esi,[ebp+10h]
mov ecx,00000008h
mov edi,L1000F208
rep movsd
mov esi,[ebp+14h]
mov ecx,00000010h
mov edi,L1000F1C8
rep movsd
mov esi,[ebp+18h]
mov ecx,0000000Ah
mov edi,L1000F228
rep movsd
...
显然上面的代码试图将参数存储到它的内存中。这里我们有六个参数和五个 rep movsd
。可能是因为输入了五个变量而最后一个没有。
但我不明白的是,地址与变量完全不匹配。既不是根据它们的大小,也不是根据它们的标签分割。无论参数是以直接方式还是反向方式存储,它们都与以下地址不匹配:
L1000F198:
dq 0000000000000000h
L1000F1A0:
dq 0000000000000000h
L1000F1A8:
db 00h;
db 00h;
db 00h;
db 00h;
L1000F1AC:
db 00h;
db 00h;
L1000F1AE:
db 00h;
db 00h;
db 00h;
db 00h;
L1000F1B2:
db 00h;
db 00h;
L1000F1B4:
db 00h;
db 00h;
db 00h;
db 00h;
L1000F1B8:
dq 0000000000000000h
L1000F1C0:
dq 0000000000000000h
L1000F1C8:
dq 0000000000000000h
L1000F1D0:
dq 0000000000000000h
L1000F1D8:
dq 0000000000000000h
L1000F1E0:
dq 0000000000000000h
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F1F0:
dq 0000000000000000h
L1000F1F8:
dq 0000000000000000h
L1000F200:
db 00h;
db 00h;
L1000F202:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F208:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F210:
dq 0000000000000000h
L1000F218:
dq 0000000000000000h
L1000F220:
dq 0000000000000000h
L1000F228:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F230:
dd 00000000h
L1000F234:
dd 00000000h
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F240:
dq 0000000000000000h
L1000F248:
db 00h;
db 00h;
L1000F24A:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F250:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F258:
dq 0000000000000000h
L1000F260:
dq 0000000000000000h
L1000F268:
dq 0000000000000000h
L1000F270:
dd 00000000h
L1000F274:
db 00h;
db 00h;
db 00h;
db 00h;
L1000F278:
dd 00000000h
L1000F27C:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F284:
dd 00000000h
L1000F288:
dd 00000000h
db 00h;
db 00h;
db 00h;
db 00h;
L1000F290:
dd 00000000h
L1000F294:
db 00h;
db 00h;
db 00h;
db 00h;
L1000F298:
db 00h;
db 00h;
db 00h;
db 00h;
我不知道这个 DLL 文件的原始语言,也不知道编译器的名称或版本。
有人可以帮我填一下这个谜题吗?
address of myProduct.price = ?
address of myProduct.size = ?
address of myProduct.isExpensive = ?
address of myProduct.isCheap = ?
address of myProduct.isVerified = ?
address of myProduct.isPacked = ?
address of myProduct.isDelivered = ?
address of pricing1.value1 = ?
address of pricing1.value2 = ?
address of pricing1.value3 = ?
address of pricing1.value4 = ?
address of pricing2.value1 = ?
address of pricing2.value2 = ?
address of pricing2.value3 = ?
address of pricing2.value4 = ?
address of receipt1.price = ?
address of receipt1.location_x = ?
address of receipt1.location_y = ?
address of receipt1.time = ?
address of receipt1.gross_weight = ?
address of receipt1.special_weight = ?
address of receipt1.discount = ?
address of receipt1.dispatched = ?
address of receipt1.paid = ?
address of location.reputation = ?
address of location.id = ?
address of location.staffs = ?
address of location.location_x = ?
address of location.location_y = ?
address of location.working_weekends = ?
address of location.ventilated = ?
address of myoutput.future_week1 = ?
address of myoutput.future_week2 = ?
address of myoutput.future_week3 = ?
address of myoutput.future_week4 = ?
address of myoutput.future_week5 = ?
address of myoutput.future_week6 = ?
address of myoutput.future_week7 = ?
address of myoutput.future_week8 = ?
address of myoutput.future_week9 = ?
address of myoutput.future_week10 = ?
address of myoutput.future_week11 = ?
address of myoutput.future_week12 = ?
address of myoutput.future_week13 = ?
address of myoutput.future_week14 = ?
address of myoutput.future_week15 = ?
address of myoutput.future_week16 = ?
address of myoutput.future_week17 = ?
更新
感谢matan7890,现在我知道myProduct
的地址在L1000F228
:
L1000F228:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F230:
dd 00000000h
L1000F234:
dd 00000000h
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F240:
dq 0000000000000000h
L1000F248:
db 00h;
db 00h;
L1000F24A:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
意思是:
address of myProduct.price = L1000F228 (8 bytes)
address of myProduct.size = L1000F230 (8 bytes)
address of myProduct.isExpensive = L1000F238 (4 bytes) -----> No Label
address of myProduct.isCheap = L1000F23C (4 bytes) -----> No Label
address of myProduct.isVerified = L1000F240 (4 bytes)
address of myProduct.isPacked = L1000F244 (4 bytes) -----> No Label
address of myProduct.isDelivered = L1000F248 (4 bytes)
这里,问题是 myProduct.isExpensive
、myProduct.isCheap
和 myProduct.isPacked
的开头没有标签。
其他问题是
myProduct.price
由 8 个单字节组成,而不是单个 8 个字节。
myProduct.size
必须是 8 个字节,但在 4 个字节之后引入另一个标签。
标签似乎没有放在正确的位置。
首先,请注意您传递的参数的顺序与您在堆栈中的想法相反。例如,您的第一个变量 myProduct
在 [ebp+18h]
中。
此外,请注意 vb Boolean
是 4 个字节而不是 1 个字节。因此,您的产品类型是 36 个字节,Pricing
是 32 个字节,依此类推。 movsd
操作码一次复制 4 个字节(双字)。通过阅读 rep
s,您的参数似乎顺序不正确,因为第二个参数复制 64 个字节(4 * 10h == 4 * 16 = 64),就像您的 Receipt
类型.似乎参数的正确顺序,仅通过参考所需的大小,是:
EstimateFuture myProduct, receipt1, pricing1, pricing2, location, myoutput
这意味着 myProduct
似乎在 L1000F228 和接下来的 40 个字节中。请注意,您的结构只有 36 个字节,这意味着您可能缺少该类型中的一个 Boolean
成员。
从这里你可以自己计算:)
我有一个 excel 脚本,它从 DLL 文件调用一个函数。我已经打开了 DLL 文件,但我对它的了解不多。
excel脚本定义了以下结构:
Public Type Product
price As Double
size As Double
isExpensive As Boolean
isCheap As Boolean
isVerified As Boolean
isPacked As Boolean
isDelivered As Boolean
End Type
Public Type Pricing
value1 As Double
value2 As Double
value3 As Double
value4 As Double
End Type
Public Type Receipt
price As Double
location_x As Double
location_y As Double
time As Double
gross_weight As Double
special_weight As Double
discount As Double
dispatched As Boolean
paid As Boolean
End Type
Public Type Location
reputation As Double
id As Long
staffs As Long
location_x As Double
location_y As Double
working_weekends As Boolean
ventilated As Boolean
End Type
Public Type Output
future_week1 As Double
future_week2 As Double
future_week3 As Double
future_week4 As Double
future_week5 As Double
future_week6 As Double
future_week7 As Double
future_week8 As Double
future_week9 As Double
future_week10 As Double
future_week11 As Double
future_week12 As Double
future_week13 As Double
future_week14 As Double
future_week15 As Double
future_week16 As Double
future_week17 As Double
future_week18 As Double
End Type
并调用以下函数
EstimateFuture myProduct, pricing1, pricing2, receipt1, location, myoutput
此函数接收 myProduct
、pricing1
、pricing2
、receipt1
和 location
作为输入,并将输出放入 myoutput
.
不管这些结构设计得好不好。我需要了解每个字段在内存中的顺序。
估算函数的汇编开头如下:
EstimateFuture:
push ebp
mov ebp,esp
and esp,FFFFFFF8h
sub esp,000000A0h
push esi
mov esi,[ebp+08h]
push edi
mov ecx,0000000Ch
mov edi,L1000F198
rep movsd
mov esi,[ebp+0Ch]
mov ecx,00000008h
mov edi,L1000F250
rep movsd
mov esi,[ebp+10h]
mov ecx,00000008h
mov edi,L1000F208
rep movsd
mov esi,[ebp+14h]
mov ecx,00000010h
mov edi,L1000F1C8
rep movsd
mov esi,[ebp+18h]
mov ecx,0000000Ah
mov edi,L1000F228
rep movsd
...
显然上面的代码试图将参数存储到它的内存中。这里我们有六个参数和五个 rep movsd
。可能是因为输入了五个变量而最后一个没有。
但我不明白的是,地址与变量完全不匹配。既不是根据它们的大小,也不是根据它们的标签分割。无论参数是以直接方式还是反向方式存储,它们都与以下地址不匹配:
L1000F198:
dq 0000000000000000h
L1000F1A0:
dq 0000000000000000h
L1000F1A8:
db 00h;
db 00h;
db 00h;
db 00h;
L1000F1AC:
db 00h;
db 00h;
L1000F1AE:
db 00h;
db 00h;
db 00h;
db 00h;
L1000F1B2:
db 00h;
db 00h;
L1000F1B4:
db 00h;
db 00h;
db 00h;
db 00h;
L1000F1B8:
dq 0000000000000000h
L1000F1C0:
dq 0000000000000000h
L1000F1C8:
dq 0000000000000000h
L1000F1D0:
dq 0000000000000000h
L1000F1D8:
dq 0000000000000000h
L1000F1E0:
dq 0000000000000000h
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F1F0:
dq 0000000000000000h
L1000F1F8:
dq 0000000000000000h
L1000F200:
db 00h;
db 00h;
L1000F202:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F208:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F210:
dq 0000000000000000h
L1000F218:
dq 0000000000000000h
L1000F220:
dq 0000000000000000h
L1000F228:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F230:
dd 00000000h
L1000F234:
dd 00000000h
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F240:
dq 0000000000000000h
L1000F248:
db 00h;
db 00h;
L1000F24A:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F250:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F258:
dq 0000000000000000h
L1000F260:
dq 0000000000000000h
L1000F268:
dq 0000000000000000h
L1000F270:
dd 00000000h
L1000F274:
db 00h;
db 00h;
db 00h;
db 00h;
L1000F278:
dd 00000000h
L1000F27C:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F284:
dd 00000000h
L1000F288:
dd 00000000h
db 00h;
db 00h;
db 00h;
db 00h;
L1000F290:
dd 00000000h
L1000F294:
db 00h;
db 00h;
db 00h;
db 00h;
L1000F298:
db 00h;
db 00h;
db 00h;
db 00h;
我不知道这个 DLL 文件的原始语言,也不知道编译器的名称或版本。
有人可以帮我填一下这个谜题吗?
address of myProduct.price = ?
address of myProduct.size = ?
address of myProduct.isExpensive = ?
address of myProduct.isCheap = ?
address of myProduct.isVerified = ?
address of myProduct.isPacked = ?
address of myProduct.isDelivered = ?
address of pricing1.value1 = ?
address of pricing1.value2 = ?
address of pricing1.value3 = ?
address of pricing1.value4 = ?
address of pricing2.value1 = ?
address of pricing2.value2 = ?
address of pricing2.value3 = ?
address of pricing2.value4 = ?
address of receipt1.price = ?
address of receipt1.location_x = ?
address of receipt1.location_y = ?
address of receipt1.time = ?
address of receipt1.gross_weight = ?
address of receipt1.special_weight = ?
address of receipt1.discount = ?
address of receipt1.dispatched = ?
address of receipt1.paid = ?
address of location.reputation = ?
address of location.id = ?
address of location.staffs = ?
address of location.location_x = ?
address of location.location_y = ?
address of location.working_weekends = ?
address of location.ventilated = ?
address of myoutput.future_week1 = ?
address of myoutput.future_week2 = ?
address of myoutput.future_week3 = ?
address of myoutput.future_week4 = ?
address of myoutput.future_week5 = ?
address of myoutput.future_week6 = ?
address of myoutput.future_week7 = ?
address of myoutput.future_week8 = ?
address of myoutput.future_week9 = ?
address of myoutput.future_week10 = ?
address of myoutput.future_week11 = ?
address of myoutput.future_week12 = ?
address of myoutput.future_week13 = ?
address of myoutput.future_week14 = ?
address of myoutput.future_week15 = ?
address of myoutput.future_week16 = ?
address of myoutput.future_week17 = ?
更新
感谢matan7890,现在我知道myProduct
的地址在L1000F228
:
L1000F228:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F230:
dd 00000000h
L1000F234:
dd 00000000h
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
L1000F240:
dq 0000000000000000h
L1000F248:
db 00h;
db 00h;
L1000F24A:
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
db 00h;
意思是:
address of myProduct.price = L1000F228 (8 bytes)
address of myProduct.size = L1000F230 (8 bytes)
address of myProduct.isExpensive = L1000F238 (4 bytes) -----> No Label
address of myProduct.isCheap = L1000F23C (4 bytes) -----> No Label
address of myProduct.isVerified = L1000F240 (4 bytes)
address of myProduct.isPacked = L1000F244 (4 bytes) -----> No Label
address of myProduct.isDelivered = L1000F248 (4 bytes)
这里,问题是 myProduct.isExpensive
、myProduct.isCheap
和 myProduct.isPacked
的开头没有标签。
其他问题是
myProduct.price
由 8 个单字节组成,而不是单个 8 个字节。
myProduct.size
必须是 8 个字节,但在 4 个字节之后引入另一个标签。
标签似乎没有放在正确的位置。
首先,请注意您传递的参数的顺序与您在堆栈中的想法相反。例如,您的第一个变量 myProduct
在 [ebp+18h]
中。
此外,请注意 vb Boolean
是 4 个字节而不是 1 个字节。因此,您的产品类型是 36 个字节,Pricing
是 32 个字节,依此类推。 movsd
操作码一次复制 4 个字节(双字)。通过阅读 rep
s,您的参数似乎顺序不正确,因为第二个参数复制 64 个字节(4 * 10h == 4 * 16 = 64),就像您的 Receipt
类型.似乎参数的正确顺序,仅通过参考所需的大小,是:
EstimateFuture myProduct, receipt1, pricing1, pricing2, location, myoutput
这意味着 myProduct
似乎在 L1000F228 和接下来的 40 个字节中。请注意,您的结构只有 36 个字节,这意味着您可能缺少该类型中的一个 Boolean
成员。
从这里你可以自己计算:)