如何排序汇编中的结构参数字段?

时间:2015-08-02 08:59:30

标签: assembly x86 dllimport argument-passing disassembly

我有一个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

此功能接收myProductpricing1pricing2receipt1location作为输入,并将输出放入myoutput。< / p>

无论这些结构是否设计得很好。我需要了解内存中每个字段的顺序。

估算功能的组装开头如下:

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.isExpensivemyProduct.isCheapmyProduct.isPacked在开始时没有标签。

其他问题是

myProduct.price由8个单字节而不是单个8字节组成。

myProduct.size必须是8个字节,但在4个字节后引入另一个标签。

标签似乎不在正确的位置。

1 个答案:

答案 0 :(得分:3)

首先,请注意,您传递的参数的顺序与您在堆栈中的想法相反。例如,您的第一个变量myProduct位于[ebp+18h]中。

此外,请注意,在vb中Boolean是4个字节而不是1.因此,您的产品类型是36个字节,Pricing是32个字节,依此类推。 movsd操作码一次复制4个字节(dwords)。通过读取rep,您的参数似乎不是正确的顺序,因为第二个参数复制64个字节(4 * 10h == 4 * 16 = 64),就像您的Receipt类型一样。看起来正确的参数顺序只是通过从想要的大小中得到的,是:

EstimateFuture myProduct, receipt1, pricing1, pricing2, location, myoutput

这意味着myProduct似乎在L1000F228和即将到来的40个字节中。请注意,您的结构只有36个字节,这意味着您可能缺少该类型中的一个Boolean成员。

从这里你可以自己计算:)