Delphi. Простая, но очень полезная функция (при написании игр, искусственных интеллектов, эмуляторов игровых автоматов и т.д.). Функция идентична random: boolean, только с параметром percent, (0 <= percent <= 100) - вероятностью истинного результата. Например, probrandom(80) вернет true с вероятностью 80%. Code: function probrandom(percent: integer): boolean; begin result := random(100) < percent; end; З.Ы. Не забываем инициализировать генератор случайных чисел (randomize)
Code: const alf = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; function power(x,y: integer): int64; begin if x = 0 then result := 0 else result := trunc(exp(ln(x)*y)); end; function fromdec(d: int64; s: integer): string; begin if (d < s) then result := alf[d + 1] else result := fromdec(d div s,s) + alf[d mod s + 1]; end; function todec(d: string; s: integer): int64; begin if length(d) = 1 then result := pos(d,alf) - 1 else result := (pos(d[1],alf) - 1) * power(s, length(d)-1) + todec(copy(d,2,length(d)-1),s); end; Delphi. Системы счисления. 2 <= s <= 36 З.Ы. Рекурсия рулит
И все-таки, как написано в 1 посте, "Не стоит превращать тему в свалку исходников, выбирайте наиболее интересные и полезные участки кода." Выбирайте действительно ИНТЕРЕСНЫЙ и НЕОБЫЧНЫЙ код, какието нестандартные приемы там и прочее. Банальщина типа реализации CopyFile не очень нужна.
Выводит содержимое файла в шестнадцатиричном формате и в виде ASCII кодов. Code: #include <iostream> #include <fstream> #include <cctype> #include <iomanip> using namespase std; int main(int argc, char *argv[]) { if(!argc=2) { cout << "USAGE: Display" rerutn 1; } ifstream in(argv[1], ios::in | ios::binary); if(!in) { cout << "Cannot open input file.\n"; return 1; } register int i, j; int count = 0; char c[16]; cout.setf(ios::uppercase); while(!in.eof()){ for(i=0; i<16 && !in.eof(); i++) { in.get(c[i]); } if(i<16) i--; for(j=0; j<i; j++) cout << setw(3) << hex << (int) c[j]; for(; j<16; j++) cout << " "; cout << "\t"; for(j=0; j<i; j++) if(isprint(c[j])) cout << c[j]; else cout << "."; cout endl; count++; if(count=16) { count=0; cout << "Press ENTER to continue: "' cin.get(); cout << endl; } } in.close(); return 0; }
штука наверняка не новая, но новичкам может быть пригодится: если возникает трудность с использованием модульности (дополнительных длл-плагинов) в своей программе, а именно в обработке плагином, например, своего объекта (так как по-хорошему мы не знаем как он представляется в памяти и видимо не должны знать по причине того, что плагин может быть написан абсолютно на чем угодно), то можно написать свою дополнительную длл, которая имеет набор функций по созданию\обработке обьекта (да хоть переменной какой-то структуры) в пространстве процесса из которого происходила загрузка сего и ее использовать как плагинной так и основной частью программы.
Функция-шаблон считывания из потока n байт. Написал специально для удобства работы с различными потоками в stl. Так, например, нет стандартного метода считывания n байт из объекта ifstream в string в stl. Code: template < typename InputIterator, typename OutputIterator > void readn(InputIterator begin, InputIterator end, int n, OutputIterator out) { for(;n > 0 && begin != end;--n, ++begin, ++out) { *out = *begin; } }
Будь-то программирование на winapi, будь-то программирование на posix при создании многопоточного приложения одинаково часто возникает неудобство выраженное в виде невозможности стандартным образом передать своей функции через CreateThread/pthread_create более одного аргумента. Пример двух используемых функций по вин thread.c: Code: /* thread.c by ZaCo */ #include <windows.h> //вспомогательная функция-поток из которой вызываем запрашиваемую функцию void * Thread(int * temp) { void * func=(void *)(*temp);//вызываемая функция temp++; //переходим к следующему адресу int num=*(int *)temp; //кол-во аргументов int i; temp+=num; //сдвигаемся просто до конца тк аргументы нужно передавать задом-наперед ;) for(i=num-1;i>=0;i--,temp--) { int * param=*(int **)temp;//каждый раз получаем нужный адрес _asm push param; } delete [2+num] (temp-1); //освобождаем память выделенную в NewThread _asm call func; //вызываем функцию return NULL; } //функция создания потока: func - функция, num - кол-во аргументов-указателей после num void * NewThread(void * func, unsigned int num, ...) { int * temp=new int[2+num]; //temp - массив адресов которые в итоге нужно передать функции-потоку memcpy(temp,&func,(2+num)*sizeof(void*)); CloseHandle(CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Thread,temp,0,NULL)); } // Работа в основной программе: Code: #include <stdio.h> void * NewThread(void *, unsigned int, ...); void * Thread(int *); #include "thread.c" void * func(int * a,char * b,int * c, char * s) { printf("%d+%d+%d+%s\n",*a,*b,*c,s); return NULL; } int main(int argc, char* argv[]) { int a=5,b=7,g=4; char s[]="it's xek!"; NewThread(func,4,&a,&b,&g,&s[0]); Sleep(1000); return 0; }
Для Microsoft Visual Studio 7 (она же 2003 .NET): Если нет желания таскать за собой рантайм в том или ином виде, а при его отключении линкер орёт на неразрешенные ссылки на __chkstk, ___securitycookie и @__security_check_cookie@4, можно обойтись следующей реализацией этого (писал сам ) Code: // будем тока выделять место в стеке под переменные extern "C" __declspec(naked) void _chkstk() { __asm { // Enter: EAX = size xor ebx, ebx xchg [esp], ebx // запоминаем адрес возврата add esp, 4 // удаляем его sub esp, eax // выделяем место push ebx // кладем адрес возврата на место и возвращаемся retn } } // любое число, в принципе, но чтобы оно было "случайное", а не вида 00010000. // хороший вариант - 19237845 или BACBBAFD или что-нибудь в этом роде extern "C" DWORD_PTR __security_cookie = 0x5F8E34B0; // проверка на переполнение буфера extern "C" void _fastcall __security_check_cookie(DWORD_PTR cookie) { if(__security_cookie != cookie) // можно добавить ченить более умное при ошибке __asm int 3; }
Stl/c++ Преобразование из string в int с контролем целостности Code: bool to_number(char const* beg, int sz, int& num) { char* end = 0; int tmp_num = ::strtol(beg, &end, 10); if(end != beg + sz) { return false; } num = tmp_num; return true; } use: Code: std::string value; int num; if (!to_number(value.c_str(), value.size(), num)) return false;
что правильнее при написании malware и почему: сначала полностью писать тулзу, а потом править ее так, чтобы не детектилась ав или брать хелло ворлд и добавлять к нему по одной функции на каждом шаге проверяя, что наша прога не палится?
Возникла у меня такая идейка. Функции в Си могут возвращать значение в регистрах eax, edx. Иными словами можно заставить функцию возвратить 2 значения вместо того, чтобы не передавать лишний укказатель указатель. Может быть это не совсем корректно, зато иногда бывает удобно. насколько я разобрался - здесь можно поступить двумя способами: LARGE_INTEGER function xx() { } void main() { LARGE_INTEGER a; a = xx(); a.HigthPart .. a.LowPart } или непосредственно к регистрам void main() { int a,b; xx(); __asm{mov b,edx} __asm{mov a,eax} } P.S. для более удобново вызова можно попробовать переопределить операторы...
Генерации кодов Грея. Пишу для тех, кто знает о чем я. Короче, как вы помните, чувак предложил рекурсивный алгоритм и все такое. Я чуть не попутал, когда убедился, что ту же самую последовательность можно сгенерировать практически одной строкой: Code: for i := 0 to N-1 do writeln(i xor (i div 2)); Какая нах рекурсия!!! Пример использования. Генерация всех подмножеств множества: Code: {$apptype console} var U: array[0..3] of byte = (1, 2, 3, 4); i,k: integer; function checkbit(d, i: integer): boolean; begin if (d and (1 shl i)) = 0 then result := false else result := true; end; begin writeln('Dano: { 1 2 3 4 }'#13#10); for i := 0 to 16 - 1 {16 - 2^N, N=4 - мощность множества} do begin write('{ '); for k := 4-1 {N-1} downto 0 do if checkbit((i xor (i div 2)), k) then write(U[4-1 {N-1} -k],' '); writeln('}'); end; readln; end. Также хочу показать простой способ построения таблиц истиности логических выражений. Допустим, нужно построить: Code: X or (Y and Z) | X | Y | Z | Y and Z | X or (Y and Z) | | 0 | 0 | 0 | 0 | 0 | | 0 | 0 | 1 | 0 | 0 | | 0 | 1 | 0 | 0 | 0 | | 0 | 1 | 1 | 1 | 1 | | 1 | 0 | 0 | 0 | 1 | | 1 | 0 | 1 | 0 | 1 | | 1 | 1 | 0 | 0 | 1 | | 1 | 1 | 1 | 1 | 1 | Вот так это делается быстро и красиво: Code: {$apptype console} type myBool = 0..1; var X,Y,Z: myBool; i: integer; function checkbit(d, i: integer): myBool; begin if (d and (1 shl i)) = 0 then result := 0 else result := 1; end; begin writeln('X or (Y and Z)'); writeln('| X | Y | Z | Y and Z | X or (Y and Z) |'); for i := 0 to 7 do begin X := checkbit(i,2); Y := checkbit(i,1); Z := checkbit(i,0); write('| ',X,' | ',Y,' | ',Z,' | ',Y and Z,' | ',X or (Y and Z),' |'); writeln; end; readln; end.
Вот только недавно сталкнулся с одной проблемой в сетевом программировании. Навреное и другие тоже сталкивались с этим. А именно: когда стоит на компе Kaspersky Antivirus ( на 6 версии - 100%) то любой connect будет удачным. В том смысле: при коннекте к любому компу на заведомо закрытый порт - коннект пройдет удачно, в следствии того, что каспер подменяет IP и порт на localhost:1110 - какбы на свой прокси, с целью проверки трафика и именно по этой причине все коннекты являются удачными. Следовательно необходимо заботится о том, чтобы какимнить обрабом проверять естьли коннект реально или нет!
Ну и извращение! Си позволяет возвращать не только простые, но и сложные типы данных, например структуры, только зачем это нужно, мне например вообще почти никогда не бывает нужно. В С++ - да. При перегрузке операций для классов там без этого не обойтись, а в си... __asm{mov b,edx} вот это вообще издевателсьво. Остерегайтесь ассемблерных вставок в windows программах пользователського режима - они там ненужны, кроме того такой С-код непереносим. В gcc специально сделали синтаксис АТ&Т, чтобы неповадно было ассемблер использовать
С такой проблемой не сталкивался, но выход напрашивается, если ты используешь sockets api, проверяй после установки соединения, с кем реально ты соединился (если не sockets api, то наверняка тоже можно)
2 DWORD В том то и дело, что по всем параметрам соединение идет какбы нормальное. потмоу что всё подменяется довольно четко. А писать громозкий код для определения сетевой активности своей проги - тоже както не хочется. Если сам разрабатываешь и серверную и клиентскую часть, то выход прост. А если к примеру делается клиент к уже существующему серверу и идет жесткая организация пакетов типа по RFC то тогда возникает проблема. К примеру у меня тесты показали, что даже даже первые данных посланные через send удачно посылаются, даже если сервер недоступен. Просто данные шлются касперу, а от него теряются. Хотя повторная отправка пакета - уже выдает ошибку отправки, при отключеном сервере.
2slesh очень странно, в принципе, чисто теоретически, подобный перехват со стороны касперского должен официально подделывать возвращаемые ip-пакеты (адрес отправителя) иначе бы возникли проблемы с работой многих сетевых приложений. насчет connect'а: я так понимаю, что касперский должен выполнять функцию шлюза локальной сети, однако если тут этого не происходит, то видимо он вообще работает с пакетами на высоком уровне)) если так, то лучше избавиться от подобного ПО при определенных навыках можешь поработать с сырыми пакетами и посмотреть кто-что посылает. по-хорошему касперский должен быть ТОЧНО ip-прокси.
Касперский не перестаёт нас удивлять. А что же дальше? Инжект во все процессы, с целью посмотреть, что они будут делать? Заражение .ехе файлов на диске с целью закрепить свою защиту в системе?
Бред. Что куда неперносимо? В пределах разных Windows? С какой радости. Между платформами? Дык виндоус-код и так непереносим в этом смысле.. Так что уточни, что ты имел в виду.
>>Бред. Что куда неперносимо? >>программах пользователського режима - они там ненужны, кроме того такой С-код непереносим с опущенным словом windows очень даже правильно про пользовательский режим - ну в общем-то правда, хотя наверняка найдутся примеры чья оптимизированная реализации на ассемблере будет нужна по части глупости компилятора. а C-код и правда не переносим будет, ведь асм-вставки это не стандарт языка.