Показать сообщение отдельно

  #3  
Старый 19.06.2008, 07:29
taha
Постоянный
Регистрация: 20.08.2006
Сообщений: 327
С нами: 10381346

Репутация: 1077
По умолчанию

На счет комментирования каждой строчки не согласен! Буду комментировать только то, что необходимо!

Итак! Наверняка все исследовали CrackME от Great'a, который использует vm. Во время исследования этой вм, мной были написаны следущие скрипты. Скрипты немного кривоваты, но в качестве оправдания скажу, что они были написаны в боевых условиях!

1: Разбор команд VM от Great'a. Данный скрипт разбирает только те команды, которые использует алгоритм защиты CrackME от Great'a.

Код:
 Результат:

| Address  | Message
+----------+------------------------------------------
|          | ...
|          |
|          | -----[ Mnemonics ]-----
|          |
| 004014BB | xor r4, r4
| 004014C5 | mov r5, r0
| 004014CF | add r5, r2
| 004014D9 | mov r3, dword [r0]
| 004014E3 | xor r3, r1
| 004014ED | add r4, r3
| 004014F7 | inc r0
| 00401501 | cmp r0, r5
|          | Execute if less:
| 00401515 | mov [eip], 0x004014d9
| 0040151F | cmp r4, r7
|          | Execute if equal:
| 00401533 | mov r8, 0x87148712
| 0040153D | mov r4, 0x00000000
|          |
|          | ---[ End Mnemonics ]---
Note: Address - это EIP виртуальной машины! Кстати!!! Я разбираю команду за командой и если бы Great применил старенький трюк с прыжком в середину команды или смешивание, то всё накрылось бы пиздой!

Код:
# -*- coding: cp1251 -*- 

# Author: taha
#   Data: 18.o6.2oo8
#   Note: Разбор команд VM от Great'a. Данный скрипт разбирает только те команды, которые
#         использует алгоритм защиты CrackME от Great'a.

# Результат:

#| Address  | Message
#+----------+------------------------------------------
#|          | ...
#|          |
#|          | -----[ Mnemonics ]-----
#|          |
#| 004014BB | xor r4, r4
#| 004014C5 | mov r5, r0
#| 004014CF | add r5, r2
#| 004014D9 | mov r3, dword [r0]
#| 004014E3 | xor r3, r1
#| 004014ED | add r4, r3
#| 004014F7 | inc r0
#| 00401501 | cmp r0, r5
#|          | Execute if less:
#| 00401515 | mov [eip], 0x004014d9
#| 0040151F | cmp r4, r7
#|          | Execute if equal:
#| 00401533 | mov r8, 0x87148712
#| 0040153D | mov r4, 0x00000000
#|          |
#|          | ---[ End Mnemonics ]---

# Note: Address - это EIP виртуальной машины! Кстати!!! Я разбираю команду за командой
#       и  если  бы  Great  применил  старенький трюк с прыжком в середину команды или
#       смешивание, то всё накрылось бы пиздой!

import immlib

imm = immlib.Debugger()

def get_args(ind, reg, arg):
	s = ""
	if reg <= 0x9:
		s = "r"+str(reg)
		if ind == 0x1:						# Индикатор говорит нам, что команда берет DWORD по адресу reg+arg
			s = "dword ["+s
			if arg != 0:					# При arg равном 0'ю вспоминать о нем не обязательно
				s = s + " + 0x%08x" % arg
			s = s+"]"
	elif reg == 0xC:						# reg равное 0xC, говорит о том, что arg не что иное как Immediate
		s = "0x%08x" % arg
	return s

def main(args):
	imm = immlib.Debugger()
	imm.Log("")
	imm.Log(" [ Author: taha", highlight=1)
	imm.Log("     Data: 18.o6.2oo8", highlight=1)
	imm.Log("       Special for Antichat ]", highlight=1)
	imm.Log("")
	imm.Log("-----[ Mnemonics ]-----", highlight=2)
	imm.Log("")
	pCode   = 0x4014BB
	while 1:
		a = (imm.readLong(pCode) & 0xFF)
		opcode = a & 0x3F
		bit8   = a >> 0x7
		bit7   = (a >> 0x6) & 0x1
		a = (imm.readLong(pCode+0x1) & 0xFF)
		FieldB = a & 0x0F
		FieldA = a >> 0x4
		arg1 = imm.readLong(pCode+0x2)
		arg2 = imm.readLong(pCode+0x6)
		tReg2 = get_args(bit7,FieldA,arg2)
		tReg1 = get_args(bit8,FieldB,arg1)
		c_arg = 2
		if opcode == 0x6:
			mnem = "xor "
		elif opcode == 0x3:
			mnem = "mov "
			if FieldB == 0xA:
				tReg1 = "[eip]"
				tReg2 = "0x%08x" % arg2
		elif opcode == 0x4:
			mnem = "add "
		elif opcode == 0xA:
			mnem = "inc "
			c_arg = 1
		elif opcode == 0xF:
			mnem = "cmp "
		elif opcode == 0x14:
			mnem = "Execute if less: "
			c_arg = 0
		elif opcode == 0x10:
			mnem = "Execute if equal: "
			c_arg = 0
		else:
			break
		if c_arg == 0:
			imm.Log(mnem)
		elif c_arg == 1:
			imm.Log(mnem+tReg1, address = pCode)
		elif c_arg == 2:
			imm.Log(mnem+tReg1+", "+tReg2, address = pCode)
		one_arg = 2
		pCode += 0xA
	imm.Log("")
	imm.Log("---[ End Mnemonics ]---", highlight=2)
2: Далее очень полезно было бы просматривать состояние регистров! Например возьмем | 004014ED | add r4, r3 из результата работы предыдущего скрипта! Поставим условную точку останова с условием "[vm_eip] == 004014ED" и исполним мой скрипт!

Код:
# -*- coding: cp1251 -*- 
# Author: taha
#   Data: 18.o6.2oo8
#   Note: Подсматриваем  значения регистров виртуальной машины.
#         Опять же, просматриваются только те регистры, которые
#         задействованы в CrackME от Great'a.

import immlib

imm = immlib.Debugger()

regs = ['r0 ','r1 ','r2 ','r3 ','r4 ','r5 ','r6 ','r7 ','r8 ','r9 ',\
		'eip']

def main(args):
	imm.Log("")
	imm.Log("Dump of registers: ", highlight=2)
	imm.Log("")
	count, addr_vm_regs = 0x0, 0x401400
	for x in regs:
		imm.Log(x+": 0x%08x " % imm.readLong(addr_vm_regs+count*4))
		count += 0x1
	return
 
Ответить с цитированием