Pe32 executable console intel 80386 for ms windows

On Windows, like: is64 abc.exe 1 and is32 def.exe 1 While abc.exe is compiled 64-bit and def.exe is 32-bit on Windows.

Is there a command line tool to check 32-bit or 64-bit of an exe?

Yes

c:Program Files (x86)GnuWin32bin>file file.exe
file.exe; PE32 executable for MS Windows (console) Intel 80386 32-bit

c:Program Files (x86)GnuWin32bin>cd ....evernoteevernote   
c:Program Files (x86)EvernoteEvernote>file evernote.exe
evernote.exe; PE32 executable for MS Windows (GUI) Intel 80386 32-bit

c:Program Files (x86)EvernoteEvernote>cd c:Program FilesInternet Explorer    
c:Program FilesInternet Explorer>file iexplore.exe
iexplore.exe; PE32+ executable for MS Windows (GUI) Mono/.Net assembly

The PE32 format stands for Portable Executable 32-bit, while PE32+ is Portable Executable 64-bit format.

See http://gnuwin32.sourceforge.net/packages/file.htm

like:

is64 abc.exe
1

Not exactly like that.

You can use the -b option to exclude the filename from the output, then you just need some command-line kung fu to extract the first word (PE32 or PE32+) compare it with PE32+ and use that in your ìf` statement.


Windows 10

On Windows 10, if you have the anniversary update, if you enable the bash shell, you can open a bash shell and use the file command like this

rgb@MYPCNAME:/mnt/c$ file install.exe
install.exe: PE32 executable (GUI) Intel 80386, for MS Windows

or

rgb@MYPCNAME:/mnt/c/Program Files/Internet Explorer$ file ieinstal.exe
ieinstal.exe: PE32+ executable (GUI) x86-64, for MS Windows

Приветствую.

Не знаю как вам, но мне сначала совершенно не хотелось ставить новую Windows 8. А смысл? Смысла не было, семёрка отлично работала и продолжила бы работу, но… Умные люди из Microsoft любят всё переделывать заново и в этот раз они конкретно переборщили.

Дело в том, что новая версия эмулятора WP,

Windows Phone Emulator (XDE), использует технологию Hyper-V, которая в семействе настольных Windows появилась только начиная с Windows 8.

У меня возникла идея любой ценой установить этот SDK себе в VS2012 под Windows 7 и выжать из него максимум возможностей.

Внимание!

  • Эмулятор будет доступен только для WP 7.1 и ниже;
  • Blend будет доступен только для WP 7.1 и ниже, а значит XAML под WP 8 придётся писать руками;
  • Это just for fun, ведь нормальные герои всегда идут в обход!

Под катом я вкратце расскажу, как устроен установщик WP8 SDK и покажу кривой путь через болотце для тех, кто не хочет расставаться с Windows 7, но хочет продложить разработку под новые версии Windows Phone.

Копаемся в пакете

Загрузив с официального сайта установщик WPexpress_full.exe, я попробовал его запустить. Он меня послал, сказав что я должен переустановить винду (вот не ожидал!) на что-нибудь поновее, например Windows 8. От такой дерзости я опешил и недолго думая обновил ту самую картинку с собакой, на всякий случай, чтобы было чем отмахиваться в идеологических спорах с друзьями.

Всё подозрение пало на маркетологов.

WPexpress_full.exe отлично распаковывается с помощью WinRAR, внутри обнаружились следующие файлы:

0: XML document text
u0: PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit
u1: PE32 executable for MS Windows (DLL) (console) Intel 80386 32-bit Mono/.Net assembly
u10: PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit
u11: PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit
u12: XML  document text
u13: XML  document text
u14: exported SGML document text
u15: UTF-8 Unicode (with BOM) text, with very long lines, with CRLF line terminators
u16: PNG image data, 63 x 63, 8-bit/color RGBA, non-interlaced
u17: HTML document text
u18: XML document text
u2: XML document text
u3: exported SGML document text
u4: XML document text
u5: MS Windows icon resource - 3 icons, 16x16, 16-colors
u6: MS Windows icon resource - 3 icons, 16x16, 16-colors
u7: MS Windows icon resource - 3 icons, 16x16, 16-colors
u8: PE32 executable for MS Windows (DLL) (console) Intel 80386 32-bit Mono/.Net assembly
u9: XML  document text

После изучения файла 0, который являлся заголовочным для этого пакета, выяснилось, что инсталлятор сделан с помощью тулкита Windows Installer XML (WiX) toolset. Выкачал инструменты этого WiX, среди них была утилита dark.exe, отвечающая за распаковку .msi пакетов, собранных дефолтным инструментарием WiX. Утилита подошла и к этому пакету.

Он распаковался:

.
├── AdminDeployment.xsd
├── BootstrapperApplicationData.xml
├── BootstrapperCore.config
├── BootstrapperCore.dll
├── HighContrastThemes.xaml
├── License.htm
├── LocalizableStrings.xml
├── ManagedUx.dll
├── SkuResources.xaml
├── Themes.xaml
├── manifest.xml
├── mbahost.dll
├── mbapreq.dll
├── mbapreq.png
├── mbapreq.thm
├── mbapreq.wxl
├── res
│   ├── info.ico
│   ├── stop.ico
│   └── warn.ico
└── sqmapi.dll

После прочтения доков и осмотра XML файлов стало ясно, что установщик делался с кастомным интерфейсом, с использованием ManagedUx и Bootstrapper (Burn) из WiX SDK (в архиве wix36-sources.zip есть пример такого проекта — WixBA).

Проще говоря, то что у нас есть — без воссоздания WiX проекта в Visual Studio пересобрать обратно в установщик нельзя. Как минимум

manifest.xml является

<BurnManifest xmlns="http://schemas.microsoft.com/wix/2008/Burn">

и как собирать такие манифесты — ни одна утилита из стандартного набора WiX не знает.

Поэтому не смотря на очень привлекательную строчку в

BootstrapperApplicationData.xml

<UxBlocker ShortName="CheckX64runningWin2008ServerOrWin8" Type="Stop" Condition="(VersionNT < v6.1) OR ((VersionNT = v6.1) AND (NTProductType < 3)) OR (NOT VersionNT64)" DisplayText="#loc.Win8X64Block"/>

которую можно удалить, такой способ придётся оставить.

Парсим manifest.xml

В

manifest.xml прописаны все пакеты, которые устанавливаются установщиком, а так же URI источников. Я написал ruby-скрипт, который парсит и скачивает всё необходимое, затем поочерёдно устанавливает.
Порядок установки пакетов такой же, как они следуют в XML манифесте, надеюсь это не важно.

Исходные тексты на GitHub

Там же есть папка с готовым бинарником (скрипт + зависимости + ruby 1.9.3, собрано с помощью ocra), нужно просто перетянуть на него

WPexpress_full.exe и наблюдать.

Готовый к употреблению архив в ZIP

Tips & Tricks

Редактор XAML будет пытаться запустить Blend, тот в свою очередь — компонент эмулятора WP8, отчего сам же Blend будет вечно падать. Я сразу переключил редактор XAML на тот что без визуальщины, автокомплит там работает и ладно.

В сухом остатке имеем:

  • Полноценный рабочий SDK для Windows Phone 7.1
  • Нерабочий эмулятор Windows Phone 8
  • Нерабочий редактор интерфейсов Blend для WP 8
  • Неполноценный, но таки рабочий (!) SDK для WP 8

Факт: Windows Phone 8 запускается в VirtualBox на той же Windows 7, но нет курсора мышки и сети, так что пока ничего полезного это не дало.

Желаю удачи с этим делом!

~ Xlab

— UPD: Если у вас была ошибка с бинарником

/src/application.rb:76:in `require_relative': cannot load such file — /src/chain (LoadError)

скачайте новую версию с github, пофикшено.

I have made a console application in C# using MonoDevelop compiled with Mono 3.2.1 configured as AnyCPU in my Ubuntu system.

When I take this application into some Windows 7 64bit system and run it, in task manager list it shows a *32 postfix by its process name. Doesn’t that mean it’s run as a 32bit program? What should I do in order for this application to be run in 64bit?

[UPDATE]

As a point was made in comments, let me clarify that in Windows 7 machine I’m using Microsoft’s .Net library and not Mono’s.

[UPDATE]

I searched the Internet a little bit and found out the following command which outputs stuff about an executable file in Linux:

:~$ file /bin/bash 
/bin/bash: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0xe643cefb2c672ad94e955067c511537ddbab48da, stripped

So I tested it on a .exe file compiled with AnyCPU using Mono and MonoDevelop:

:~$ file /ConsoleTest/bin/Release/ConsoleTest.exe
/ConsoleTest/bin/Release/ConsoleTest.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows

Reading the Wikipedia page PE stands for 32bit programs while PE+ for 64bit ones.

Taking the tests further, I used MS Visual Studio to compile a simple console programs in three modes (AnyCPU, x86 and x64). Once compiled I took all three of them into my Ubuntu machine and tried the file command on them. Here are the results:

:~$ file /ConsoleTest-AnyCPU.exe 
/ConsoleTest-AnyCPU.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows

:~$ file /ConsoleTest-x86.exe 
/ConsoleTest-x86.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows

:~$ file /ConsoleTest-x64.exe 
/ConsoleTest-x64.exe: PE32+ executable (console) x86-64 Mono/.Net assembly, for MS Windows

As you can see only the x64 one is marked as PE+! Then I tried running them in both Ubuntu and Windows.

In Ubuntu all three of them run! But unfortunately I’ve got no mean to say whether they are running in 32bit mode or 64bit!

In Windows while all three of them run (of course they do), the hated *32 postfix is shown in process name only in x86 compiled mode. The lack of *32 indicates that the other two modes of AnyCPU and x64 are running in 64bit.

So my question still stands: What should I do to run an AnyCPU compiled program using Mono and MonoDevelop in Ubuntu, as a 64bit process in Windows?

Table of Contents

Установка и использование MSYS2 и Mingw-w64 под Windows

Текст был первоначально написан для сайта “Железные призраки прошлого”, но затем невозбранно перенесен на эту Wiki и теперь живет тут.

Введение

В целях ретрокомпьютинга иногда возникает желание “что-нибудь скомпилировать под 32-битный Windows”. Ага, ага. Вот и у меня однажды возникала
такая же ситуация. Когда-то давно мне довелось пользоваться компилятором Mingw и оболочкой MSYS, так что я попробовал снова их найти и установить. Оказалось, что там “всё не так, как раньше”.
Вобщем, сейчас ситуация такая: “простой” MinGW и “классический” MSYS обновляться перестали
и они зачахли где-то в районе 2015 года.

ПРИМЕЧАНИЕ: Надеюсь, читатели понимают разницу между Cygwin и Mingw. Кратко: Cygwin пытается воссоздать наиболее полную “среду” UNIX/POSIX на Windows, со всеми её фишками, типа fork(), особенностями файловой системы, сигналами, псевдотерминалами и т.д. в то время как Mingw — это (изначально) просто перенос компилятора GCC на Windows, без вот этого всего. А MSYS — это “оболочка”, то есть набор утилит для сборки, главные из которых — пожалуй make и bash. Подробности.

Оказывается, нынче текущая версия MSYS — это MSYS2. Это такой странный гибрид
из Cygwin и старого MSYS.
Подобно Cygwin он делает замену путей в стиле UNIX, маскирует расширение *.exe,
поддерживает псевдотерминалы, UNIX-сигналы и еще много чего. Это, с одной стороны, облегчает перенос и сборку
всяких нетривиальных UNIX программ, а с другой стороны, теперь все msys-программы, в отличии от старого MSYS тянут за собой
DLL-ку: msys-2.0.dll .

А компилятор с тулзами нынче называется Mingw-w64. Это вовсе не значит, что он 64-битный,
это просто такое имя. Он существует во всех возможных комбинациях: 32-битный (т.е. работающий на 32-бит Windows)
для билда 32-битных программ, 64-битный для билдинга 64-битных программ, и все промежуточные
варианты, то есть 32-битный для построения 64-битных и наоборот, 64-битный для 32-бит.

Вы еще не запутались ? Держитесь, это только начало… :)

MSYS2 теперь поддерживает несколько видов терминалов (т.е. программ для отрисовки “текстового” экрана) — один новомодный Mintty,
утащенный с того же Cygwin, который типа лучше поддерживает механизмы терминала UNIX, но опять
же, тянет за собой всякое… Другой — почти классическая Windows-консоль почти без обвеса (ConEmu)
но зато с закладками (Tabs). На самом деле, есть еще третий вид терминала (defterm), но он не совсем поддерживается…
Подробности.
Чтобы запустить MSYS2 c нужным терминалом, надо стартовый msys2_shell.cmd запустить с нужным
ключиком. По-умолчанию запускается Mintty.

Да, сама MSYS2 тоже бывает 32-битная и 64-битная. К счастью на сайте MSYS2 есть нужный инсталлятор,
(msys2-x86_64 или msys2-i686) — это такой огромный файл .EXE, у которого внутри целый архив соответствующих программ.
MSYS2 64-битная по умолчанию ставится в C:msys64, а 32-битная — в C:msys32. Можете попробовать поменять каталог,
но тогда никто ничего не гарантирует… Но вот беда — инсталлятор старый и первое, что нужно сделать —
это обновиться: pacman -Syuu
Этот pacman первым делом обновит сам себя, так что ОБЯЗАТЕЛЬНО надо прибить всё окно! НЕ выходя!!!
И запустить pacman -Syuu еще раз.

Вы еще тут ? Я еще держусь, но с трудом… :)

ПРИМЕЧАНИЕ: С мая 2020 32-битную MSYS2 стали потихоньку сворачивать. Она еще поддерживается, но пакеты для нее выходят крайне редко, а начальный инсталлятор для 32-битной версии MSYS2 убрали с главной стравницы сюда. Следите за новостями. Таким образом, даже для сборки 32-битных приложений нужно использовать 64-битную ОС и 64-битную MSYS2. Увы.

Компилятор и его запуск

Ну вот например поставили мы MSYS2 (без разницы, 64-битную или 32-битную) и обновились. Давайте попробуем, наконец, скомпилить HelloWorld
под Windows консоль. А вот хрен вам! Оказывается, теперь есть НЕ ОДИН компилятор, точнее не одна build-система, а несколько.
Из них первая — для компиляции программ под САМУ MSYS2 (вы же помните, что она тащит за собой теперь как
минимум DLL msys-2.0.dll и работает с UNIX-путями), а остальные build-системы — для обычных “голых” Windows программ,
как в старом добром Mingw. Компилятор и там и там — знакомый Mingw-w64, но по-разному настроенный. Да,
не забываем что всё это может существовать в 32-бит, 64-бит и все комбинации между ними!
Так что на самом деле у нас бывает (как минимум!) ТРИ build системы: msys2, mingw32 и mingw64.
Все три ставить не обязательно. Например, если нам надо только собирать “чистые” 32-битные программы
на 64-битной винде то можно поставить 64-битную MSYS2 без её собственных компиляторов и build-систему mingw32.
(как понимаете, на самом деле это будет 64-битный компилятор по имени Mingw-w64 работающий под 64-битной MSYS2 и который умеет
делать 32-битные “чистые” программы под Windows. Надеюсь крыша у вас еще не поехала…)

Итак, давайте сначала установим тулзы для сборки: pacman --needed -S base-devel
Это установит всякие полезные для сборки утилиты в нашу MSYS2 (любой битности).
Установщик pacman знает про себя, 32-бита он или 64, берёт правильные пакеты и ставит
в правильный каталог. Репозиторий для любой MSYS2 всегда называется просто msys2 :)
Компилятор для самой MSYS2 в base-devel не входит, да он нам и не нужен.

MSYS2 Menu
А вот теперь аккуратнее! Чтобы установить build-систему, которая делает 32-бит программы
надо установить группу mingw-w64-i686-toolchain. То есть компилятор называется Mingw-w64
(помним, что это просто название такое). Ставится он на нашу текущую MSYS2 и будет
генерить 32-битные программы (хвостик -i686). Делаем pacman -S --needed mingw-w64-i686-toolchain.
Пакеты компилятора скачаются (из репозитория mingw32) и будут установлены.
Вот только никакого компилятора не появится!

Чтобы воспользоваться нужным компилятором, надо запустить нашу MSYS2 особым образом.
Если вы откроете кнопку Пуск –> Все программы –> “MSYS2 32bit” то увидите три разных “среды”:
“MSYS2 MSYS”, “MSYS2 MinGW 32bit” и “MSYS2 MinGW 64bit” (а в новых добавились еще clang и ucrt). По крайней мере, на Windows7 так.
На Windows10 эти программы расположены в главном меню под буквой “M”. Вот эти три разные режима запуска и делают всю магию.
Альтернативный путь — запускать напрямую программы из папки C:msys64……exe или скрипт C:msys64msys2_shell.cmd с ключами -mingw32, -mingw64
или -msys2. Это точно то же самое.

Давайте запустим “MSYS2 MinGW 32bit”. Вот теперь у нас доступен компилятор gcc, причем он полностью
настроен, с указанием папки include, линкера и пути к библиотекам. Ура!

Пишем программы

Создадим Си-шный файлик hello.c со стандартным библиотечным вызовом printf():

#include <stdio.h>

int main () {
   printf("Hello, World!n");
   return 0;
}

откомпилим его:

$ gcc -o hello hello.c

и запустим ИЗ CMD.EXE (то есть из другого окна CMD, а не из оболочки MSYS2):

C:TEMPTEST>hello
Hello, World!

Всё работает.
Есть и недостатки — полученный EXE-шник имеет размер почти 300Kb! Воспользуемся командой
strip и удалим из него все лишнее. Получится EXE-шник около 16К, что гораздо лучше.
Посмотрим, что у нас получилось (пример из Windows 7):

$ file hello.exe
hello.exe: PE32 executable (console) Intel 80386, for MS Windows

$ ldd hello.exe
        ntdll.dll => /c/Windows/SYSTEM32/ntdll.dll (0x772c0000)
        kernel32.dll => /c/Windows/system32/kernel32.dll (0x768e0000)
        KERNELBASE.dll => /c/Windows/system32/KERNELBASE.dll (0x75130000)
        msvcrt.dll => /c/Windows/system32/msvcrt.dll (0x76ae0000)

Как и требовалось, это “чистое” автономное 32-битное консольное Win32 приложение, которое использует только
стандартные библиотеки 32-битного Windows (можно поспорить насчет стандартности
MSVCRT.DLL, в котором и располагается printf()), но по факту, она есть практически везде. На 64-битном Windows вывод ldd будет несколько другой, поскольку там другая архитектура запуска 32-битных программ WindowsOnWindows (WoW). Скорее всего, эта программа будет
работать даже в Windows 95, поскольку формат PE-файла не изменился (не пробовал).

В данном пакете сразу включен Windows SDK, поэтому можно писать программы на Win32 API,
как невинные так и более
серьезные, типа CreateFile( L“\\.\PhysicalDrive0”…

Давайте теперь напишем оконную программку под Windows (точнее под Win32). Вытащим
пример из старика Петзольда (Charles Petzold. Programming Windows):

#include <windows.h>

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     MessageBox (NULL, TEXT ("Hello, Windows!"), TEXT ("HelloMsg"), 0) ;
     return 0 ;
}

откомпилируем:

$ gcc -mwindows -o hellowin hellowin.c

Все работает. Чтобы указать, что у нас оконная, а не консольная программа,
используется ключ -mwindows . Первоначально ключ -m служил для указания модели машины или
процессора, а тут его приспособили для указания “подсистемы”. Если в программе есть WinMain(),
то даже -mwindows указывать не обязательно, компилятор сам понимает, но на всякий случай укажем.

ПРИМЕЧАНИЕ1: Не стоит ждать многого от штатной библиотеки MSVCRT.DLL . Это далеко не полная реализация libc.
Кроме явного отсутствия “юниксовых” возможностей типа fork() и т.д. расхождения могут быть совсем неожиданные (и в разных версиях Windows — разные).
Например, printf() не поддерживает формат %zd для типа size_t и другие неожиданные вещи. Компилятор
Mingw-w64 знает много таких особенностей и по мере возможностей дает предупреждения. Подробности.

ПРИМЕЧАНИЕ2: Компиляторы gcc, а особенно g++ иногда создают код, который зависит от библиотек
libgcc и libstdc++. Чтобы полученное приложение не требовало соответствующих DLL, в командную
строку можно добавить опции -static-libgcc и -static-libstdc++. Библиотеки же, которые являются “стандартными”
для Windows, умный Mingw-w64 всегда делает динамическими, даже несмотря на присутствие опции -static
в опциях компилятора.

Консольные полноэкранные приложения

TODO. Параграф не дописан! Имеются проблемы со сборкой static!

При портировании UNIX-приложений на MSYS2 часто возникают сложности с работой “полноэкранных” текстовых приложений, TUI (Text User Interface) т.е. требущих управления экраном и управления курсором.

Тут надо сначала немного углубиться в теорию. С точки зрения UNIX мы имеем две сложно-взаимодействующих абстракции:

  1. Стандартные потоки STDIN/STDOUT/STDERR. Это псевдо-файлы, которые передаются при старте UNIX программы, с номерами файловых десткрипторов 0,1, и 2. Довольно часто, это не терминал, а вывод из предыдущей программы (pipe) или реальный файл.

  2. Терминал TTY. У терминала в UNIX имеется множество функций и атрибутов. Например, имеется API управления дисциплиной линии (всякие RTS/CTS), различные режимы ввода (с эхо или без) termio/termios, возможность переключения raw/cooked режимов, а также специальные функции управления заданиями (job control, например обработка CTRL-C, CTRL-Z) и т.д. Кроме того, у каждой разновидности терминала имеется база, описывающая его систему команд, в основном через ESC-последовательности (termcap/terminfo).

На Windows — совершенно другая идеология управления консолью (WinAPI Console). (Пример: Пишем простое консольное приложение на чистом WinAPI). Поэтому и возникает необходимость в эмуляторе терминала и промежуточной библиотеке типа msys-2.0.dll или cygwin.dll, которая имитирует (с разной степенью успешности) поведение UNIX системы. Тем или иным способом в оболочках типа MSYS2 и CYGWIN эта проблема решена. Но с “автономными” консольными Windows приложениями неколько сложнее. На это накладывается взаимодействие c MSVCRT.DLL, которая имитирует файловые потоки STDIN/STDOUT/STDERR и также вносит свои особенности.

Как же быть ?

Можно предложить такое неожиденное решение. Как правило, управление терминалом в UNIX-программах редко делают напрямую, на нижнем уровне через API терминала termio/termios. Как правило, используют готовые библиотеки, например Termcap или Curses. Такую UNIX программу намного легче портировать в консольное “автономное” Windows приложение.

Одна из популярных библиотек, требующих прямого управления консолью — readline. Библиотека GNU Readline используеся довольно широко. Самый известный пример — bash. Давайте установим: pacman -S libreadline-devel и pacman -S mingw-w64-i686-ncurses.

Конец недописанного параграфа.

SDL

Если вы хотите быть современным молодым динамичным программистом, то лучше писать на каком-нибудь
Framework :) (как етто по рюсcки? Каркас?). Например, очень большое число разных эмуляторов
винтажных систем написано на SDL.

По SDL в сети гуляет просто огромное число примеров, туториалов, введений и т.д. SDL рисует,
поёт, поддерживает джойстик и сеть, может быть даже варит кофе… Текущая версия: SDL2.
Давайте поставим себе SDL2 вместе со всеми её запчастями :

pacman -S mingw-w64-i686-SDL2 mingw-w64-i686-SDL2_gfx mingw-w64-i686-SDL2_image
mingw-w64-i686-SDL2_mixer mingw-w64-i686-SDL2_net mingw-w64-i686-SDL2_ttf

(набирать в одну строку или покомпонентно)

Напишем небольшую программу под SDL:

#include <SDL2/SDL.h> 

int main(int argc, char *argv[]) 
{ 
   SDL_Event e;
   int quit = 0;
   SDL_Window* win;
   SDL_Surface* surf;

   SDL_Init(SDL_INIT_EVERYTHING);
   win = SDL_CreateWindow("Hello SDL!", 
                          SDL_WINDOWPOS_CENTERED, 
                          SDL_WINDOWPOS_CENTERED, 
                          320, 240, 0);
   surf = SDL_GetWindowSurface( win );
   SDL_FillRect( surf, NULL, 
               SDL_MapRGB( surf->format, 0, 0, 0xFF ) );
   SDL_UpdateWindowSurface( win );
   while( !quit )
      {    
      while( SDL_PollEvent( &e ) != 0 )
         {
            if( e.type == SDL_QUIT )
               {
                  quit = 1;
               }
         }
      }
   SDL_DestroyWindow(win);
   SDL_Quit();
   return 0; 
}

Программа просто создает маленькое (320×240) окошко с заголовком, закрашивает его синим
(R=0, G=0, B=0xFF) и ждет, когда из нее выйдут.

Компиляция чуть сложнее.

  • Первое: SDL ПЕРЕОПРЕДЕЛЯЕТ функцию main(). То есть наша main() вызывается ИЗ системы SDL, а стартует программа начиная с функции SDL_main(). Это надо явно описать.

  • Второе: Поскольку мы не используем WinMain() напрямую, но хотим программу под Windows и не хотим,чтобы болталось черное окно консоли, то нам нужно ЯВНО добавлять ключ -mwindows .

  • Третье: При сборке нужно указать, что нам необходима библиотека SDL.

Получается целая куча ключей командной строки.

Можно выписать ключи на бумажку или создать make-файл.
Однако всё проще. Многие Frameworks имеют специальные конфиг-файлы, в которых указаны всё
необходимые настройки и нужно просто их использовать. SDL2 — не исключение.

$ sdl2-config --cflags --libs
-I/mingw32/include/SDL2 -Dmain=SDL_main
-L/mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows

Давайте просто подключим вывод в свою командную строку (это делается с помощью
обратного апострофа: ` . Читается как “Использовать ВЫВОД команды”. Подробности в man bash секция “Command Substitution” )

$ gcc -o hellosdl hellosdl.c `sdl2-config --cflags --libs`

Все откомпилировалось. НО! Если мы попытаемся теперь запустить эту программу из CMD.EXE (или просто кликнуть из проводника Windows), мы получим ошибку:

“Запуск программы невозможен, так как на компьютере отсутствует SDL2.dll .

Попробуйте переустановить программу.”

Это неудивительно, так как полученная программа требует для своей работы SDL2.DLL,
а она пока доступна только “изнутри” среды MSYS2. Можно пойти двумя путями: первый — установить
SDL2.DLL “в систему”, второй: просто положить SDL2.DLL в каталог с программой. Тогда за
счет известной особенности Windows “use local DLL” программа при запуске найдет нужную
DLL и подключит. Скачаем нужный runtime (например 32-битный) на сайте
https://www.libsdl.org/download-2.0.php
и просто положим DLL в каталог с программой. Теперь всё запускается из под CMD.EXE и рисует синее окошко.

ПРИМЕЧАНИЕ: Обратите внимание, что MSYS2-шная SDL2.DLL тянет за собой кучу других DLL. Это происходит потому,
что авторы MSYS2 выбрали такой путь: всё что можно — выносить в отдельные библиотеки. Ну ОК. Это хорошо работает
для экономии памяти MSYS2,
но сильно мешает создавать “автономные” приложения Windows на Mingw. Используйте “официальную” SDL2.DLL

Второе. Можно даже саму SDL2.DLL вкомпилить статически. Можно. Но сейчас SDL2 употребляется настолько часто,
что автор считает допустимым использовать такие “инфраструктурные” компоненты, типа QT или той же SDL2 в форме DLL и ставить их “в систему”. Дело вкуса.

OpenGL

Другая самая известная библиотека — это 3D библиотека OpenGL.
По ней также существуют тысячи примеров и туториалов. Не вдаваясь в тонкости OpenGL и его реализации
на разных машинах и видеокартах, попробуем создать OpenGL Windows-приложение. Возьмем, например,
официальные примеры с официального сайта OpenGL.
Например, нарисуем красный кубик: cube.c.

Тут все-таки надо сказать, что OpenGL за время своего существования сменил несколько версий. Поэтому,
при чтении литературы иногда надо обращать внимание, про какую версию OpenGL идет речь.
Вдобавок OpenGL за это время оброс несколькими побочными библиотеками,
которые формально не входят в спецификацию, но все к ним настолько привыкли, что используют их не задумываясь.
Самые часто применяемые — это GLU и GLUT.
Библиотека GLUT, например, обеспечивает связку с операционной системой, в частности создает окно нужным способом:
через X Window на UNIX системах, или через GDI на Windows. Большинство примеров с сайта OpenGL написаны с применением GLU и GLUT. В Windows имеются библиотеки OPENGL32.DLL и GLU32.DLL но нету GLUT.

Как было написано выше, хотелось бы создать максимально независимое Windows-приложение и не таскать за собой libfreeglut.dll. К сожалению, в текущем MSYS2 не очень понятно (мне по крайней мере) разделены
библиотеки, например статическая libglut.a содержится в “базовом” пакете mingw-w64-i686-crt-git, а
реализация freeglut несет с собой libfreeglut_static.a (именно с таким именем, нарушая обычное наименование библиотек
Mingw-w64). В любом случае — установим пакет freeglut: pacman -S mingw-w64-i686-freeglut и откомпилируем наш кубик:

$ gcc -o cube -DFREEGLUT_STATIC cube.c -static -mwindows -lglut -lfreeglut_static -lgdi32 -lwinmm -lglu32 -lopengl32

Для сборки независимого EXE-шника пришлось добавить всю эту цепочку библиотек. Не завидую авторам скриптов ./configure

ПРИМЕЧАНИЕ: Здесь собирается 32-битное приложение. Сборка 64-битных тут пока не рассматривается. Опция -mwindows
нужна, чтобы не создавалось черное окно консоли для Windows-приложений. Библиотека -lwinmm нужна для поддержки джойстика (!) в GLUT.
Библиотеку -lgdi32 в принципе можно не добавлять, она и так унаследуется.

Другая популярная библиотека-“связка” для управления окнами для OpenGL — это GLFW
Установим ее: pacman -S mingw-w64-i686-glfw . Текущая версия: glfw3. Это надо учитывать, когда читаете туториалы,
иногда речь идет о старых версиях без упоминания деталей.

Пример возьмем с официального сайта GLFW: Getting started. Там же есть
краткая инструкция по сборке: Building programs that use GLFW.
Особых сложностей не заметно, за исключением тонкостей сборки со статической и динамической библиотекой GLFW3.DLL.

Скомпилируем:

$ gcc -o glfwtest -DGLFW_DLL glfwtest.c -mwindows -lglfw3 -lgdi32 -lopengl32

Большинство опций нам уже знакомо: -mwindows для создания не-консольного приложения, подключение библиотек,
новое — только определение -DGLFW_DLL согласно рекомендациям по сборке. Получившееся приложение требует GLFW3.DLL ,
которую для Windows можно скачать с официального сайта GLFW. Обратите внимание, что подобно SDL2.DLL —
это “инфраструктурная” библиотека. Использовать ли ее — дело вкуса. Можно скомпилировать GLFW статически:

$ gcc -o glfwtest glfwtest.c -mwindows -static -lglfw3 -lgdi32 -lopengl32

Исполняемый файл увеличится примерно на 200К, за счет включения GLFW внутрь приложения, но зависимости
будут только от “стандартных” DLL имеющихся в Windows.

OpenGL через SDL

Наконец, существует возможность — использовать уже знакомую нам SDL для “склейки” операционной
системы и OpenGL. Это намного удобнее т.к. в SDL имеются функции ввода, управления
манипуляторами, звуком, сетью и т.д. и самое главное — обе библиотеки кросс-платформенные.

<to be continued…>

Дополнительное чтение

In a previous post I talked about building cross platform GUI applications using Eto.Forms. One thing that came up was that to run the applications on Linux, you needed to have Mono installed and to run mono with the executable as an input argument. That’s probably fine if you are building a web application and it’s going to be on limited servers, but if you are distributing a desktop application you may not want to have to guide a user into downloading and using mono themselves.

Luckily, there is actually a way of bundling mono with your application that removes the need for a user to have to download, install, and then run mono. This means you can distribute your application to a Linux machine without any worry about prerequisites.Now I know this isn’t really .NET Core, but one of the most important things about Core is the cross platform-ness. And since Core doesn’t have desktop application support, I may aswell write a little bit on how to make that happen using Mono.

Setup and Install

The craziest thing about looking up how to use Mkbundle on Windows is that there is very little information about it in the past 5 years. Everything I found was from 2013 or earlier, and it was very outdated. It often involved downloading Cygwin and fiddling with paths and environment variables until things just sort of fell into place. To be fair, there comes a time in every Windows developers life when they resign themselves to the fact they will have to install Cygwin for whatever flaky piece of software they need to use, but today is not that day!

Head over to the Mono website and download the latest version for your PC : https://www.mono-project.com/download/stable/

I personally went with the 32 bit, just because everything I read out there was using that version and I didn’t want to run into an issue that “needed” the 32 bit version after all.


This part is important so I’ve put it in bold and put it between horizontal rules just to make sure you read this part! 

After install comes an extremely important step. This might sound like a little side bar but please, if this is your first time trying mkbundle on Windows, you will thank me later. If you try and run MKBundle right away, you will get an error that likely looks like this :

ERROR: The SDK location does not contain a C:Program Files (x86)Mono/bin/mono runtime

I smacked my head against the wall for an age with this. Eventually I actually tracked down the source code for mkbundle on Github. And found this line here : https://github.com/mono/mono/blob/master/mcs/tools/mkbundle/mkbundle.cs#L536

runtime = Path.Combine (sdk_path, "bin", "mono");
if (!File.Exists (runtime))
    Error ($"The SDK location does not contain a {path}/bin/mono runtime");

What it’s trying to do is check that you have a *file* called “C:Program Files (x86)monobinmono”. Now I bold that part about it being a file, because it’s not looking for a directory. On non Windows systems, files don’t need to have extensions (like .exe), but on Windows they typically do. So what we actually need to do is make sure that this “test” passes. And it’s simple. Go to your mono/bin folder. In there, you should find a mono.exe. Make a *copy* of this file, and remove the extension so it is simply called “mono”. And it should sit side by side with your existing exe.

Now this should satisfy the file check and mono should run fine. I have logged a ticket on Github with Mono around this issue here : https://github.com/mono/mono/issues/7731 . So if you have the same problem or you’re coming from Google after smacking your head against the desk repeatedly with this issue, jump on and add your 2 cents!


Fetching The Correct Mono Runtime

OK with that out of the way, after installing everything you should now have a “Mono Command Prompt” available to you on your machine. Just type “Mono” in your start menu and it should pop up!

This works essentially like a regular command prompt, with the Mono commands already built in.

Now the next step is a little tricky. It’s not like you can run mkbundle and suddenly you have an executable for every OS in existence. Instead you need to fetch the runtime for the particular OS you want your application to run on, and bundle it for that particular runtime. If we package an exe with mkbundle right now then the only people that can run that application are people with the same OS (In our case Windows). This is not as dumb as you might first think. If we did do this, it would mean we could distribute an application that could run on Windows without Mono (Obviously), but more importantly without .NET Framework. There is definitely times where this could come in handy, but for now, we want to build for Linux, so let’s do that.

There is supposed to be commands to fetch and download various runtimes to your machine right from the command prompt. Ofcourse, Mono being a flaky POS at times (Sorry, it’s getting irritating working through these issues), the command doesn’t work at all. Instead if we run the command that “should” fetch available runtimes we get :

System.Net.WebException: Error: TrustFailure (The authentication or decryption has failed.)

And if instead we try the command that supposedly will download the runtime we want (For example we know the runtime signature so just slam that in), we will get :

Failure to download the specified runtime from https://download.mono-project.com/runtimes/raw/

So, we have to do everything manually.

First go to this URL : https://download.mono-project.com/runtimes/raw/. You need download the runtime for the particular OS you want to compile to. Once downloaded, you need to extract this to a particular directory in your documents folder. If I downloaded mono 5.10.0 for Ubuntu, then my directory that I extract to should be : C:UsersmyuserDocuments.monotargetsmono-5.10.0-ubuntu-16.04-x64/ .

Once this has been done, we should then be able to run a command within the mono command prompt : mkbundle –local-targets . The output of this should be all “targets” we have available to us.

C:Program Files (x86)Mono>mkbundle --local-targets
Available targets locally:
        default - Current System Mono
        mono-5.10.0-ubuntu-16.04-x64

mkbundle Command

Navigate to your applications directory that you want to “bundle”. In my case I’ve created a simple “HelloWorldConsole” application that does nothing but print out “Hello Mono World”. Inside this directory I run the following command mkbundle HelloWorldConsole.exe –simple -o HelloWorldBundleUbuntu –cross mono-5.10.0-ubuntu-16.04-x64  Where HelloWorldConsole.exe is my built console app, the -o flag is what I want the output filename to be, and the –cross flag tells us which runtime we want to compile for.

mkbundle HelloWorldConsole.exe --simple -o HelloWorldBundleUbuntu --cross mono-5.10.0-ubuntu-16.04-x64
From: C:UserswadegDocuments.monotargetsmono-5.10.0-ubuntu-16.04-x64
Using runtime: C:UserswadegDocuments.monotargetsmono-5.10.0-ubuntu-16.04-x64binmono
     Assembly: C:ProjectsHelloWorldConsoleHelloWorldConsoleHelloWorldConsolebinDebugHelloWorldConsole.exe
       Config: C:ProjectsHelloWorldConsoleHelloWorldConsoleHelloWorldConsolebinDebugHelloWorldConsole.exe.config
     Assembly: C:UserswadegDocuments.monotargetsmono-5.10.0-ubuntu-16.04-x64libmono4.5mscorlib.dll
     Assembly: C:UserswadegDocuments.monotargetsmono-5.10.0-ubuntu-16.04-x64libmono4.5I18N.West.dll
     Assembly: C:UserswadegDocuments.monotargetsmono-5.10.0-ubuntu-16.04-x64libmono4.5I18N.dll
Generated HelloWorldBundleUbuntu

Looks good to me! But let’s test it. Just for comparison sake, I also run the following command : mkbundle HelloWorldConsole.exe –simple -o HelloWorldBundleDefault . This will give us a bundled application but it will be using our default mono runtime (Which in this case is Windows). This will be important later for showing the differences.

Just quickly, I also want to show the size difference between our original application, and our bundled app.

So in terms of bundling, using Windows mono we add about 4mb. For the Ubuntu bundle, we added 8mb. Your guess is as good as mine when it comes to why the huge size difference, but the main thing is that adding 4 – 8mb actually isn’t that bad when you consider a user now doesn’t have to worry about download mono themselves. That’s actually a relatively small bundle when you think about other assets that may be going along with the app like sound, sprites, images etc.

Let’s go ahead and copy these two bundles to our Ubuntu machine for testing.

First we will take a look at our default bundle. Now this shouldn’t work at all because it’s been built for Windows. We even have a command that we can use to check the file type. So let’s try that.

$ file HelloWorldBundleDefault
HelloWorldBundleDefault: PE32 executable (console) Intel 80386, for MS Windows

So straight away it’s telling us this is for Windows. And when we run it…

$ ./HelloWorldBundleDefault
run-detectors: unable to find an interpreter for ./HelloWorldBundleDefault

Yep, so it ain’t happening. Let’s instead try our Ubuntu bundle. First the file command to see if it recognizes that it’s a different sort of application :

$ file HelloWorldBundleUbuntu 
HelloWorldBundleUbuntu: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=eed5097fca4fbf56883313da9cbc2e

So even though under the hood it’s actually the exact same C# executable, it’s been compiled correctly for Ubuntu. And when we run it :

$ ./HelloWorldBundleUbuntu
Hello Mono World

Yes! We did it! It only took me a day of headaches to work out every little issue with mkbundle to get a HelloWorld bundle working on Ubuntu! But we did it!

Final Notes

One final thing I want to say is Mono/mkbundle is pretty crap to work with on Windows. I know there is definitely going to be someone out there that hates me for saying that, but it truly is. Some of these issues that I ran into (Notably the fact it tries to check for an extension-less mono exe when running mkbundle) I can see stackoverflow questions from over a year ago having the exact same problem. That means that these problems are nothing new.

Even the documentation was rife with issues on Windows. Simply put, they didn’t work. In some ways I can understand that Mono is built for non Windows machines in mind, but it is shockingly bad for a product that Microsoft has now taken under it’s wing.

#1

Aleksandr VK

    Newbie

  • Posters
  • 72 Сообщений:

Отправлено 08 Ноябрь 2011 — 20:59

При старте Windows XP до всех сообщений, до черного экрана, сразу на фоне BIOS-информации появляется фраза (в другой кодировке, но перевести удалось):

Windows NT обнаружила только 511 КБ обычной памяти.
Для запуска Windows NT требуется 512КБ обычной памяти.
Может потребоваться обновление этого компьютера или запуск
программы настройки, поставляемой изготовителем.

На компе 512 MB памяти.
Загружался в ERD, Infra CD.
Визуально всё в порядке. Файлы boot.ini и прочее не изменены.
Есть странные директории и файлы, но их перемещение ситуацию не исправило. Да и не доходит до загрузки файлов.
Лог windows (ntbtlog.txt) даже не создается, хотя опция логирования стоит.

Прогнал cureit и avz. Результат ноль.

В инете нашел только одно похожее сообщение, которое появилось 8 часов назад.
http://otvet.mail.ru/question/66407869/

WTF ? Что делать ? Комп-то не грузиться…. :)

  • Наверх

#2


Ko6Ra

Ko6Ra

    Supporter

  • Posters
  • 3 308 Сообщений:

Отправлено 08 Ноябрь 2011 — 21:03

Наш LiveCD или LiveUSB запишите.
Там есть опция BugReport. После работы скрипта появится архивчеГ. Его можно сюда приаттачить или к нам написать.

ыЫ

  • Наверх

#3


Aleksandr VK

Aleksandr VK

    Newbie

  • Posters
  • 72 Сообщений:

Отправлено 09 Ноябрь 2011 — 16:57

Вот только что сумел собрать.

Запустил сканер на подозрительный файл и получил Trojan.PWS.SpySweep.143
Он мог стать причиной проблемы ? Если да, то как лечить комп ?

  • Наверх

#4


userr

userr

    Newbie

  • Members
  • 16 310 Сообщений:

Отправлено 09 Ноябрь 2011 — 17:06

перевод даты в BIOS на месяц/год/10 лет вперед/назад пробовали?

  • Наверх

#5


Aleksandr VK

Aleksandr VK

    Newbie

  • Posters
  • 72 Сообщений:

Отправлено 09 Ноябрь 2011 — 17:33

Нет, еще не пробовал. Сейчас идет сканирование диска С через LiveCD. Закончится — попробую.

  • Наверх

#6


mrbelyash

mrbelyash

    Беляш

  • Members
  • 25 897 Сообщений:

Отправлено 09 Ноябрь 2011 — 17:42

C:WINDOWSsystem32ydueqlf.dll-маячок

  • Наверх

#7


Aleksandr VK

Aleksandr VK

    Newbie

  • Posters
  • 72 Сообщений:

Отправлено 09 Ноябрь 2011 — 18:05

C:WINDOWSsystem32ydueqlf.dll-маячок

Нет такого файла в системе. Это несколько раньше было — его подхватили когда его еще Dr.Web не определял.
Сейчас вылечен.

  • Наверх

#8


Aleksandr VK

Aleksandr VK

    Newbie

  • Posters
  • 72 Сообщений:

Отправлено 09 Ноябрь 2011 — 19:47

Перевод часов в BIOS результата не дал.
Сканирование livecd системы — чисто.

Может и не вирус вовсе ? Что там в bugreport ?

  • Наверх

#9


Aleksandr VK

Aleksandr VK

    Newbie

  • Posters
  • 72 Сообщений:

Отправлено 09 Ноябрь 2011 — 21:29

  • Наверх

#10


Tecak

Tecak

    Newbie

  • Members
  • 1 Сообщений:

Отправлено 10 Ноябрь 2011 — 05:35

У меня вчера с утра после перезагрузки компа вылезла точно такая же фигня.
_________________________________________
Windows NT обнаружила только 504 КБ обычной памяти.
Для запуска Windows NT требуется 512 КБ обычной памяти.
Может потребоваться обновление этого компьютера или запуск
программы настройки, поставляемой изготовителем.
_________________________________________
Промучил комп весь вечер. Пока ничего не помогло. На F8 не реагирует. С USB не грузится. Грузится HirensBootCD — все диски целые, ошибок нет, нашел несколько вирьев (их удаление никак на загрузку не повлияло). Судя по появившимся за сутки темам в инете предположительно это Rootkit.Boot.Cidox.a (BootKit). Что на это скажут специалисты?

PS/ стоит авира про, обновляется своевременно

Сообщение было изменено Tecak: 10 Ноябрь 2011 — 05:37

  • Наверх

#11


Aleksandr VK

Aleksandr VK

    Newbie

  • Posters
  • 72 Сообщений:

Отправлено 10 Ноябрь 2011 — 08:24

Вот тут http://nnm-club.ru/forum/viewtopic.php?t=381665&start=210
пишут что
«Просто подхватили Mayachok.2 в загрузочный сектор — и всего то. Отправленное изображение
DrWeb CureIt, запущенный из-под LiveCD поможет…»

Но мне Drweb не помог. Не нашел Mayachok и не полечил загрузочный сектор.

  • Наверх

#12


mrbelyash

mrbelyash

    Беляш

  • Members
  • 25 897 Сообщений:

Отправлено 10 Ноябрь 2011 — 09:47

Интересно,а если запустить tdsskiller из под лайфсд?

  • Наверх

#13


userr

userr

    Newbie

  • Members
  • 16 310 Сообщений:

Отправлено 10 Ноябрь 2011 — 09:53

Aleksandr VK,
Вы в Поддержку написали, конечно же? пост 2.
Мы тоже тут еще подумаем.

  • Наверх

#14


Aleksandr VK

Aleksandr VK

    Newbie

  • Posters
  • 72 Сообщений:

Отправлено 10 Ноябрь 2011 — 10:59

Aleksandr VK,
Вы в Поддержку написали, конечно же? пост 2.
Мы тоже тут еще подумаем.

Конечно нет :angry: Там было «или». Я выбрал сюда.

Интересно,а если запустить tdsskiller из под лайфсд?

Кто такой и что делает ? Где брать ?

  • Наверх

#15


mrbelyash

mrbelyash

    Беляш

  • Members
  • 25 897 Сообщений:

Отправлено 10 Ноябрь 2011 — 11:02

Aleksandr VK,
Вы в Поддержку написали, конечно же? пост 2.
Мы тоже тут еще подумаем.

Конечно нет :angry: Там было «или». Я выбрал сюда.

Интересно,а если запустить tdsskiller из под лайфсд?

Кто такой и что делает ? Где брать ?

у касперов

  • Наверх

#16


alexbar

alexbar

    Newbie

  • Posters
  • 4 Сообщений:

Отправлено 10 Ноябрь 2011 — 11:14

Та же проблема

Windows NT обнаружила только 477 КБ обычной памяти.
Для запуска Windows NT требуется 512КБ обычной памяти.
Может потребоваться обновление этого компьютера или запуск
программы настройки, поставляемой изготовителем.

но в системе RAID1
при отключении RAID загрузка без проблем и с одного HDD и с другого
NOD LiveCD ничего не нашел
DrWeb LiveCD нашел несколько троянов, удалил но чуда не случилось
продолжаю искать решение

  • Наверх

#17


Aleksandr VK

Aleksandr VK

    Newbie

  • Posters
  • 72 Сообщений:

Отправлено 10 Ноябрь 2011 — 11:20

при отключении RAID загрузка без проблем и с одного HDD и с другого

Что подтверждает что вирус испортил MBR. Попробую вечером восстановить… fdisk /mbd может поможет…

  • Наверх

#18


Aleksandr VK

Aleksandr VK

    Newbie

  • Posters
  • 72 Сообщений:

Отправлено 10 Ноябрь 2011 — 11:30

Интересно,а если запустить tdsskiller из под лайфсд?

TDSSKiller.exe: PE32 executable for MS Windows (GUI) Intel 80386 32-bit
DrwebLiveCD: Linux based загрузочный диск.
Интересно, как же запустить :angry:

  • Наверх

#19


mrbelyash

mrbelyash

    Беляш

  • Members
  • 25 897 Сообщений:

Отправлено 10 Ноябрь 2011 — 11:32

Интересно,а если запустить tdsskiller из под лайфсд?

TDSSKiller.exe: PE32 executable for MS Windows (GUI) Intel 80386 32-bit
DrwebLiveCD: Linux based загрузочный диск.
Интересно, как же запустить :angry:

логика подсказывает что с загрузочного сд на базе винды :(

  • Наверх

#20


alexbar

alexbar

    Newbie

  • Posters
  • 4 Сообщений:

Отправлено 10 Ноябрь 2011 — 11:37

Ну вот решение моей проблемы

Удаление загрузочных вирусов в Windows ХР

Для этого вам потребуется загрузочный диск с консолью восстановления (или дискеты аварийного восстановления). В BIOS нужно установить загрузку с CD-ROM’а, поместить в лоток CD-ROM’а загрузочный диск с установочным пакетом Windows XP Professional и перезагрузиться. Когда установщик Windows XP загрузит свои файлы в оперативную память ПК, появится диалоговое окно Установка Windows XP Professional, содержащее меню выбора, из которого нас интересует пункт *Чтобы восстановить Windows XP с помощью консоли восстановления, нажмите [R=Восстановить].

Нажмите R. Загрузится консоль восстановления. Если на ПК установлена одна ОС, и она (по умолчанию) установлена на диске C:, то появится следующее сообщение:

1: C:WINDOWS

В какую копию Windows следует выполнить вход?

Введите 1, нажмите Enter.

Появится сообщение:

Введите пароль администратора:

Введите пароль, нажмите Enter (если пароля нет, просто нажмите Enter).

Появится приглашение системы:

C:WINDOWS>

введите fixmbr

Появится сообщение:

**ПРЕДУПРЕЖДЕНИЕ**

На этом компьютере присутствует нестандартная или недопустимая основная загрузочная запись. При использовании FIXMBR можно повредить имеющуюся таблицу разделов. Это приведет к утере доступа ко всем разделам текущего жесткого диска.

Если отсутствуют проблемы доступа к диску, рекомендуется прервать работу команды FIXMBR.

Подтверждаете запись новой MBR?

Введите y (что означает yes).

Появится сообщение:

Производится новая основная загрузочная запись на физический диск DeviceHarddisk0Partition0.

Новая основная загрузочная запись успешно сделана.

На появившееся приглашение системы: C:WINDOWS>

Введите fixboot

Появится сообщение:

Конечный раздел: C:.

Хотите записать новый загрузочный сектор в раздел C:?

Введите y (что означает yes).

Появится сообщение:

Файловая система в загрузочном разделе: NTFS (или FAT32).

Команда FIXBOOT записывает новый загрузочный сектор.

Новый загрузочный сектор успешно записан.

На приглашение системы C:WINDOWS>

введите exit, начнется перезагрузка ПК. Нажмите Del, войдите в BIOS Setup и установите загрузку с жесткого диска.

Удачи всем

  • Наверх

File

Uncompress DC682778F53E853B3188AC63EB376D8B.zip (password is «flare») and you will get a file named loader with following properties:

MD5 b767bd2c7c29056505d6ca290330b919
SHA1 11c975a899bf81a152218c62c01acdf937007ad0
SHA256 403c319f2aa744d6cba81ea98881ac91d766b582c907ec5bf0d99f2312d9dbd9
File type PE32 executable (GUI) Intel 80386, for MS Windows

Analysis

loader.exe

Uncompressed files

The file is an AutoIt based executable. Let’s use Exe2aut to decompile the loader.exe file. It results in several files:

challenge-7.sys
Driver for Windows 7
MD5sum dade1de693143d9ef28fe7ebe7a7fb22
SHA1sum 745ba710cf5d4a8cbb906f84e6096ca1b9a1bae3
SHA256sum 59dbf937021c7856bad4155440dbd2e0c5422f06589bb11e5ac0b3300aad629c
File type PE32 executable (native) Intel 80386, for MS Windows
challenge-xp.sys
Driver for Windows XP
MD5sum 399a3eeb0a8a2748ec760f8f666a87d0
SHA1sum 393f2aefa862701642f566cdaee01a278e2378c0
SHA256sum 57b1d7358d6af4e9d683cf004e1bd59ddac6047e3f5f787c57fea8f60eb0a92b
File type PE32 executable (native) Intel 80386, for MS Windows
ioctl.exe
Driver controller
MD5sum 205af3831459df9b7fb8d7f66e60884e
SHA1sum dfb2dc09eb381f33c456bae0d26cf28d9fc332e0
SHA256sum 44473274ab947e3921755ff90411c5c6c70c186f6b9d479f1587bea0fc122940
File type PE32 executable (console) Intel 80386, for MS Windows
loader_.au3
The decompiled version of the AutoIt executable

Decrypt loader.exe

As the file names suggest, we probably have to do with a driver that is controlled by ioctl.exe. A dynamic analysis confirms it and we can see that the appropriate driver is chosen depending on whether it is run on Windows XP or Windows 7 before being renamed to challenge.sys and placed in %WINDIR%System32 along with ioctl.exe.

The loader_.au3 file shows encrypted content that is passed to the dothis() function. This function accepts 2 parameters: the encoded string and a key.

Flare-on-challenge-2015-l10-loader-encrypted-content.png

To decode these strings, we will reuse the decryption functions already in the code. To do that, download the AutoIt program and modify the source code by replacing the Execute statement with MsgBox in the dothis() function:

Func dothis($data, $key)
	$exe = decrypt($data, $key)
	$exe = BinaryToString($exe)
	;Return Execute($exe)
        Return MsgBox(0, "DEBUG", $exe)
EndFunc

Run the modified executable and you will get this:

Flare-on-challenge-2015-l10-patched-autoit.png

If @OSArch <> "X86" Then
	MsgBox(0, "Unsupported architecture", "Must be run on x86 architecture")
	Exit
EndIf
If @OSVersion = "WIN_7" Then
	FileInstall("challenge-7.sys", @SystemDir & "challenge.sys")
ElseIf @OSVersion = "WIN_XP" Then
	FileInstall("challenge-xp.sys", @SystemDir & "challenge.sys")
Else
	MsgBox(0, "Unsupported OS", "Must be run on Windows XP or Windows 7")
	Exit
EndIf
FileInstall("ioctl.exe", @SystemDir & "ioctl.exe")
$nret = _CreateService("", "challenge", @SystemDir & "challenge.sys", "", "", $SERVICE_KERNEL_DRIVER, $SERVICE_DEMAND_START)
If $nret Then
	If _StartService("", "challenge") Then
		ShellExecute(@SystemDir & "ioctl.exe", "22E0DC")
	EndIf
EndIf

Code analysis:

  • first check that the executable is run on a 32 bits OS. If it’s not the case, display an error message and exit.
  • Then check whether the OS is Windows 7 or Windows XP and rename the appropriate driver (respectively challenge-7.sys and challenge-xp.sys to challenge.sys in %WINDIR%system32). If the executable is run on a different OS, display an error message and exit.
  • Install ioctl.exe in %WINDIR%system32
  • Register the challenge.sys driver as a service named challenge and send the ID 22E0DC to the controler (ioctl.exe).

ioctl.exe

Now, let’s have a look at ioctl.exe. Nothing special here. The DeviceIoControl function is just passing the argument to the IRP table of the driver. Now, let’s open our driver to check what is called at this IRP.

challenge.sys

Determine index

Let’s use challenge-7.sys for our analysis. A quick analysis shows that the IRP code (22E0DC) is sent to sub_29CD20 which is the IRP dispatcher.

.text:0029CD20 ; int __stdcall sub_29CD20(int, PIRP Irp)
.text:0029CD20 sub_29CD20      proc near
.text:0029CD20
.text:0029CD20 var_20          = dword ptr -20h
.text:0029CD20 var_1C          = byte ptr -1Ch
.text:0029CD20 var_15          = byte ptr -15h
.text:0029CD20 var_14          = dword ptr -14h
.text:0029CD20 var_5           = byte ptr -5
.text:0029CD20 var_4           = dword ptr -4
.text:0029CD20 Irp             = dword ptr  0Ch
.text:0029CD20
.text:0029CD20                 mov     edi, edi
.text:0029CD22                 push    ebp
.text:0029CD23                 mov     ebp, esp
.text:0029CD25                 sub     esp, 20h
.text:0029CD28                 mov     [ebp+var_5], 41h
.text:0029CD2C                 mov     eax, [ebp+Irp]           ; IRP code saved to EAX
.text:0029CD2F                 mov     dword ptr [eax+18h], 0
.text:0029CD36                 mov     ecx, [ebp+Irp]
.text:0029CD39                 mov     dword ptr [ecx+1Ch], 0
.text:0029CD40                 mov     edx, [ebp+Irp]
.text:0029CD43                 push    edx
.text:0029CD44                 call    sub_29D7B0
.text:0029CD49                 mov     [ebp+var_14], eax       ; EAX saved to var_14
.text:0029CD4C                 mov     eax, [ebp+var_14]       ; var_14 saved to EAX
.text:0029CD4F                 mov     cl, [eax]
.text:0029CD51                 mov     [ebp+var_1C], cl
.text:0029CD54                 cmp     [ebp+var_1C], 0Eh
.text:0029CD58                 jz      short loc_29CD5F
.text:0029CD5A                 jmp     loc_29D46B      ; jumptable 0029CD91 default case
.text:0029CD5F ; ---------------------------------------------------------------------------
.text:0029CD5F
.text:0029CD5F loc_29CD5F:
.text:0029CD5F                 mov     edx, [ebp+var_14]
.text:0029CD62                 mov     eax, [edx+0Ch]
.text:0029CD65                 mov     [ebp+var_4], eax
.text:0029CD68                 mov     ecx, [ebp+var_4]
.text:0029CD6B                 mov     [ebp+var_20], ecx
.text:0029CD6E                 mov     edx, [ebp+var_20]
.text:0029CD71                 sub     edx, 22E004h           ; EDX = IRP code - 0x22E004
.text:0029CD77                 mov     [ebp+var_20], edx      ; 
.text:0029CD7A                 cmp     [ebp+var_20], 190h ; switch 401 cases
.text:0029CD81                 ja      loc_29D46B      ; jumptable 0029CD91 default case
.text:0029CD87                 mov     eax, [ebp+var_20]
.text:0029CD8A                 movzx   ecx, ds:byte_29D614[eax]
.text:0029CD91                 jmp     ds:off_29D480[ecx*4] ; switch jump
.text:0029CD98 ; ---------------------------------------------------------------------------

At offset 0x29CD71, we see that 0x22E004 is substracted from the IRP code to get an index. In our case, the index is:

0x22E0DC - 0x22E004 = 0x18

This index is used to get a value from byte_29D614[eax]. In our case, it returns:

 Python>hex(Byte(0x29D614+0xd8))
 0x36
 

This index is then used in a second table to jump to a new location (jmp ds:off_29D480[ecx*4]):

 Python>hex(Dword(0x29D480+0x36*4))
 0x29d180L
 

Here is the code at this location:

.text:0029D180 loc_29D180:             ; jumptable 0029CD91 case 216
.text:0029D180 movzx   eax, [ebp+var_5]
.text:0029D184 push    eax
.text:0029D185 call    sub_29C1A0
.text:0029D18A mov     [ebp+var_15], al
.text:0029D18D jmp     loc_29D46B

sub_29C1A0

It only calls the sub_29C1A0 function. Let’s jump to that function:

Flare-on-challenge-2015-l10-sub 29C1A0.png

This function is performing a binary check of each bit (value 0 or 1) of a sequence of bytes and jumps to different branches depending on the value of the probed bit. Below is the code corresponding to the checks performed on the 1st byte (8 tests because 1 byte = 8 bits):

.text:0029C1C7                 movzx   ecx, byte ptr [ebp+var_1C]
.text:0029C1CB                 and     ecx, 1
.text:0029C1CE                 jz      short loc_29C1D7 ; jump if 8th bit is 0
.text:0029C1D0                 xor     al, al
.text:0029C1D2                 jmp     loc_29CCE6
.text:0029C1D7 ; ---------------------------------------------------------------------------
.text:0029C1D7
.text:0029C1D7 loc_29C1D7:                             ; CODE XREF: sub_29C1A0+2E�j
.text:0029C1D7                 movzx   edx, byte ptr [ebp+var_1C]
.text:0029C1DB                 and     edx, 2
.text:0029C1DE                 jz      short loc_29C1E7 ; jump if 7th bit is 0
.text:0029C1E0                 xor     al, al
.text:0029C1E2                 jmp     loc_29CCE6
.text:0029C1E7 ; ---------------------------------------------------------------------------
.text:0029C1E7
.text:0029C1E7 loc_29C1E7:                             ; CODE XREF: sub_29C1A0+3E�j
.text:0029C1E7                 movzx   eax, byte ptr [ebp+var_1C]
.text:0029C1EB                 and     eax, 4
.text:0029C1EE                 jnz     short loc_29C1F7 ; jump if 6th bit is 1
.text:0029C1F0                 xor     al, al
.text:0029C1F2                 jmp     loc_29CCE6
.text:0029C1F7 ; ---------------------------------------------------------------------------
.text:0029C1F7
.text:0029C1F7 loc_29C1F7:                             ; CODE XREF: sub_29C1A0+4E�j
.text:0029C1F7                 movzx   ecx, byte ptr [ebp+var_1C]
.text:0029C1FB                 and     ecx, 8
.text:0029C1FE                 jz      short loc_29C207 ; jump if 5th bit is 0
.text:0029C200                 xor     al, al
.text:0029C202                 jmp     loc_29CCE6
.text:0029C207 ; ---------------------------------------------------------------------------
.text:0029C207
.text:0029C207 loc_29C207:                             ; CODE XREF: sub_29C1A0+5E�j
.text:0029C207                 movzx   edx, byte ptr [ebp+var_1C]
.text:0029C20B                 and     edx, 10h
.text:0029C20E                 jnz     short loc_29C217 ; jump if 4th bit is 1
.text:0029C210                 xor     al, al
.text:0029C212                 jmp     loc_29CCE6
.text:0029C217 ; ---------------------------------------------------------------------------
.text:0029C217
.text:0029C217 loc_29C217:                             ; CODE XREF: sub_29C1A0+6E�j
.text:0029C217                 movzx   eax, byte ptr [ebp+var_1C]
.text:0029C21B                 and     eax, 20h
.text:0029C21E                 jnz     short loc_29C227 ; jump if 3th bit is 1
.text:0029C220                 xor     al, al
.text:0029C222                 jmp     loc_29CCE6
.text:0029C227 ; ---------------------------------------------------------------------------
.text:0029C227
.text:0029C227 loc_29C227:                             ; CODE XREF: sub_29C1A0+7E�j
.text:0029C227                 movzx   ecx, byte ptr [ebp+var_1C]
.text:0029C22B                 and     ecx, 40h
.text:0029C22E                 jnz     short loc_29C237 ; jump if 2nd bit is 1
.text:0029C230                 xor     al, al
.text:0029C232                 jmp     loc_29CCE6
.text:0029C237 ; ---------------------------------------------------------------------------
.text:0029C237
.text:0029C237 loc_29C237:                             ; CODE XREF: sub_29C1A0+8E�j
.text:0029C237                 movzx   edx, byte ptr [ebp+var_1C]
.text:0029C23B                 and     edx, 80h
.text:0029C241                 jz      short loc_29C24A ; jump if 1st bit is 0
.text:0029C243                 xor     al, al
.text:0029C245                 jmp     loc_29CCE6

For the 1st byte, here is what we have:

bit # 8 7 6 5 4 3 2 1
expected value 0 0 1 0 1 1 1 0

wich results (with bits reordered) in 01110100 or 116 in decimal (ASCII char t). And so on for all bytes in the sequence.

Instead of manually performing the same task for all bytes, you can write a python script and execute it in IDA-Pro (Alt+F7):

tmp = ''
secret = []
loc = 0x29C1CE

while loc < 0x29CCE0:

    # Check whether instruction is jz
    if Byte(loc) == 0x74 and (Byte(loc + 1) == 0x7 or Byte(loc + 1) == 0x4):
        tmp += '0'
    # Check whether instruction is jnz
    elif Byte(loc) == 0x75 and (Byte(loc + 1) == 0x7 or Byte(loc + 1) == 0x4):
        tmp += '1'

    # When all 8 bits are tested, reverse bit order and get ascii char corresponding to byte
    if len(tmp) == 8:
        secret.append(chr(int(tmp[::-1], 2)))
        tmp = ''

    loc+=1

print ''.join(secret)

This script displays the following message:

try this ioctl: 22E068

IRP 22E068

Let’s do the same process with this new IRP. We can directly determine the location as follows:

Python>hex(Dword(0x29D480+Byte(0x29D614+0x22E068-0x22E004)*4))
0x29cf5aL

At this location (offset 0x29cf5a), the code looks like this:

.text:0029CF5A                 call    sub_2D2E0
.text:0029CF5F                 jmp     loc_29D46B

Let’s analyze the sub_2D2E0 function.

sub_2D2E0

This function is also very complex as depicted on the following graph:

Flare-on-challenge-2015-l10-sub 2D2E0.png

It is actually a series of conditions and sub-conditions, but a deeper analysis of some of these branches shows that there are actually fake tests. Indeed, as shown on the below screenshot, the execution workflow will always be the same since EDX is set to 0.

Flare-on-challenge-2015-l10-fake-condition.png

At the very end of the function, we notice that there is a buffer (byte_29f210) sent to another function (sub_110F0) as follows:

Flare-on-challenge-2015-l10-byte 29f210.png

A quick analysis of sub_110F0 shows a very probable encryption routine:

Flare-on-challenge-2015-l10-sub 110F0.png

Without going further in the analysis of this function, let’s try to debug the driver and stop after the call to this function to check what value the buffer has. Unfortunately, it only contains zeroes.

Patch the sub_2D2E0 function

At this stage, we can guess that we have to patch the sub_2D2E0 function in order to take the jumps where we had fake tests. The problem is that Windows won’t let us load a modified driver because an integrity check is performed. For this reason, the best is to dump the memory segment that corresponds to the function, patch it, and reimport the segment. This way, we will be able to execute the function and put a breakpoint after the call to the encryption routine. Let’s detail this process.

Once your kernel debugging environment is ready, let’s open WinDbg on the debugger’s side and put a breakpoint when the driver is loaded:

kd> sxe ld challenge
kd> g

On the debuggee’s side, execute loader.exe. It will copy challenge.sys and ioctl.exe to C:WindowsSystem32, register the driver and start the service as studied previously. When the driver will be loaded, it should freeze the debuggee and you should see the following output on the debugger’s side:

ModLoad: 9aa16000 9acab000   challenge.sys
nt!DbgLoadImageSymbols+0x47:
82a34578 cc              int     3

Now, we will dump the driver header to get the address of the entry point:

kd> !dh challenge
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
     14C machine (i386)
       6 number of sections
55B81359 time date stamp Wed Jul 29 01:42:17 2015

       0 file pointer to symbol table
       0 number of symbols
      E0 size of optional header
     102 characteristics
            Executable
            32 bit word machine

OPTIONAL HEADER VALUES
     10B magic #
    9.00 linker version
  28E600 size of code
    2200 size of initialized data
       0 size of uninitialized data
  29203E address of entry point
    1000 base of code
[REMOVED]

Now, we can break at the entry point:

kd> bp challenge+29203E
Loading symbols for 9aa16000    challenge.sys ->   challenge.sys
*** ERROR: Module load completed but symbols could not be loaded for challenge.sys
kd> g
Breakpoint 0 hit
challenge+0x29203e:
9aca803e 8bff            mov     edi,edi

It is important to take note of the offset 9aca803e because we will have to convert addresses in IDA-Pro to get the equivalent of the ones in WinDbg. You can use a small python snipet as follows:

# d = delta between EP in WinDbg and IDA Pro
d=0x9aca803e-0x2a203e
def convaddr(a):
    return hex(a+d)

At this stage, we want to break at location 0x29cd71 (converted to 0x9aca2d71), just before the index is computed. It will enable us to modify the value of the IRP because the one by default is 22E0DC and we want to use 22E068 instead, as seen previously.

kd> bp 9aca2d71
kd> g
Breakpoint 1 hit
challenge+0x28cd71:
9aca2d71 81ea04e02200    sub     edx,22E004h

We need to change the value of EDX because it contains the default IRP:

kd> redx
edx=0022e0dc
kd> r @edx=22E068

And put a breakpoint at location 0x29cf5a (converted to 0x9aca2f5a) because this is the branch that will be taken with this IRP.

kd> bp 9aca2f5a
kd> g
Breakpoint 2 hit
challenge+0x28cf5a:
9aca2f5a e88103d9ff      call    challenge+0x1d2e0 (9aa332e0)

Now, the program is stopped just before sub_2D2E0 is called. This is where we want to patch the function. Let’s dump the memory segment corresponding to this function (In IDA Pro, right click on function and select Edit function..). Then convert the addresses as follows:

Flare-on-challenge-2015-l10-dump-sub 2D2E0.png

kd> .writemem sub_2D2E0.mem 9aa332e0 9aab3c3a
Writing 8095b bytes...

Now patch the dump with a small python snippet:

>cd "program files (x86)windows kits8.1debuggersx86"
>python
>>> fn = "sub_2D2E0.mem"
>>> buf = bytearray(open(fn, 'rb').read())
>>> with open(fn, 'wb') as f:
...     f.write(buf.replace("xc6x45x9ex00", "xc6x45x9ex01"))
...
>>> exit()

And reimport the patched memory segment into WinDbg:

kd> .readmem sub_2D2E0.mem 9aa332e0 9aab3c3a
Reading 8095b bytes............

Now we want to set a breakpoint just after sub_110F0 is called, at offset 0xADC36 (converted to 0x9aab3c36) and get the value of byte_29F210 (converted to 0x9aca5210).

kd> bp 9aab3c36
kd> g
Breakpoint 3 hit
challenge+0x9dc36:
9aab3c36 8be5            mov     esp,ebp
kd> da 9aca5210
9aca5210  "[email protected]"
9aca5230  "n.com"

Solution

The solution is [email protected].

Keywords:
reverse-engineering
challenge
flare
fireeye
autoit
sys
kernel
driver
windbg

Понравилась статья? Поделить с друзьями:
  • Pcradio premium для windows 10 скачать
  • Pdo could not find driver windows
  • Pdfelement pro для windows скачать бесплатно на русском языке
  • Pdfbinder скачать бесплатно на русском для windows 10 64 bit
  • Pcomm dll скачать для windows 10