Вопрос Защита от декомпиляции

Carlos

Участник
Модератор
Сделал по хитрому и простому.
В самом начале секции прописал ненужный файл, который никак не задействуется инсталлятором.

Код:
[Files]
Source: Include\123.exe;      DestDir: "{tmp}";
Source: dll\*.dll;            Flags: dontcopy solidbreak nocompression deleteafterinstall noencryption
Source: Pictures\*.*;         Flags: dontcopy solidbreak nocompression deleteafterinstall noencryption
Source: Pictures\Slides\*.*;  Flags: dontcopy solidbreak nocompression deleteafterinstall noencryption
Source: Music\*.*;            Flags: dontcopy solidbreak nocompression deleteafterinstall noencryption
 

vint56

Ветеран
Проверенный
nowik1971, пример
Код:
[Setup]
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application

[Types]
Name: full; Description: Full installation; Flags: iscustom

[Tasks]
Name: "tweaker"; Description: "У меня слабый компьютер и я хочу поднять FPS"; MinVersion: 0.0,5.0;
Name: "tweaker\cpu"; Description: "Распределение нагрузки между ядрами процессора"; MinVersion: 0.0,5.0;
Name: "tweaker\cpu\1"; Description: "Нагрузка на одно ядро процессора"; MinVersion: 0.0,5.0;
Name: "tweaker\cpu\2"; Description: "Равномерная нагрузка на все ядра процессора"; MinVersion: 0.0,5.0;
Name: "tweaker\cpu\3"; Description: "Установить высокий приоритет"; MinVersion: 0.0,5.0;
Name: "tweaker\cpu\4"; Description: "Предзагрузка звуков в начале боя"; MinVersion: 0.0,5.0;
Name: "tweaker\effects"; Description: "Отключение визуальных эффектов"; MinVersion: 0.0,5.0;
Name: "tweaker\effects\1"; Description: "Отключить дым и пламя от выстрелов"; MinVersion: 0.0,5.0;
Name: "tweaker\effects\2"; Description: "Отключить дым из выхлопных труб танков"; MinVersion: 0.0,5.0;
Name: "tweaker\effects\3"; Description: "Отключить дым от уничтоженных танков"; MinVersion: 0.0,5.0;
Name: "tweaker\effects\4"; Description: "Отключить облака"; MinVersion: 0.0,5.0;
Name: "tweaker\effects\5"; Description: "Отключить эффект взрыва снарядов и попадания в объекты"; MinVersion: 0.0,5.0;
Name: "tweaker\effects\6"; Description: "Отключить эффект движения деревьев"; MinVersion: 0.0,5.0;
Name: "tweaker\effects\7"; Description: "Отключить эффекты проявления погоды и дым от объектов на картах"; MinVersion: 0.0,5.0;
Name: "tweaker\effects\8"; Description: "Отключить эффекты разрушения объектов"; MinVersion: 0.0,5.0;
Name: "tweaker\effects\9"; Description: "Отключить тени под танком"; MinVersion: 0.0,5.0;
Name: "tweaker\effects\10"; Description: "Отключить эффекты попадания по танкам"; MinVersion: 0.0,5.0;
Name: "tweaker\effects\11"; Description: "Отключить эффекты уничтожения танков"; MinVersion: 0.0,5.0;
Name: "tweaker\effects\12"; Description: "Увеличить максимальную дальность видимости"; MinVersion: 0.0,5.0;
Name: "tweaker\effects\13"; Description: "Отключить туман на всех картах"; MinVersion: 0.0,5.0;
Name: "tweaker\effects\14"; Description: "Отключить загрузку эмблем кланов"; MinVersion: 0.0,5.0;

[Components]
Name: "kmp"; Description: "Настройка Прицелов"; MinVersion: 0.0,5.0;
Name: "kmp\1"; Description: "Аркадный прицел"; MinVersion: 0.0,5.0;
Name: "kmp\1\1"; Description: "Стандартный прицел + таймер"; MinVersion: 0.0,5.0;
Name: "kmp\1\2"; Description: "Выбор Джова"; MinVersion: 0.0,5.0;
Name: "kmp\1\3"; Description: "Выбор Дезертода"; MinVersion: 0.0,5.0;
Name: "kmp\1\4"; Description: "Выбор Муразора"; MinVersion: 0.0,5.0;
Name: "kmp\1\5"; Description: "Корейсктй прицел"; MinVersion: 0.0,5.0;
Name: "kmp\1\6"; Description: "Выбор Вспышки"; MinVersion: 0.0,5.0;
Name: "kmp\1\7"; Description: "Дамоклов Меч"; MinVersion: 0.0,5.0;
Name: "kmp\1\8"; Description: "Taipan v1"; MinVersion: 0.0,5.0;
Name: "kmp\1\9"; Description: "Taipan v2"; MinVersion: 0.0,5.0;
Name: "kmp\1\10"; Description: "Исторический прицел"; MinVersion: 0.0,5.0;
Name: "kmp\1\11"; Description: "Прицел Marsoff"; MinVersion: 0.0,5.0;
Name: "kmp\1\12"; Description: "Прицел Warplanes (Бирюза)"; MinVersion: 0.0,5.0;
Name: "kmp\1\13"; Description: "Прицел Warplanes (Зеленый)"; MinVersion: 0.0,5.0;
Name: "kmp\1\14"; Description: "Прицел Valuhow"; MinVersion: 0.0,5.0;
Name: "kmp\1\15"; Description: "Прицел Бирюза"; MinVersion: 0.0,5.0;
Name: "kmp\2"; Description: "Сведение Снайперского прицела"; MinVersion: 0.0,5.0;
Name: "kmp\2\1"; Description: "Сведение Dikey93"; MinVersion: 0.0,5.0;
Name: "kmp\2\2"; Description: "Сведение OverCross"; MinVersion: 0.0,5.0;
Name: "kmp\2\3"; Description: "Сведение J1mb0 Crosshair"; MinVersion: 0.0,5.0;
Name: "kmp\2\4"; Description: "Сведение Deegie Sights"; MinVersion: 0.0,5.0;
Name: "kmp\2\5"; Description: "Сведение Дамоклов Меч"; MinVersion: 0.0,5.0;
Name: "kmp\2\6"; Description: "Сведение Demon2597@"; MinVersion: 0.0,5.0;
Name: "kmp\2\7"; Description: "Сведение Fatality"; MinVersion: 0.0,5.0;
Name: "kmp\2\8"; Description: "Сведение Hameleon"; MinVersion: 0.0,5.0;
Name: "kmp\2\9"; Description: "Сведение MeltyMap's MathMod"; MinVersion: 0.0,5.0;
Name: "kmp\2\10"; Description: "Сведение Minimalistic Sights"; MinVersion: 0.0,5.0;
Name: "kmp\2\11"; Description: "Сведение Marsoff"; MinVersion: 0.0,5.0;
Name: "kmp\2\12"; Description: "Сведение PietrofSKY's Crosshair"; MinVersion: 0.0,5.0;
Name: "kmp\2\13"; Description: "Сведение Гарпун"; MinVersion: 0.0,5.0;
Name: "kmp\2\14"; Description: "Сведение Кирила Орешкина"; MinVersion: 0.0,5.0;
Name: "kmp\2\15"; Description: "Сведение С углом вхождения снаряда"; MinVersion: 0.0,5.0;
Name: "kmp\3"; Description: "Артиллерийский Прицел"; MinVersion: 0.0,5.0;
Name: "kmp\3\1"; Description: "Артиллерийский Прицел OverCross"; MinVersion: 0.0,5.0;
Name: "kmp\3\2"; Description: "Артиллерийский Прицел J1mb0 Crosshair"; MinVersion: 0.0,5.0;
Name: "kmp\3\3"; Description: "Артиллерийский Прицел Вспышки"; MinVersion: 0.0,5.0;
Name: "kmp\3\4"; Description: "Артиллерийский Прицел Deegie Sights"; MinVersion: 0.0,5.0;
Name: "kmp\3\5"; Description: "Артиллерийский Прицел MeltyMap's MathMod"; MinVersion: 0.0,5.0;
Name: "kmp\3\6"; Description: "Артиллерийский Прицел Дамоклов Меч"; MinVersion: 0.0,5.0;
Name: "kmp\3\7"; Description: "Артиллерийский Прицел Taipan"; MinVersion: 0.0,5.0;
Name: "kmp\3\8"; Description: "Артиллерийский Прицел Minimalistic Sights"; MinVersion: 0.0,5.0;
Name: "kmp\3\9"; Description: "Артиллерийский Прицел Гарпун"; MinVersion: 0.0,5.0;
Name: "kmp\4"; Description: "Сведение Артиллерийского прицела"; MinVersion: 0.0,5.0;
Name: "kmp\4\1"; Description: "Сведение Dikey93"; MinVersion: 0.0,5.0;
Name: "kmp\4\2"; Description: "Сведение OverCross"; MinVersion: 0.0,5.0;
Name: "kmp\4\3"; Description: "Сведение J1mb0 Crosshair"; MinVersion: 0.0,5.0;
Name: "kmp\4\4"; Description: "Сведение Deegie Sights"; MinVersion: 0.0,5.0;
Name: "kmp\4\5"; Description: "Сведение Дамоклов Меч"; MinVersion: 0.0,5.0;
Name: "kmp\4\6"; Description: "Сведение MeltyMap's MathMod"; MinVersion: 0.0,5.0;
Name: "kmp\4\7"; Description: "Сведение Minimalistic Sights"; MinVersion: 0.0,5.0;
Name: "kmp\4\8"; Description: "Сведение Гарпун"; MinVersion: 0.0,5.0;
Name: "kmp\5"; Description: "Снайперский прицел"; MinVersion: 0.0,5.0;
Name: "kmp\5\1"; Description: "Стандартный прицел + таймер"; MinVersion: 0.0,5.0;
Name: "kmp\5\2"; Description: "Выбор Джова"; MinVersion: 0.0,5.0;
Name: "kmp\5\3"; Description: "Выбор Дезертода"; MinVersion: 0.0,5.0;
Name: "kmp\5\4"; Description: "Выбор Муразора"; MinVersion: 0.0,5.0;
Name: "kmp\5\5"; Description: "Корейсктй прицел"; MinVersion: 0.0,5.0;
Name: "kmp\5\6"; Description: "Выбор Вспышки"; MinVersion: 0.0,5.0;
Name: "kmp\5\7"; Description: "Дамоклов Меч"; MinVersion: 0.0,5.0;
Name: "kmp\5\8"; Description: "Taipan v1"; MinVersion: 0.0,5.0;
Name: "kmp\5\9"; Description: "Taipan v2"; MinVersion: 0.0,5.0;
Name: "kmp\5\10"; Description: "Исторический прицел"; MinVersion: 0.0,5.0;
Name: "kmp\5\11"; Description: "Прицел Marsoff"; MinVersion: 0.0,5.0;
Name: "kmp\5\12"; Description: "Прицел Warplanes (Бирюза)"; MinVersion: 0.0,5.0;
Name: "kmp\5\13"; Description: "Прицел Warplanes (Зеленый)"; MinVersion: 0.0,5.0;
Name: "kmp\5\14"; Description: "Прицел Valuhow"; MinVersion: 0.0,5.0;
Name: "kmp\5\15"; Description: "Прицел Бирюза"; MinVersion: 0.0,5.0;
 

nowik1971

Мимокрокодил
Не кто и не говорит, я просто спор выиграл в том что смог запороленый распаковать вот и все..... о другом не шло разговора
 

nowik1971

Мимокрокодил
честно щас просто некогда я его распаковывал, но ничего не понял и стер хотя что-то осталось могу скинуть...
Ах, я понял у тебя не вышло .... ну, пардон
 

Ekspoint

Новичок
честно щас просто некогда я его распаковывал, но ничего не понял и стер хотя что-то осталось могу скинуть...
Ах, я понял у тебя не вышло .... ну, пардон
сейчас стоит защита паролем, вот и интересно как ты пароль узнал
 

El Sanchez

Новичок
Обратное преобразование байткода (CompiledCode.bin) или тем более псевдоассемблерного дампа (CodeSection.txt) в исходный код возможно, поэтому любые манипуляции с PasswordEdit от полной декомпиляции не спасут. Если писать пароль только в директиве Password секции Setup, то тут уже ничего нельзя сделать.
 

Ekspoint

Новичок
Обратное преобразование байткода (CompiledCode.bin) или тем более псевдоассемблерного дампа (CodeSection.txt) в исходный код возможно, поэтому любые манипуляции с PasswordEdit от полной декомпиляции не спасут. Если писать пароль только в директиве Password секции Setup, то тут уже ничего нельзя сделать.
А как txt в норм код преооброзавать
 

El Sanchez

Новичок
Начинать учиться декомпилировать байткод нужно с простых скриптов. Написать процедуру/функцию с одной строкой, а в ней только
какая-либо простая операция типа присвоения значения переменной. Потом постепенно усложнять код, присваивая переменной простое арифметическое, логическое выражение, вызов функции без параметров, с параметрами, приведение типов, добавить в процедуру/функцию параметры с разными модификаторами, добавить локальные переменные и т.д. После каждого усложнения кода смотреть как формируется дамп. Когда основа будет пройдена, приступать к анализу синтаксических конструкций типа if-else-then, for-do, try-except-finally, case, with, вызов методов экземпляров классов и обращения к их свойствам, доступ к символам строки по индексу, работа с интерфесными объектами.
Для понимания того, что написано ниже, нужно знать, хотя бы поверхностно, что такое стек и как это работает, гугл в помощь. В качестве подопытного примера для декомпиляции я взял первый же найденный через гуглу простой псевдокод: http://forum.ru-board.com/topic.cgi?forum=5&topic=4801&start=1480#17. Псевдокод состоит из секций TYPES (список типов, используемых в коде), VARS (список глобальных переменных), PROCS (список процедур/функций и их код).
[TYPES]
Type [0]: Pointer
Type [1]: U32
Type [2]: Variant
Type [3]: Unknown 14
Type [4]: Unknown 24
Type [5]: Extended
Type [6]: Double
Type [7]: Single
Type [8]: String
Type [9]: U32
Type [10]: S32
Type [11]: S16
Type [12]: U16
Type [13]: S8
Type [14]: Char
Type [15]: U32
Type [16]: U8 Export: BOOLEAN
Type [17]: U8
Type [18]: U8

Список типов, используемых в коде.
Число в скобках после слова Type - это порядковый номер (индекс) типа во внутреннем списке типов, после двоеточия - тип.​
Начало списка практически одинаково у всех дампов, в список сначала заносятся встроенные фундаментальные типы движка, в конце те, что используются в коде пользователя явно и типы промежуточных переменных времени исполнения (результаты функций в выражениях хранятся в временных переменных, вызовы методов экземпляров классов и их свойств и т.д.). U32 - unsigned integer, 32-бит, беззнаковое целое, (DWORD, Cardinal), S32 - signed integer, 32-бит, знаковое целое (Integer, Longint), S16 - SmallInt, U16 - WORD, S8 - ShortInt, U8 - Byte, строка Type [16]: U8 Export: BOOLEAN говорит, что в коде используется тип Boolean, а не Byte.​
[VARS]
Список глобальных переменных. Пуст, глобальных переменных нет.​
[PROCS]
Список процедур/функций.
Число в скобках после слова Proc - индекс процедуры/функции во внутреннем списке процедур.
Cлово Export - пользовательская процедура/функция.
Слова External Decl - встроенная процедура/функция.
После двоеточия: имя процедуры/функции, за которым следуют список типов параметров и их модификаторы. Если описывается процедура, то первым в списке будет написано -1, а если функция, то первым будет тип результата, следом идут параметры (если есть) вида "модификатор типпараметра", где модификатор @ - параметр передан по значению или с модификатором const, ! - параметр передан по ссылке с модификатором var или out. Например: @12 !14 - передали 2 параметра с типами под номерами из TYPES 12 и 14, второй параметр по ссылке, т.е. (var1: WORD; var var2: Char)​
Proc [0] Export: !MAIN -1
[0] RET

С внутренней процедуры !MAIN начинается любой код.
Любая процедура/функция заканчивается инструкцией RET (от слова Return, выход из процедуры).
Число в скобках перед каждой инструкцией - смещение адреса инструкции относительно точки входа в процедуру/функцию.​
Proc [1] Export: ISX64 16
Декларация пользовательской функции ISX64 без параметров, возвращающей Boolean.
А вот и первая пользовательская функция. Функция потому, что первый параметр (он же неявный параметр Result) в списке не -1, а индекс типа, в секции TYPES индекс 16 соответствует типу Boolean. После 16 ничего нет, значит никакие параметры явно в функцию не передаются. Смело пишем:
function IsX64: Boolean; begin end;
[0] PUSHTYPE 18(U8) // 1
Заносим на стек указатель на тип внутренней переменной (PUSHTYPE), с которой будем работать ниже. Тут заносится инфа о типе U8 (Byte, Boolean).
При операциях со стеком после комментария // число указывает на индекс элемента на вершине стека (оно же количество элементов на стеке).
С PUSHTYPE может начинаться не только работа с внутренней переменной в блоке begin-end (тело), а еще и декларация локальных переменных (var). Как узнать где мы - уже в теле или объявляем локальные переменные? Очень просто. Перед RET инструкция POP не выталкивает из стека PUSHTYPE'ы локальных переменных, поэтому, например, POP // 2 перед RET будет означать, что первые 2 PUSHTYPE в самом начале объявляют 2 локальные переменные, а дальше уже тело идет.​
[5] PUSHVAR Base[1] // 2
Инициализируем и заносим (PUSHVAR) на стек переменную (Base[1]), тип которой занесли предыдущей инструкцией. Число в скобках после Base - индекс элемента с инфой о типе на стеке. 1 элемент занесен предыдущей инструкцией - PUSHTYPE 18(U8) // 1.​
[11] CALL 2
Вызов (CALL) процедуры с индексом 2 (Proc [2] соответствует вызову внутренней функции PROCESSORARCHITECTURE, см. ниже).
Теперь понятна возня с помещением на стек указателя на тип переменной и самой переменной. Перед вызовом какой-либо процедуры/функции на стек сначала заносятся все параметры. PROCESSORARCHITECTURE, как и любая другая функция, имеет 1 неявный параметр Result, с ним и работали предыдущие PUSHTYPE/PUSHVAR. Итак, временно пишем в теле:
ProcessorArchitecture
Пока еще не знаем, что с ProcessorArchitecture (он же Base[1], он же Result функции ProcessorArchitecture) делать.​
[16] POP // 1
Выталкиваем из стека Result функции ProcessorArchitecture.​
[17] COMPARE into Base[-1]: Base[1] = [2]
Операция сравнения (COMPARE), результат сравнения (Base[1] = [2]) заносится (into) в переменную Base[-1].
Видим, что внутренняя переменная Base в скобках имеет отрицательный индекс -1. Так вот по отрицательным индексам лежат переменные, передаваемые в пользовательскую процедуру/функцию. У функций, в том числе и нашей IsX64, если вы не забыли, всегда есть по крайней мере 1 параметр, это Result и он неявно по ссылке передается в функцию. Так вот Base[-1] соответствует Result, Base[-2] - первому явному параметру, Base[-3] - второму и т.д. Для процедур аналогично, кроме Result, там нет неявных параметров, поэтому Base[-1] - первый параметр, Base[-2] - второй.
Итак, понятно, что головному Result'у присваивается результат сравнения Base[1] = [2]. Base[1] мы уже знаем, что это результат функции ProcessorArchitecture, = [2] сравнивается с константой 2. Глянем в хелп и найдем что ProcessorArchitecture возвращает и с чем его можно сравнить. Результат типа TSetupProcessorArchitecture, константа 2 этого перечисляемого типа соответствует paX64. Итак, временно пишем:
Result := ProcessorArchitecture = paX64;
[35] POP // 0
Выталкиваем из стека инфу о типе.​
[36] RET
Конец функции, выход из нее, больше с Result ничего не делается, поэтому пишем уже на чистовик:
function IsX64: Boolean;
begin

Result := ProcessorArchitecture = paX64;
end;
Proc [2]: External Decl: \01 PROCESSORARCHITECTURE
Proc [3] Export: ISIA64 16

Декларация пользовательской функции IsIA64 без параметров, возвращающей Boolean.​
[0] PUSHTYPE 18(U8) // 1
[5] PUSHVAR Base[1] // 2

На стеке тип Boolean и переменная Base[1] этого типа. Локальных переменных нет, т.к. последний POP указывает на 0.​
[11] CALL 2
Вызов PROCESSORARCHITECTURE, результат в Base[1]
[16] POP // 1
Выталкиваем из стека Result функции ProcessorArchitecture.​
[17] COMPARE into Base[-1]: Base[1] = [3]
Знакомая по предыдущей функции строка, только сравнение с константой 3. Пишем:
Result := ProcessorArchitecture = paIA64;
[35] POP // 0
Выталкиваем из стека инфу о типе.​
[36] RET
Выход из функции. Пишем:
function IsIA64: Boolean;
begin

Result := ProcessorArchitecture = paIA64;
end;
Proc [4] Export: ISWIN2K 16
Декларация пользовательской функции IsWin2K без параметров, возвращающей Boolean.​
[0] PUSHTYPE 9(U32) // 1
[5] PUSHVAR Base[1] // 2

На стеке тип Cardinal и переменная Base[1] этого типа. Локальных переменных нет, т.к. последний POP указывает на 0.​
[11] CALL 5
Вызов GETWINDOWSVERSION, результат в Base[1]
[16] POP // 1
Выталкиваем из стека Result функции GetWindowsVersion. Временно пишем:
GetWindowsVersion
[17] CALC Base[1] SHR [24]
Операция с числами (CALC). Биты числа Base[1] (он же GetWindowsVersion) сдвигаются вправо (SHR) на 24 ([24]) позиции, результат идет в Base[1]. Временно пишем:
GetWindowsVersion shr 24
[33] COMPARE into Base[-1]: Base[1] >= [5]
Уже знаем. Временно пишем:
Result := GetWindowsVersion shr 24 >= 5;
[54] POP // 0
Выталкиваем из стека инфу о типе.​
[55] RET
Выход из функции. Пишем:
function IsWin2K: Boolean;
begin

Result := GetWindowsVersion shr 24 >= 5;
end;
Proc [5]: External Decl: \01 GETWINDOWSVERSION
Proc [6] Export: ISOTHERARCH 16

Декларация пользовательской функции IsOtherArch без параметров, возвращающей Boolean.​
[0] PUSHVAR Base[-1] // 1
Сразу работа с головным Result.​
[6] CALL 1
Вызов IsX64, результат в Result. Временно пишем:
Result := IsX64;
[11] POP // 0
Выталкиваем из стека Result.​
[12] BNOT Base[-1]
Логическая операция not (BNOT), применительно к нашему Result. Временно пишем:
Result := not IsX64;
[18] COND_NOT_GOTO currpos + 36 Base[-1] [64]
Условие и переход по метке при невыпонении условия. Тут если Result равен False, то переход по смещению [64], там тоже условный переход по смещению [104], по смещению [104] инструкция RET.​
[28] PUSHTYPE 16(U8) // 1
[33] PUSHVAR Base[1] // 2

На стеке тип Boolean и переменная Base[1] этого типа.​
[39] CALL 3
Вызов IsIA64, результат в Base[1]. Временно пишем:
Result := not IsX64;
IsIA64
[44] POP // 1
Выталкиваем из стека Base[1].​
[45] BNOT Base[1]
Логическая операция not (BNOT), применительно к нашему Base[1]. Временно пишем:
Result := not IsX64;
not IsIA64
[51] CALC Base[-1] AND Base[1]
Опаньки, Result скрестили с Base[1] (not IsIA64). Временно пишем:
Result := not IsX64;
Result := Result and not IsIA64;
Объединяем:
Result := not IsX64 and not IsIA64;
Теперь становится понятным почему 2 условных перехода. Сначала в выражении вычисляется not IsX64 и если результат равен False, то смысла в вычислении остальных членов логического выражения нет и происходит переход по первой метке на метку условного перехода от второго члена выражения not IsIA64.​
[63] POP // 0
Выталкиваем из стека инфу о типе.​
[64] COND_NOT_GOTO currpos + 30 Base[-1] [104]
Если вторая часть выражения not IsIA64 равна False, то выход (переход на [104], где лежит RET).​
[74] PUSHTYPE 16(U8) // 1
[79] PUSHVAR Base[1] // 2

На стеке тип Boolean и переменная Base[1] этого типа.​
[85] CALL 4
Вызов IsWin2K, результат в Base[1]. Временно пишем:
Result := not IsX64 and not IsIA64;
IsWin2K
[90] POP // 1
Выталкиваем из стека Base[1].​
[91] CALC Base[-1] AND Base[1]
Опять Result скрестили с Base[1] (IsWin2K). Временно пишем:
Result := not IsX64 and not IsIA64;
Result := Result and IsWin2K;
Объединяем:
Result := not IsX64 and not IsIA64 and IsWin2K;
[103] POP // 0
Выталкиваем из стека инфу о типе.​
[104] RET
Выход из функции. Пишем:
function IsOtherArch: Boolean;
begin

Result := not IsX64 and not IsIA64 and IsWin2K;
end;
Proc [7] Export: NOTX64 16
Декларация пользовательской функции NotX64 без параметров, возвращающей Boolean.​
[0] PUSHVAR Base[-1] // 1
На стеке Result.​
[6] CALL 1
Вызов IsX64, результат в Result. Временно пишем:
Result := IsX64;
[11] POP // 0
Выталкиваем из стека Result.​
[12] BNOT Base[-1]
Логическая операция not (BNOT), применительно к нашему Result. Временно пишем:
Result := not IsX64;
[18] COND_NOT_GOTO currpos + 36 Base[-1] [64]
На выход, если Result в False. Опять выражение?​
[28] PUSHTYPE 16(U8) // 1
[33] PUSHVAR Base[1] // 2

На стеке тип Boolean и переменная Base[1] этого типа.​
[39] CALL 3
Вызов IsIA64, результат в Base[1]. Временно пишем:
Result := not IsX64;
IsIA64
[44] POP // 1
Выталкиваем из стека Base[1].​
[45] BNOT Base[1]
Логическая операция not (BNOT), применительно к нашему Base[1]. Временно пишем:
Result := not IsX64;
not IsIA64
[51] CALC Base[-1] AND Base[1]
Result скрестили с Base[1] (not IsIA64). Временно пишем:
Result := not IsX64;
Result := Result and not IsIA64;
Объединяем:
Result := not IsX64 and not IsIA64;
[63] POP // 0
Выталкиваем из стека инфу о типе.​
[64] RET
Выход из функции. Пишем:
function NotX64: Boolean;
begin

Result := not IsX64 and not IsIA64;
end;
Proc [8]: External Decl: \01\00 DIREXISTS
Дамп выложили неполностью, DIREXISTS нигде выше не используется.​
Итого имеем:
Код:
function IsX64: Boolean;
begin
  Result := ProcessorArchitecture = paX64;
end;

function IsIA64: Boolean;
begin
  Result := ProcessorArchitecture = paIA64;
end;

function IsWin2K: Boolean;
begin
  Result := GetWindowsVersion shr 24 >= 5;
end;

function IsOtherArch: Boolean;
begin
  Result := not IsX64 and not IsIA64 and IsWin2K;
end;

function NotX64: Boolean;
begin
  Result := not IsX64 and not IsIA64;
end;
Можно скомпилировать, снять дамп и сверить.
 
Сверху