Ещё одну хитрую штуку хочу...
От: nen777w  
Дата: 12.11.09 01:06
Оценка:
Как вставить кусок бинарных данных (из файла/вручную) в код программы.
Например:

void  foo()
{
  for( int n = 0; n < m; n++ ) 
  {
     int k = n*m;
     goto skip_bin;
begin_bin_data:
     мои бинарные данные
skip_bin:
  }
}


И получить в компайл тайме в какую то константу адрес начала этих данных т.е. с метки begin_bin_data:

Только не советуйте завести массив char-ов это не то что мне нужно.
Мне нужно вставить бинарные данные именно в тело функции.

Есть идея на препроцессоре забить между _asm { кучу nop-ов } потом написать утилиту обрабатывающую экзешник.
Но хотелось бы добиться это средствами языка, без хаков тем более этот код должен компилится под разными компиляторами.
Re: Ещё одну хитрую штуку хочу...
От: Cyberax Марс  
Дата: 12.11.09 01:10
Оценка: :)
Здравствуйте, nen777w, Вы писали:

N>Есть идея на препроцессоре забить между _asm { кучу nop-ов } потом написать утилиту обрабатывающую экзешник.

N>Но хотелось бы добиться это средствами языка, без хаков тем более этот код должен компилится под разными компиляторами.
Чистый C? Можно попробовать так (если данные на стеке):
void  foo()
{
  for( int n = 0; n < m; n++ ) 
  {
     int k = n*m;
     void *start, *end;
     goto skip_bin;

begin_bin_data:
     {
          int marker=1;
          start=&marker;
     }
     мои бинарные данные
     {
          int marker=1;
          end=&marker;
     }
skip_bin:
  }
}
Sapienti sat!
Re[2]: Ещё одну хитрую штуку хочу...
От: nen777w  
Дата: 12.11.09 01:35
Оценка:
спасибо, но на стеке не подходит.
По сути хочется спрятать исполняемый код виртуальной машины внутри реального кода.
Что бы при дизассемблировании это выглядело как нормальный asm код, который по сути белеберда
И в то же время надо где то хранить адрес начала этого бинарного кода что бы виртуальная машинка могла его выполнить.
Ну и опять повторюсь не хотелось бы делать внешние утилиты а добиться этого сразу при компиляции.
Re[3]: Ещё одну хитрую штуку хочу...
От: CreatorCray  
Дата: 12.11.09 07:06
Оценка:
Здравствуйте, nen777w, Вы писали:

N>По сути хочется спрятать исполняемый код виртуальной машины внутри реального кода.

N>Что бы при дизассемблировании это выглядело как нормальный asm код, который по сути белеберда
Если у тебя в основном коде нет jmp в этот кусок то нормальные дизассемблеры его выделят как кусок данных и дизасмить не станут.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re: Ещё одну хитрую штуку хочу...
От: std.denis Россия  
Дата: 12.11.09 07:47
Оценка: 6 (1)
Заменить "мои бинарные данные" на #include "my_binary_data.h", и внешней утилитой создавать из бинарных данных этот "my_binary_data.h", содержащий байты сконверченные в текст. Например в такой:
#define DB(x) __asm _emit x;
    DB(0x12);
    DB(0x34);
    DB(0x56);
#undef DB
Это для VC. Для GCC нужно поменять определение DB(x). Ну или лучше сделать без макроса, а чтобы утилита сразу фигачила правильные команды для нужного компилятора.
Re[4]: Ещё одну хитрую штуку хочу...
От: std.denis Россия  
Дата: 12.11.09 07:56
Оценка:
CC>Если у тебя в основном коде нет jmp в этот кусок то нормальные дизассемблеры его выделят как кусок данных и дизасмить не станут.
Угу, поэтому jmp нужно сделать условным, и подобрать неочевидное условие, которое будет всегда вызывать переход. А вычисление адреса перехода опять же сделать на основе математики. Хотя тут конечно лучше шифровать байт-код, чтобы его границы сложно было выделить в исполняемом коде на глаз.

Кстати, можно было бы сделать виртуальную машину, которая выполняет подмножество команд x86, но делает это неожиданным способом. Простейший пример: сложение вместо умножения, умножение вместо деления и т.п. Или такое уже есть?
Re: Ещё одну хитрую штуку хочу...
От: sch  
Дата: 12.11.09 09:17
Оценка: 6 (1) -1
N>Как вставить кусок бинарных данных (из файла/вручную) в код программы.

Пишешь небольшой скрипт, который берёт данные и дампит в виде

db байт1 байт2 байт3 ... байт N

в файлик.

Потом берёшь и в коде делаешь вот так

_asm
{
begin:

#include "my_dumped_file.hpp"

}

Скрипт можно легко вызвать из любого нормального мейкфайла (или генератора мейкфалов), ну или (например) pre-build step если пользуешься вижаком.

Я так делал чтобы включить в код скомпилированный шейдер, очень удобно получилось.
Re[2]: Ещё одну хитрую штуку хочу...
От: nen777w  
Дата: 12.11.09 10:18
Оценка:
Спасибо тебе дорогой товарищ!
То что нужно!
Никогда не знал про _emit

MSVC 2005 — скушала
Посмотрю что скажет GCC под OSX. Ещё интересно что скажет GCC когда будет компилить код для ppc архитектуры.
Re[2]: Ещё одну хитрую штуку хочу...
От: std.denis Россия  
Дата: 12.11.09 10:49
Оценка:
sch>Пишешь небольшой скрипт, который берёт данные и дампит в виде
sch>db байт1 байт2 байт3 ... байт N
угу, осталось объяснить компилятору, что же такое "db"
Re[3]: Ещё одну хитрую штуку хочу...
От: std.denis Россия  
Дата: 12.11.09 10:51
Оценка: 4 (1)
в gcc данные вписываются как-то так: asm(".byte 0x12");
Re: Ещё одну хитрую штуку хочу...
От: nen777w  
Дата: 12.11.09 11:46
Оценка:
Кому интересно вот что получилось:

 //bin_data.h
#define DB(x) __asm _emit x;
    DB(0x0a);
    DB(0x0a);
    DB(0x0a);
    DB(0x01);
    DB(0x02);
    DB(0x03);
    DB(0x04);
    DB(0x05);
    DB(0x0a);
    DB(0x0a);
    DB(0x0a);
#undef DB




int    foo();

#define SetLabel(l, s)            __asm mov dword ptr l, offset s

typedef unsigned __int32 Label;
Label byte_code_begin;
Label byte_code_end;

int main(int argc, char* argv[])
{
    foo();
    return 0;
}

#pragma optimize ("", off)
int    foo()
{
    SetLabel(byte_code_begin, lbl_start_bin);
    SetLabel(byte_code_end, lbl_skip_bin);
    int total = byte_code_end - byte_code_begin;
lbl_start_fn:
    __asm {
        push offset lbl_skip_bin
        ret
    }
lbl_start_bin:
    #include "bin_data.h"
lbl_skip_bin:;
    return 10;
}
#pragma optimize ("", on)


За Макрос SetLabel() отдельное спасибо WolfHound
Re[2]: Ещё одну хитрую штуку хочу...
От: nen777w  
Дата: 12.11.09 11:51
Оценка:
З.Ы.
Кстати говоря о дизассемблерах.
Пробовал дизасемблировать код под IDA как и ожидалось бинарный код выглядит как нормальный asm код.
А вот OllyDbg меня честно говоря удивил, он тупо начинат сбоить
Re: Ещё одну хитрую штуку хочу...
От: Pavel Dvorkin Россия  
Дата: 13.11.09 12:32
Оценка:
Здравствуйте, nen777w, Вы писали:

N>Как вставить кусок бинарных данных (из файла/вручную) в код программы.


http://www.winasm.net/forum/index.php?showtopic=1198

Там есть программа bin2coff. Вызывается так

bin2coff srcfile.ext output.obj label

srcfile.ext :
Any kind of binary file

output.obj :
The name of the object file to be created

label :
A label name presenting the embedded binary data to the linker
Notice that the label should be prefixed with an underscore depending
on the external label naming convention of your development tools.

В итоге имеем obj — файл с публичным символом label. Остается в С написать нечто вроде

extern void* pBitmap

и получить доступ к этим данным. Есть пример, но на асме.

Аналогичная программа bin2obj


N>Но хотелось бы добиться это средствами языка, без хаков тем более этот код должен компилится под разными компиляторами.


Компиляторами — будет, но только для Windows
With best regards
Pavel Dvorkin
Re[2]: Ещё одну хитрую штуку хочу...
От: nen777w  
Дата: 13.11.09 15:01
Оценка:
Спасибо интересно, но я уже утилиту написал которая файл в хидер преобразовывает
(имеется ввиду хидер с макросами как std.denis советовал)

Кстати возник вопрос номер два Пока до документации сам не добрался, только вечером смогу.
Во общем есть чудесная функция для Win32, VirtualProtect() позволяющая установить атрибуты чтения/записи и т.п. для блока памяти.

Нужна такая же только для MacOSX. Опять же повторюсь к доке X-Code пока не добрался, только вечером смогу.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.