Reverse Code Engineering

逆向工程代码 обратная код машиностроения

Reverse Code Engineering

逆向工程代码 обратная код машиностроения

Reverse Code Engineering

Share what I know............... learn what I don’t

آخرین نظرات

اتوماتیک کردن مهندسی معکوس از طریق اسکریپت

چهارشنبه, ۳۱ شهریور ۱۳۹۵، ۱۰:۲۹ ق.ظ

مهندسی معکوس یک کار ماهرانه هستش مخصوصا زمانی که ما میخواهیم یک برنامه بزرگ یا فایل های پک شده مثل Malware ها رو آنالیز کنیم.
برخی ازین کارهای رایج شامل:
* پیگیری تخصیصات حافظه
* پیگیری فراخوانی API های خاص
* انپک کردن خانواده ای از Malware ها
* تصمیم گیری هوشمندانه مبتنی بر رویدادهای خاص

البته ما در اینجا مثالهای ساده ای رو بازگو میکنیم تا شما رو با این روش آنالیز آشنا کنیم, ما میخواهیم فراخوانی های HeapAlloc رو در یک برنامه مانیتور کنیم ,نه همه اونها,تنها مقادیری خاص,مثل درخواست تخصیص های بزرگتر از 1024 بایت.
یک اسکریپت ساده همه این اطلاعات رو به ما میدهد بجای ایجاد نقاط توقف به صورت دستی روی تابع HeapAlloc و سپس بررسی سایزهای تخصیص یافته ...

Ollydbg - Playing with OllyScript

همانطور که میدونید Olly یکی از بهترین دیباگر های سطح کاربر هستش که یک رابط بسیار عالی داره و به طور رایج ازین دیباگر استفاده میشه.
اما این دیباگر از اسکریپت پشتیبانی نمیکنه و این کارو از طریق پلاگین ها انجام میده.در اینجا هم ما از پلاگین OllyScript که توسط ShaG نوشته شده استفاده میکنیم.
این پلاگین syntax شبیه به اسمبلی داره که البته ما در اینجا قصد آموزش اسکریپت نویسی رو نداریم و انشالله در مقاله ای جدا به آن می پردازیم.


طرح مشکل:
ما میخواهیم یک برنامه رو برای یک باگ ساده بررسی کنیم و میخوایم بدونیم که کدام تابع باعث این مشکل میشه.اما تابع در اعماق برنامه قرار داره و بصورت دستی ساعت ها وقت می بره.بنابراین در اینجا ما مسیر جریان اجرا رو تریس می کنیم و میخوایم تا لاگ کنیم آدرس برگشت هر تابع رو.

راه حل:
مشکل بالا را به چند روش می توان حل کرد. اما نمایش آن به صورت ساده,استفاده از روند زیر هستش:

    1- From current EIP, search for calls and create breakpoint on that call
    2- Step into the call
    3- Log the value at ESP (i.e return address) and search for calls at return address and
    4- Breakpoint on the call
    5- Repeat step 1, 2, 3 inside the call
    6- Run


اسکریپت زیر این کارو انجام می دهد. فقط توجه کنید این اسکریپت فقط برای نمایش مفهوم هستش.


EOB breakprocess
var return
var infunction
var x
var y
mov infunction,EIP
mov return,EIP

start:
findop return,#E8#
mov x,$RESULT
findop infunction,#E8#
mov y,$RESULT
cmp x,0
ja breaksetx
backx:
cmp y,0
ja breaksety
backy:
run

breakprocess:
sti
mov return,[esp]
msg return
sti
mov infunction,EIP
jmp start

breaksetx:
bp x
jmp backx

breaksety:
bp y
jmp backy
برای اطلاعات بیشتر می تونید به رفرنس OllyScript مراجعه کنید.
 اسکریپت با EOB (اجرا پس از BP) شروع شده, همانطور که مشخصه هر زمان که BP رخ بده برچسب مقابل EOP اجرا خواهد شد(breakprocess)

var - declares a variable.
mov - is similar to assembly
findop - search for opcode from the specified address & stores the results into a $RESULT variable
run - is similar to F9 in ollydbg
sti - step into - similar to F7 in ollydbg
msg - will show a messagebox - (log should be used but I used msg just for visual pleasure :))
همانطور که می بینید اسکریپت شبیه به اسمبلی است. بیشتر از ollyscript برای آنپک کردن بد افزارها استفاده می کنند.اما در کل قابل انعطاف پذیری زیادی نداره و تنها میشه ازش برای اتوماتیک سازی برخی کارها در olly استفاده کرد.

Immunity Debugger

این دیباگر  واسط کاربری مشابهی با olly داره و توسط شرکت immunity inc توسعه داده میشه.هدف کلی تولید این دیباگر جستجوی آسیب پذیری هاس. یکی از مزایای این دیباگر داشتن API هایی برای کارهای گوناگون مهندسی معکوس و پشتیانی از پایتون هستش که این دیباگر رو نسبت به دیگر دیباگر ها متمایز می کنه.

طرح مشکل:
ما می خوایم تا تمام آدرسهای دستور jmp esp رو جستجو کنیم:

حل مشکل:
از اسکریپت زیر میتونیم در python shell این دیباگر استفاده کنیم:

data = "jmp esp"
asm = imm.assemble(data) # imm is object of immlib class
results = imm.search(asm)

for addr in results:
print "%s %0.8x" % (data,addr)
توی 5 خط میشه کل آدرس های jmp esp رو بدست آورد:)

Pydbg

این ابزار یک دیباگر مبتنی بر پایتون هستش که دارای انعطاف پذیری خوبی است.

طرح مشکل:
ما میخوایم تابع VirtuallAlloc زمانی که فراخوانی میشه مسیریابی کنیم,
 اسکریپت ما میبایست آرگومانها و اشاره گر برگشتی توسط تابع را به ما برگرداند.

VirtualAlloc:

LPVOID WINAPI VirtualAlloc(
__in_opt LPVOID lpAddress,
__in SIZE_T dwSize,
__in DWORD flAllocationType,
__in DWORD flProtect
);

حل مشکل:
1- قرار داد PB روی این تابع
2. خارج کردن آرگومانها از پشته
3- خارج کردن آدرس برگشت از پشته و قرار دادن BP روی آن
4- بدست آوردن مقدار رجیستر EAX

import sys
import pefile
import struct
from pydbg import *
from pydbg.defines import *


def ret_addr_handler(dbg):

lpAddress = dbg.context.Eax # Get value returned by VirtualAlloc
print " Returned Pointer: ",hex(int(lpAddress))

return DBG_CONTINUE

def virtual_handler(dbg):

print "****************"
pdwSize = dbg.context.Esp + 8 # 2nd argument to VirtualAlloc
rdwSize = dbg.read_process_memory(pdwSize,4)
dwSize = struct.unpack("L",rdwSize)[0]
dwSize = int(dwSize)
print "Allocation Size: ",hex(dwSize)

pflAllocationType = dbg.context.Esp + 12 # 3rd argument to VirtualAlloc
rflAllocationType = dbg.read_process_memory(pflAllocationType,4)
flAllocationType = struct.unpack("L",rflAllocationType)[0]
flAllocationType = int(flAllocationType)
print "Allocation Type: ",hex(flAllocationType)

pflProtect = dbg.context.Esp + 16 # 4th Argument to VirtualAlloc
rflProtect = dbg.read_process_memory(pflProtect,4)
flProtect = struct.unpack("L",rflProtect)[0]
flProtect = int(flProtect)
print "Protection Type: ",hex(flProtect)

pret_addr = dbg.context.Esp # Get return Address
rret_addr = dbg.read_process_memory(pret_addr,4)
ret_addr = struct.unpack("L",rret_addr)[0]
ret_addr = int(ret_addr)
dbg.bp_set(ret_addr,description="ret_addr breakpoint",restore = True,handler = ret_addr_handler)

return DBG_CONTINUE

def entry_handler(dbg):

virtual_addr = dbg.func_resolve("kernel32.dll","VirtualAlloc") # Get VirtualAlloc address
if virtual_addr:
dbg.bp_set(virtual_addr,description="Virtualalloc breakpoint",restore = True,handler = virtual_handler)

return DBG_CONTINUE

def main():

file = sys.argv[1]
pe = pefile.PE(file)
# get entry point
entry_addr = pe.OPTIONAL_HEADER.AddressOfEntryPoint + pe.OPTIONAL_HEADER.ImageBase
dbg = pydbg() # get pydbg object
dbg.load(file)
dbg.bp_set(entry_addr,description="Entry point breakpoint",restore = True,handler = entry_handler)
dbg.run()

if __name__ == '__main__':
main()

Windbg

این دیباگر رسمی مایکروسافت هستش که قدرت زیادی روی ویندوز داره مخصوصا در هنگام دیباگ کردن کرنل .
این دیباگر نیز زبان اسکریپت نویسی مخصوص خودش رو داره که شبیه زبان سی هستش, اطلاعات بیشتر رو در این مورد می تونید از فایل راهنمای خود دیباگر بدست بیارید.

طرح مشکل:
ما malloc رو می خوایم مسیریابی کنیم, زمانی که فراخوانی می شه, اسکریپت ما باید سایز درخواستی برای تخصیص و همچنین اشاره گر برگشتی را به ما برگرداند.

حل:
1 - قرار دادن BP روی malloc
2- خارج کردن پارامترها از پشته
3- خارج کردن آدرس برگشت از پشته و قرار دادن PB روی آن
4- بدست اوردن مقدار رجیستر EAX

bp msvcrt!malloc ".printf \"Size: %x\n\",poi(esp+4);gu;.printf \"Returned Pointer: %x\n\",eax;g"

زمان استفاده از چندین دستور در یک خط باید این دستورات را با (;) از هم جداکنیم.

bp - sets breakpoint
msvcrt!malloc - this is DLL!Method (here DLL name & function name are separated by ! )

این بعنوان BP های شرطی شناخته می شوند.

bp address or dll!method or dll!method+offset "block that should be executed when breakpoint hits"

poi - is similar to pointer in c
gu - go up - execute until return
g - go or execute

منبع
http://www.securityxploded.com

نظرات (۰)

هیچ نظری هنوز ثبت نشده است
ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی