Как упорядочены поля структурных аргументов в сборке?

У меня есть скрипт 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 байта вводится другая метка.

Кажется, этикетки не на своем месте.

1 ответ

Решение

Прежде всего, имейте в виду, что передаваемые вами аргументы упорядочены в порядке, обратном тому, что вы думаете в стеке. Например, ваша первая переменная myProduct в [ebp+18h],

Также знайте, что в vb Boolean 4 байта, а не 1. Итак, ваш тип продукта составляет 36 байтов, Pricing 32 байта и так далее. movsd Код операции копирует 4 байта за раз (слова). Читая reps, кажется, что ваши аргументы не в правильном порядке, потому что вторые аргументы копируют 64 байта (4 * 10h == 4 * 16 = 64), как ваш Receipt тип. Кажется, что правильный порядок аргументов, только исходя из требуемых размеров, таков:

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

Это означает myProduct Это, кажется, в L1000F228 и ближайшие 40 байтов. Имейте в виду, что ваша структура занимает всего 36 байтов, что означает, что вы можете пропустить один Boolean член в этом типе.

Отсюда вы можете рассчитать сами:)

Другие вопросы по тегам