Jump to content

Assembly code


Beege
 Share

Recommended Posts

Here's a practice script that Ive been playing with while trying to learn assembly. what it does is start a timer, then does 5 loops that each sleep 500ms and then gets the end time.

I can't figure out how to get the times out of the dllstruct. help would be great. thanks for looking.

#include <Memory.au3>
#Include <Array.au3>

Global $pQueryPerformanceFrequency = _Get_Function_Address('kernel32.dll', 'QueryPerformanceFrequency')
Global $pQueryPerformanceCounter = _Get_Function_Address('kernel32.dll', 'QueryPerformanceCounter')
Global $pSleep = _Get_Function_Address('kernel32.dll', 'Sleep')

Global $d_ST = DllStructCreate("int64")
Global $pStartTime = DllStructGetPtr($d_ST)

Global $d_ET = DllStructCreate("int64")
Global $pEndTime = DllStructGetPtr($d_ET)

Global $d_FT = DllStructCreate("int64")
Global $pFreq = DllStructGetPtr($d_FT)

Global $iMilliseconds = 500, $loops = 5

#Region Assembly
Global $aOpcode[23]
$aOpcode[0] = "0x"
$aOpcode[1] = '';"33DB"

;(2-7) DllCall("kernel32.dll", "int", "QueryPerformanceFrequency", "ptr", $pFreq)
$aOpcode[2] = "B8" & SwapEndian($pFreq);                     move eax, $pFreq
$aOpcode[3] = "50" ;                                        push eax
$aOpcode[4] = "B8" & SwapEndian($pQueryPerformanceFrequency) ;mov eax, $pQueryPerformanceFrequency
$aOpcode[5] = "FFD0" ;                                      call eax

;(6-9) $starttime = _TimerInt() ;  DllCall("kernel32.dll", "int", "$pQueryPerformanceCounter", "ptr", $pStartTime)
$aOpcode[6] = "B8" & SwapEndian($pStartTime);               move eax, $pStartTime
$aOpcode[7] = "50" ;                                        push eax
$aOpcode[8] = "B8" & SwapEndian($pQueryPerformanceCounter) ;mov eax, $pQueryPerformanceCounter
$aOpcode[9] = "FFD0" ;                                      call eax

;(10) $b = 0
$aOpcode[10] = "33DB" ;                                     xor ebx, ebx

;(11-14) Sleep($milliseconds)
$aOpcode[11] = "B8" & SwapEndian($iMilliseconds);           move eax, $milliseconds
$aOpcode[12] = "50" ;                                       push eax
$aOpcode[13] = "B8" & SwapEndian($pSleep) ;                 mov eax, $Sleep
$aOpcode[14] = "FFD0" ;                                     call eax

;(15) $b += 1
$aOpcode[15] = "43" ;                                       inc ebx

;(16-17) If $b <> $loops then jump back to index 11.
$aOpcode[16] = "81FB" & SwapEndian($loops) ;                cmp ebx, loops;
$aOpcode[17] = _jne($aOpcode, 17, 11);  '75' & Hex(-22, 2)  jne from index 17 to 11   (Jump if ebx is not = loops)

;;(18-21) DllCall("kernel32.dll", "int", "QueryPerformanceCounter", "ptr", $pEndTime)
$aOpcode[18] = "B8" & SwapEndian($pEndTime);                move eax, $pEndTime
$aOpcode[19] = "50" ;                                       push eax
$aOpcode[20] = "B8" & SwapEndian($pQueryPerformanceCounter);mov eax, $pQueryPerformanceCounter
$aOpcode[21] = "FFD0" ;                                     call eax

;return
$aOpcode[22] = "C3";                                        ret
#EndRegion


$sOpcode = _ArrayToString($aOpcode, '')
$execute = _Execute_Opcode($sOpcode)

$Freq = DllStructGetData($d_FT, 1)
$StartTime = DllStructGetData($d_ST, 1)
$EndTime = DllStructGetData($d_ET, 1)

$Total_Time = $EndTime - $StartTime
$Total_Time /= $Freq
$Total_Time *= 1000

MsgBox(0, 'Total Time', $Total_Time)

Func _Execute_Opcode($sOpcode)
    Local $CodeBuffer = DllStructCreate("byte[" & BinaryLen($sOpcode) & "]")
    DllStructSetData($CodeBuffer, 1, $sOpcode)
    $Ret = DllCall("user32.dll", "int", "CallWindowProc", "ptr", DllStructGetPtr($CodeBuffer), "int", 0, "int", 0, "int", 0, "int", 0)
    Return $Ret
EndFunc

Func _Get_Function_Address($sDLL, $sFunction)
    Local $Handle, $Address
    $Handle = _WinAPI_GetModuleHandle($sDLL)
    $Address = DllCall($sDLL, "ptr", "GetProcAddress", "ptr", $Handle, "str", $sFunction)
    Return $Address[0]
EndFunc   ;==>_Get_Function_Address

Func _jne($array, $iStart, $iEnd)
    Local $bytes
    $bytes = BinaryLen('0x' & _ArrayToString($array, '', $iEnd, $iStart)) + 2
    Return '75' & Hex(-$bytes, 2)

EndFunc   ;==>_jne

Func SwapEndian($iValue)
    Return Hex(Binary($iValue))
EndFunc   ;==>SwapEndian

edit: Somehow I posted the code twice

Edited by Beege
Link to comment
Share on other sites

Im trying to figure out what windows dll call I would use instead dllstructgetdata() for this part of the code:

$Freq = DllStructGetData($d_FT, 1)
$StartTime = DllStructGetData($d_ST, 1)
$EndTime = DllStructGetData($d_ET, 1)

kinda like how you used RtlMoveMemory function instead of dllstructsetdata() in your assembly examples.

Link to comment
Share on other sites

Exactly. By the way, Thank you especially for all the sweet assembly examples. I would never be where I am as far as assembly knowledge with out yours and monoceres examples.

Edited by Beege
Link to comment
Share on other sites

Exactly. By the way, Thank you especially for all the sweet assembly examples. I would never be where I am as far as assembly knowledge with out yours and monres examples.

monoceres

I did some modifications to your code. Every thing that I changed is between ";XXXXXX" lines. I didn't touch anything else.

There are few issues and all are caused by the fact that it's working with integers (dword).

If you want to process bigger numbers you will have to do additional modifications.

If you want floats you need to switch to them also (check Space.au3 maybe)

#include <Memory.au3>
#include <Array.au3>

;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Global $pRemoteCode = _MemVirtualAlloc(0, 512, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


Global $pQueryPerformanceFrequency = _Get_Function_Address('kernel32.dll', 'QueryPerformanceFrequency')
Global $pQueryPerformanceCounter = _Get_Function_Address('kernel32.dll', 'QueryPerformanceCounter')
Global $pSleep = _Get_Function_Address('kernel32.dll', 'Sleep')

Global $d_ST = DllStructCreate("int64")
Global $pStartTime = DllStructGetPtr($d_ST)

Global $d_ET = DllStructCreate("int64")
Global $pEndTime = DllStructGetPtr($d_ET)

Global $d_FT = DllStructCreate("int64")
Global $pFreq = DllStructGetPtr($d_FT)

;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Global $iMilliseconds = 100, $loops = 5
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

#region Assembly

;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Global $aOpcode[24]
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

$aOpcode[0] = "0x"
$aOpcode[1] = '';"33DB"

;(2-7) DllCall("kernel32.dll", "int", "QueryPerformanceFrequency", "ptr", $pFreq)
$aOpcode[2] = "B8" & SwapEndian($pFreq);                     move eax, $pFreq
$aOpcode[3] = "50" ;                                        push eax
$aOpcode[4] = "B8" & SwapEndian($pQueryPerformanceFrequency) ;mov eax, $pQueryPerformanceFrequency
$aOpcode[5] = "FFD0" ;                                      call eax

;(6-9) $starttime = _TimerInt() ;  DllCall("kernel32.dll", "int", "$pQueryPerformanceCounter", "ptr", $pStartTime)
$aOpcode[6] = "B8" & SwapEndian($pStartTime);               move eax, $pStartTime
$aOpcode[7] = "50" ;                                        push eax
$aOpcode[8] = "B8" & SwapEndian($pQueryPerformanceCounter) ;mov eax, $pQueryPerformanceCounter
$aOpcode[9] = "FFD0" ;                                      call eax

;(10) $b = 0
$aOpcode[10] = "33DB" ;                                     xor ebx, ebx

;(11-14) Sleep($milliseconds)
$aOpcode[11] = "B8" & SwapEndian($iMilliseconds);           move eax, $milliseconds
$aOpcode[12] = "50" ;                                       push eax
$aOpcode[13] = "B8" & SwapEndian($pSleep) ;                 mov eax, $Sleep
$aOpcode[14] = "FFD0" ;                                     call eax

;(15) $b += 1
$aOpcode[15] = "43" ;                                       inc ebx

;(16-17) If $b <> $loops then jump back to index 11.
$aOpcode[16] = "81FB" & SwapEndian($loops) ;                cmp ebx, loops;
$aOpcode[17] = _jne($aOpcode, 17, 11);  '75' & Hex(-22, 2)  jne from index 17 to 11   (Jump if ebx is not = loops)

;;(18-21) DllCall("kernel32.dll", "int", "QueryPerformanceCounter", "ptr", $pEndTime)
$aOpcode[18] = "B8" & SwapEndian($pEndTime);                move eax, $pEndTime
$aOpcode[19] = "50" ;                                       push eax
$aOpcode[20] = "B8" & SwapEndian($pQueryPerformanceCounter);mov eax, $pQueryPerformanceCounter
$aOpcode[21] = "FFD0" ;                                     call eax

;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
$aOpcode[22] = "A1" & SwapEndian($pEndTime) & _    ; mov eax, dword[$pEndTime]
        "2B05" & SwapEndian($pStartTime) & _       ; sub eax, dword[$pStartTime]
        "69C0" & SwapEndian(1000) & _              ; imul eax, 1000
        "99" & _                                   ; cdq
        "8B0D" & SwapEndian($pFreq) & _            ; mov ecx, dword[$pFreq]
        "F7F1"                                     ; div ecx

;return
$aOpcode[23] = "C3";                                        ret
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

#endregion Assembly


$sOpcode = _ArrayToString($aOpcode, '')
$execute = _Execute_Opcode($sOpcode)

;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ConsoleWrite("! " & $execute & @CRLF)
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

;Exit

$Freq = DllStructGetData($d_FT, 1)
$StartTime = DllStructGetData($d_ST, 1)
$EndTime = DllStructGetData($d_ET, 1)

$Total_Time = $EndTime - $StartTime
$Total_Time *= 1000
$Total_Time /= $Freq

;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;MsgBox(0, 'Total Time', $Total_Time)
ConsoleWrite("! " & $Total_Time & @CRLF)
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


Func _Execute_Opcode($sOpcode)
    ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Local $CodeBuffer = DllStructCreate("byte[" & BinaryLen($sOpcode) & "]", $pRemoteCode)
    DllStructSetData($CodeBuffer, 1, $sOpcode)

    $Ret = DllCall("user32.dll", "int", "CallWindowProcW", _
            "ptr", DllStructGetPtr($CodeBuffer), _
            "int", 0, _
            "int", 0, _
            "int", 0, _
            "int", 0)
    Return $Ret[0]
    ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
EndFunc   ;==>_Execute_Opcode

Func _Get_Function_Address($sDLL, $sFunction)
    Local $Handle, $Address
    $Handle = _WinAPI_GetModuleHandle($sDLL)
    $Address = DllCall($sDLL, "ptr", "GetProcAddress", "ptr", $Handle, "str", $sFunction)
    Return $Address[0]
EndFunc   ;==>_Get_Function_Address

Func _jne($array, $iStart, $iEnd)
    Local $bytes
    $bytes = BinaryLen('0x' & _ArrayToString($array, '', $iEnd, $iStart)) + 2
    Return '75' & Hex(-$bytes, 2)

EndFunc   ;==>_jne

Func SwapEndian($iValue)
    ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Return Hex(BinaryMid($iValue, 1, 4))
    ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
EndFunc   ;==>SwapEndian

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...