Что нового

Перевод машинного кода

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
В Википедии нашёл пример программы "Hello Word!" там же и машинный код этой программы, как перевести из машинного кода обратно?

Машинный код:
Код:
BB 11 01 B9 0D 00 B4 0E 8A 07 43 CD 10 E2 F9 CD 20 48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21
Программа на ассамблере:
Код:
    org     100h            ; com программа DOS размещается по смещению 0x100 байт от начала сегмента памяти.
    mov     bx, 111h        ; положить в bx смещение строки HW
    mov     cx, 0Dh         ; положить в cx длину строки HW
    mov     ah, 0Eh         ; положить в ah номер функции прерывания 10h
label:
    mov     al, [bx]        ; помещаем байт в памяти по адресу хранящемуся в bx в al
    inc     bx              ; увеличиваем значение смещения символа, который требуется напечатать
    int     10h             ; вызов прерывания 10h
    loop    label           ; если cx≠0, то перейти к метке label и уменьшит cx на 1.
    int     20h             ; выйти в DOS
HW  db 'Hello, World!'      ; сама строка, которую требуется напечатать, её смещение 111h 
                            ; относительно начала сегмента памяти (11h относительно начала программы)
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
Viktor1703 [?]
перевести из машинного кода обратно?
обратно куда?
и вообще, Виктор, ты вроде давно на форуме, что за вакханалия с разделом? это же явно тема для общения
 
Автор
Viktor1703

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
Извиняюсь, действительно что-то я ...... обратно в смысле в исходный код, наверное это не возможно, но не узнаешь пока не спросишь, а в yandexe показывают пример как наобород перевести текст в машинный код, но там так расталкованно что не спервого раза поймёшь
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
Viktor1703
исходные коды, как-бы так помягче выразиться, бывают на бесчисленном кол-ве ЯП. именно в исходный код на котором было написано приложение конечно же уже не перевести. но этого никто и не делает. делают обычно то, что ты привел в своем посте - приводят код ассемблера. это называется обратным инжинирингом (reverse engineering) или дизассемблированием. тот, кто разбирается в языке ассемблера, может запросто диззассемблировать приложение, добавить нужный ему функционал и скомпилировать снова. и от такого не застраховано ни одно приложение. это к слову о всякого рода защитах.
 
Автор
Viktor1703

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
Понятно, просто если бы не так затруднительно было бы это делать, то данные которые записываем в своё приложение, можно бы было хранить в самом exe в какой нибудь переменной, хотя скорее всего ошибаюсь, так как приложение летит от вмешательства в его код, но было бы интересно, уже много способов хранения данных в exe перепробовал, но они ни есть айс.
 

Garrett

Модератор
Локальный модератор
Сообщения
3 999
Репутация
964
Viktor1703 [?]
как перевести из машинного кода обратно?
Для вашего примера вам просто необходимо загрузить вашу программу в любой дизассемблер или HEX редактор с поддержкой дизассемблирования, и дальше можете "химичить" (если знаете ассемблер) :smile:

[?]
то данные которые записываем в своё приложение, можно бы было хранить в самом exe
В любом EXE, в конце файла, есть область нулевых байт, там вы можете без проблем хранить свои данные, однако чтобы записать их туда вам нужно будет выйти из программы.
 
Автор
Viktor1703

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
В любом EXE, в конце файла, есть область нулевых байт, там вы можете без проблем хранить свои данные, однако чтобы записать их туда вам нужно будет выйти из программы.
Да, это само собой, но эти данные показать в окне своей программы возможность есть?
 

Garrett

Модератор
Локальный модератор
Сообщения
3 999
Репутация
964
Viktor1703, полагаю есть, я просто не задавался такой целью.
Нужно поэкспериментировать.
 
Автор
Viktor1703

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
Попробую тоже по эксперементировать
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
Garrett [?]
Нужно поэкспериментировать.
Целый день экспериментировал. :smile:
Взял за образец этот пример Yashied`a, вроде работает.
1. Компилируем этот скрипт с именем Write_To_Exe.au3.
Код:
#NoTrayIcon

Opt('MustDeclareVars', 1)

Global $iPID, $sFileName, $sText, $iFlag

If $CmdLine[0] <> 4 Then Exit

$iPID = Number($CmdLine[1])
$sFileName = $CmdLine[2]
$sText = $CmdLine[3]
$iFlag = Number($CmdLine[4])

_Write_To_Exe($iPID, $sFileName, $sText, $iFlag)
If @error Then
	MsgBox(16, 'Error', '_Write_To_Exe')
	Exit
EndIf
Run($sFileName)
_ScriptDestroy()

Func _Write_To_Exe($i_PID, $s_FilePath, $s_Text, $i_Flag)
	Local $h_File, $i_Len, $i_Max_Len = 255, $t_Text, $p_Text, $i_Byte, $t_Sign, $p_Sign, _
			$i_Error = 1

	If ProcessExists($i_PID) Then
		ProcessClose($i_PID)
		If Not ProcessWaitClose($i_PID, 2) Then Return SetError($i_Error)
	EndIf
	If $i_Flag Then $s_Text = ''
	$i_Len = StringLen($s_Text)
	If $i_Len > $i_Max_Len Then
		$s_Text = StringLeft($s_Text, $i_Max_Len)
	EndIf
	For $i = $i_Len To $i_Max_Len
		$s_Text &= Chr(0)
	Next
	$t_Text = DllStructCreate('byte[' & $i_Max_Len + 1 & ']')
	DllStructSetData($t_Text, 1, $s_Text)
	$h_File = _WinAPI_CreateFile($s_FilePath, 2, 6)
	If Not $h_File Then
		Return SetError($i_Error)
	EndIf
	If $i_Flag Then
		$t_Sign = DllStructCreate('dword')
		DllStructSetData($t_Sign, 1, 0x0144ADDA)
		For $i = 1 To 1
			If Not _WinAPI_SetFilePointer($h_File, 0, 2) Then ExitLoop
			$p_Sign = DllStructGetPtr($t_Sign)
			If Not _WinAPI_WriteFile($h_File, $p_Sign, 4, $i_Byte) Or $i_Byte <> 4 Then ExitLoop
			$p_Text = DllStructGetPtr($t_Text)
			If Not _WinAPI_WriteFile($h_File, $p_Text, ($i_Max_Len + 1), $i_Byte) Or $i_Byte <> ($i_Max_Len + 1) Then ExitLoop
			$i_Error = 0
		Next
	Else
		For $i = 1 To 1
			If Not _WinAPI_SetFilePointer($h_File, -1 * ($i_Max_Len + 1), 2) Then ExitLoop
			$p_Text = DllStructGetPtr($t_Text)
			If Not _WinAPI_WriteFile($h_File, $p_Text, ($i_Max_Len + 1), $i_Byte) Or $i_Byte <> ($i_Max_Len + 1) Then ExitLoop
			$i_Error = 0
		Next
	EndIf
	_WinAPI_CloseHandle($h_File)
	Return SetError($i_Error)
EndFunc   ;==>_Write_To_Exe

Func _ScriptDestroy()
	Local $s_Temp, $s_Path, $h_File_Temp
	$s_Temp = @ScriptDir & '\~RANDOM.bat'
	$s_Path = FileGetShortName(@ScriptFullPath)
	$h_File_Temp = FileOpen($s_Temp, 2)
	FileWriteLine($h_File_Temp, '@echo off')
	FileWriteLine($h_File_Temp, ':loop')
	FileWriteLine($h_File_Temp, 'del ' & $s_Path)
	FileWriteLine($h_File_Temp, 'if exist ' & $s_Path & ' goto loop')
	FileWriteLine($h_File_Temp, 'del %0')
	FileClose($h_File_Temp)
	Run($s_Temp, '', @SW_HIDE)
EndFunc   ;==>_ScriptDestroy

#region From WinAPI.au3
Func _WinAPI_CloseHandle($hObject)
	Local $aResult = DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hObject)
	If @error Then Return SetError(@error, @extended, False)
	Return $aResult[0]
EndFunc   ;==>_WinAPI_CloseHandle

Func _WinAPI_WriteFile($hFile, $pBuffer, $iToWrite, ByRef $iWritten, $pOverlapped = 0)
	Local $aResult = DllCall("kernel32.dll", "bool", "WriteFile", "handle", $hFile, "ptr", $pBuffer, "dword", $iToWrite, "dword*", 0, "ptr", $pOverlapped)
	If @error Then Return SetError(@error, @extended, False)
	$iWritten = $aResult[4]
	Return $aResult[0]
EndFunc   ;==>_WinAPI_WriteFile

Func _WinAPI_ReadFile($hFile, $pBuffer, $iToRead, ByRef $iRead, $pOverlapped = 0)
	Local $aResult = DllCall("kernel32.dll", "bool", "ReadFile", "handle", $hFile, "ptr", $pBuffer, "dword", $iToRead, "dword*", 0, "ptr", $pOverlapped)
	If @error Then Return SetError(@error, @extended, False)
	$iRead = $aResult[4]
	Return $aResult[0]
EndFunc   ;==>_WinAPI_ReadFile

Func _WinAPI_CreateFile($sFileName, $iCreation, $iAccess = 4, $iShare = 0, $iAttributes = 0, $pSecurity = 0)
	Local $iDA = 0, $iSM = 0, $iCD = 0, $iFA = 0

	If BitAND($iAccess, 1) <> 0 Then $iDA = BitOR($iDA, 0x20000000);$GENERIC_EXECUTE)
	If BitAND($iAccess, 2) <> 0 Then $iDA = BitOR($iDA, 0x80000000);$GENERIC_READ)
	If BitAND($iAccess, 4) <> 0 Then $iDA = BitOR($iDA, 0x40000000);$GENERIC_WRITE)

	If BitAND($iShare, 1) <> 0 Then $iSM = BitOR($iSM, 0x00000004);$FILE_SHARE_DELETE)
	If BitAND($iShare, 2) <> 0 Then $iSM = BitOR($iSM, 0x00000001);$FILE_SHARE_READ)
	If BitAND($iShare, 4) <> 0 Then $iSM = BitOR($iSM, 0x00000002);$FILE_SHARE_WRITE)

	Switch $iCreation
		Case 0
			$iCD = 1;$CREATE_NEW
		Case 1
			$iCD = 2;$CREATE_ALWAYS
		Case 2
			$iCD = 3;$OPEN_EXISTING
		Case 3
			$iCD = 4;$OPEN_ALWAYS
		Case 4
			$iCD = 5;$TRUNCATE_EXISTING
	EndSwitch

	If BitAND($iAttributes, 1) <> 0 Then $iFA = BitOR($iFA, 0x00000020);$FILE_ATTRIBUTE_ARCHIVE)
	If BitAND($iAttributes, 2) <> 0 Then $iFA = BitOR($iFA, 0x00000002);$FILE_ATTRIBUTE_HIDDEN)
	If BitAND($iAttributes, 4) <> 0 Then $iFA = BitOR($iFA, 0x00000001);$FILE_ATTRIBUTE_READONLY)
	If BitAND($iAttributes, 8) <> 0 Then $iFA = BitOR($iFA, 0x00000004);$FILE_ATTRIBUTE_SYSTEM)

	Local $aResult = DllCall("kernel32.dll", "handle", "CreateFileW", "wstr", $sFileName, "dword", $iDA, "dword", $iSM, "ptr", $pSecurity, "dword", $iCD, "dword", $iFA, "ptr", 0)
	If @error Or $aResult[0] = Ptr(-1) Then Return SetError(@error, @extended, 0) ; INVALID_HANDLE_VALUE
	Return $aResult[0]
EndFunc   ;==>_WinAPI_CreateFile

Func _WinAPI_SetFilePointer($hFile, $iPos, $iMethod = 0)
	Local $aResult = DllCall("kernel32.dll", "INT", "SetFilePointer", "handle", $hFile, "long", $iPos, "ptr", 0, "long", $iMethod)
	If @error Then Return SetError(@error, @extended, -1)
	Return $aResult[0]
EndFunc   ;==>_WinAPI_SetFilePointer
#endregion From WinAPI.au3

2. Кладем полученный Write_To_Exe.exe в одну папку со следующем скриптом и компилируем его:
Код:
#include <WinAPI.au3>
#include <File.au3>

Opt('MustDeclareVars', 1)
Opt('TrayMenuMode', 1)

Global $fCheck, $sText

If @Compiled Then
	$fCheck = _Check_ScriptFullPath()
	If @error Then
		MsgBox(16, 'Error', '_Check_ScriptFullPath')
		Exit
	EndIf
	If Not $fCheck Then
		_Write_ScriptFullPath(@AutoItPID, @ScriptFullPath, 'First', 1)
		If @error Then
			MsgBox(16, 'Error', '_Write_ScriptFullPath')
			Exit
		EndIf
	EndIf
Else
	Exit
EndIf

$sText = _Read_ScriptFullPath()
If $sText Then
	MsgBox(64, 'Info', 'Прочитали из себя:' & @LF & $sText)
EndIf
If MsgBox(68, 'Info', 'Пишем в себя?') = 7 Then Exit

$sText = InputBox('Пишем в себя', 'Введите фразу не длиннее 255 символов', 'Test string')
If Not @error And $sText Then
	_Write_ScriptFullPath(@AutoItPID, @ScriptFullPath, $sText, 0)
	If @error Then
		MsgBox(16, 'Error', '_Write_ScriptFullPath')
		Exit
	EndIf
EndIf

Func _Write_ScriptFullPath($i_PID, $s_FilePath, $s_Text, $i_Flag)
	Local $s_TempFile, $s_Read, $h_File

	$s_TempFile = _TempFile(@TempDir, '~', '.exe')
	If Not FileInstall('Write_To_Exe.exe', $s_TempFile) Then Return SetError(1)
	If StringInStr($s_TempFile, ' ') Then $s_TempFile = '"' & $s_TempFile & '"'
	If StringInStr($s_FilePath, ' ') Then $s_FilePath = '"' & $s_FilePath & '"'
	If StringInStr($s_Text, ' ') Then $s_Text = '"' & $s_Text & '"'
	Run($s_TempFile & ' ' & $i_PID & ' ' & $s_FilePath & ' ' & $s_Text & ' ' & $i_Flag)
	Exit
EndFunc   ;==>_Write_ScriptFullPath

Func _Read_ScriptFullPath()
	Local $h_File, $t_Data, $p_Data, $s_Data, $i_Byte, $s_Result

	$h_File = _WinAPI_CreateFile(@ScriptFullPath, 2, 2)
	If Not $h_File Then
		Return $s_Result
	EndIf
	$t_Data = DllStructCreate('byte[256]')
	$p_Data = DllStructGetPtr($t_Data)
	For $i = 1 To 1
		If Not _WinAPI_SetFilePointer($h_File, -256, 2) Then ExitLoop
		If Not _WinAPI_ReadFile($h_File, $p_Data, 256, $i_Byte) Or $i_Byte <> 256 Then ExitLoop
		$s_Data = BinaryToString(DllStructGetData($t_Data, 1))
		If Not $s_Data Then ExitLoop
		$s_Result = StringReplace($s_Data, Chr(0), '')
	Next
	_WinAPI_CloseHandle($h_File)
	Return $s_Result
EndFunc   ;==>_Read_ScriptFullPath

Func _Check_ScriptFullPath()
	Local $h_File, $t_Check, $p_Check, $s_Check, $i_Byte, $i_Error = 1, $f_Check = False

	$h_File = _WinAPI_CreateFile(@ScriptFullPath, 2, 2)
	If Not $h_File Then
		Return SetError($i_Error)
	EndIf
	$t_Check = DllStructCreate('byte[1]')
	$p_Check = DllStructGetPtr($t_Check)
	For $i = 1 To 1
		If Not _WinAPI_SetFilePointer($h_File, -1, 2) Then ExitLoop
		If Not _WinAPI_ReadFile($h_File, $p_Check, 1, $i_Byte) Or $i_Byte <> 1 Then ExitLoop
		$s_Check = BinaryToString(DllStructGetData($t_Check, 1))
		If Not $s_Check Then ExitLoop
		If $s_Check == Chr(0) Then $f_Check = True
		$i_Error = 0
	Next
	_WinAPI_CloseHandle($h_File)
	Return SetError($i_Error, 0, $f_Check)
EndFunc   ;==>_Check_ScriptFullPath

При запуске (у меня работает) можно записать - прочитать произвольную фразу длиной до 255 символов.
 
Автор
Viktor1703

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
Браво madmasles, спасибо за пример, сколько я ни пробывал у меня всё вылетало +1
 
Верх