Add files via upload

This commit is contained in:
vxunderground
2020-10-09 21:50:53 -05:00
committed by GitHub
parent 3b1112577c
commit 930c435323
36 changed files with 16849 additions and 0 deletions
+510
View File
@@ -0,0 +1,510 @@
;::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Simple Morpher v.0.1 :
; :
; x0man © 2008 :
; :
; http://www.virustech.org/ :
;::::::::::::::::::::::::::::::::::::::::::::::::::::::
;-----------------------------------------------------------------------------------------:
; :
;В Кратце расскажу алгоритм, который у меня реализован. :
; :
;Есть массив в который заносятся данные о инструкциях :
;Одним эллементом массива является: :
; :
;_OPCODE struct; :
; dwOldAddress dd ? ; Старый адрес инструкции (до морфинга) :
; dwNewAddress dd ? ; Новый адрес инструкции (после морфинга) :
; dwJumpAddress dd ? ; Адрес куда должен указывать прыжок(или вызов) :
; ; (если инструкция им является) :
; dwLength dd ? ; в данном примере эта переменная не используется :
; ; Надеюсь вам она пригодиться больше чем мне :) :
;_OPCODE ends :
; :
;В "мой" Первый этап входит :
; 1. Парсинг кода, и выделение на каждую инструкцию одного :
; эллемента массива, заполняя данные в структуре _OPCODE. :
; 2. Расширение кода для будущих изменений (замена коротких прыжков на длинные) :
; 3. Если инструкция является прыжком или вызовом, нам нужно :
; подсчитать скажем так EIP при выполнении оной. :
; 4. И есстественно разбавление кода (инструкцией NOP) :
; :
;Второй этап :
; 1. Проходимся по массиву с описаниями инструкций :
; 2. Если инструкция является вызовом, то вычисляем параметр у прыжка :
; или вызова, и меняем его на корректный(уже в изменённом коде). :
; :
; :
;Вроде бы всё... для более точных описаний смотрим код! :
; :
;Дизассемблер длинн инструкций я взял Catchy_32, который можно скачать с :
; http://www.wasm.ru, он также прилагается к исходникам в приложении. :
; :
;GreeTz: :
; Osen :
; izee [ EOF-Project ] http://eof-project.net/ :
; :
; tPORt (http://www.tport.org/) :
; REVENGE(http://www.revenge-crew.com/) :
; TLG (http://tlg.astalavista.ms/) :
; TSRh (http://tsrh.org.ua/) :
; TPOC (http://vx.netlux.org/tpoc/) :
; :
; :
; Спасибо за внимание! :
; :
; 10.05.2008 :
; x0man [VirusTech] :
; http://www.virustech.org :
;-----------------------------------------------------------------------------------------:
.386
.model flat, stdcall
option casemap :none
include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\kernel32.inc
include \MASM32\INCLUDE\user32.inc
includelib \MASM32\LIB\kernel32.lib
includelib \MASM32\LIB\user32.lib
; #########################################################################
_OPCODE struct
dwOldAddress dd ? ; Старый адрес инструкции (до морфинга)
dwNewAddress dd ? ; Новый адрес инструкции (после морфинга)
dwJumpAddress dd ? ; Адрес куда должен указывать прыжок(или вызов)
; (если инструкция им является)
dwLength dd ? ; в данном примере эта переменная не используется
; Надеюсь вам она пригодиться больше чем мне :)
_OPCODE ends
; #########################################################################
.code
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Код для теста :)
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
test_code:
@@:
jmp @F
mov eax, edx
pop eax
push eax
call @F
cmp eax, 0
jne @B
jmp @B
add ecx, edx
add eax, edx
xchg edx, ecx
call @B
jne @F
db 0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0
jne @B
ret
@@:
ret
int 3
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;::::::::::::::::::::::::::::::::::
; Подключим дизасм длинн инструкций
include Catchy32\Catchy32.inc
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
; Функция для подсчёта числа, куда должен указывать прыжок|
; Пример: dwCurrentAddress - указывает на код |
; |
; 00000000: 74 30 JE imm8 |
; эта функция высчитывает "imm8" |
; в нашем примере imm8 = 00000000 + 30 + 2 = 00000032 |
; т.е. |
; 00000000 - Текущий адрес |
; 30 - Параметр |
; 2 - Длинна инструкции JE imm8 |
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
; 00000000: 74 30 JE 00000032 --. |
; 00000002: | |
; | |
; 00000032: <-----° |
; Это описание для "положительных" прыжков |
; Для отрицательных, попробуйте разобрать сами |
; там не сложно ;-) |
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::|:::|
; IN dwCurrentAddress : текущий адрес предпологаемого прыжка |
; OUT EAX : Адрес куда прыжок указывает |
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
get_jump_address proc dwCurrentAddress : DWORD
push ecx
push edi
mov edi, dwCurrentAddress
mov al, byte ptr [edi]
;:::::::::::::::::::::::::::::::::::::
; XX imm8
cmp al, 070h
jl @F
cmp al, 07Fh
jna @_jump_imm8_
@@:
;:::::::::::::::::::::::::::::::::::::
cmp al, 0EBh
je @_jump_uncond_imm8_
;:::::::::::::::::::::::::::::::::::::
; 0F XX imm32
cmp al, 00Fh
jne @F
mov ah, byte ptr [edi + 1]
cmp ah, 080h
jl @F
cmp ah, 08Fh
jna @_jump_imm32_
;:::::::::::::::::::::::::::::::::::::
@@:
;:::::::::::::::::::::::::::::::::::::
; JMP imm32
cmp al, 0E9h
je @_jump_uncond_imm32_
;:::::::::::::::::::::::::::::::::::::
; CALL
cmp al, 0E8h
je @_call_imm32_
;:::::::::::::::::::::::::::::::::::::
jmp @_exit_
;:::::::::::::::::::::::::::::::::::::
@_jump_imm8_:
@_jump_uncond_imm8_:
;:::::::::::::::::::::::::::::::::::::
; Короткие прыжки
movzx eax, byte ptr [edi + 1]
mov cl, al
test cl, 10000000b ; isNegative?
jnz @_neg_1
add edi, eax
add edi, 2
xchg eax, edi
jmp @_exit_
@_neg_1:
neg al
sub al, 2
sub edi, eax
xchg eax, edi
jmp @_exit_
@_jump_imm32_:
;:::::::::::::::::::::::::::::::::::::
; Длинные прыжки
mov eax, dword ptr [edi + 2]
mov ecx, eax
shr ecx, 24d
test ecx, 10000000b ; isNegative?
jnz @_neg_2
add eax, edi
add eax, 6
jmp @_exit_
@_neg_2:
neg eax
sub eax, 6
sub edi, eax
xchg eax, edi
jmp @_exit_
;:::::::::::::::::::::::::::::::::::::
@_jump_uncond_imm32_:
@_call_imm32_:
;:::::::::::::::::::::::::::::::::::::
; JMP imm32 & CALL imm32
mov eax, dword ptr [edi + 1]
mov ecx, eax
shr ecx, 24d
test ecx, 10000000b ; isNegative?
jnz @_neg_3
add edi, eax
add edi, 5
xchg eax, edi
jmp @_exit_
@_neg_3:
neg eax
sub eax, 5
sub edi, eax
xchg eax, edi
;///////////////////////////////////////
@_exit_:
pop edi
pop ecx
ret
get_jump_address endp
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
; Функция для поиска в массиве описаний инструкций |
; Нового адреса для прыжка.... |
; |
; IN dwAddress - Адрес прыжка |
; IN pOpcodes - Указатель на массив с описаниями опкодов |
; OUT EAX - Новый адрес прыжка... |
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
get_new_jump_address proc dwAddress:DWORD, pOpcodes : DWORD
push ecx
assume ecx : ptr _OPCODE
mov ecx, pOpcodes
mov eax, dwAddress
@@:
cmp [ecx].dwOldAddress, eax
je @F
add ecx, sizeof _OPCODE
cmp [ecx].dwOldAddress, 0
jne @B
xor eax, eax
@@:
mov eax, [ecx].dwNewAddress
pop ecx
ret
get_new_jump_address endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
; Функция разбавляет определённый код, инструкцией NOP |
; ВАЖНО! Код должен заканчиваться опкодом 0CCh |
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
; IN dwCodeAddress - Адрес кода для морфинга |
; IN dwOutputBuffer - Адрес куда будет занесён проморфленный код |
; OUT EAX - Размер проморфленного кода |
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::|
MorphCode proc dwCodeAddress : DWORD, dwOutputBuffer : DWORD
local pOpcodes : DWORD
local dwTotalCodeSize : DWORD
;::::::::::::::::::::::::::::::::::::::::::::::::::
; pOpcodes - Указатель на описания опкодов ::
; dwOutputBuffer - Проморфленный код ::
;::::::::::::::::::::::::::::::::::::::::::::::::::
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Зарезервируем памяти для массива с описаниям инструкций
invoke VirtualAlloc, NULL, 1024*1024, MEM_COMMIT + MEM_RESERVE, PAGE_READWRITE
mov pOpcodes, eax
;::::::::::::::::::::::::::::::::::::::::::::
; Обнулим переменную в которую будем заносить
; Общий размер кода
push 0
pop dwTotalCodeSize
;:::::::::::::::::::::::::::::::::::::::::
; Без комментариев
assume ecx : ptr _OPCODE
mov esi, dwCodeAddress ; Code Address
mov edi, dwOutputBuffer ; New Code Address
mov ecx, pOpcodes ; array of _OPCODES
;::::::::::::::::::::::::::::::::::::::::
;::::::::::::::::::::::::::::::::::::::::
; Первый этап :::::::::::::::::::::::::::
;::::::::::::::::::::::::::::::::::::::::
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Укажем для первой инструкции её новый адрес что в EDI
mov [ecx].dwNewAddress, edi
;::::::::::::::::::::::::::::::::::::
; Начинаем цикл
; Loop 1
@_loop_1:
;::::::::::::::::::::::::::::::::::::
; Узнаем длинну у инструкции
; IN ESI == Current Code Offset
; OUT EAX == Instruction Length
call c_Catchy
;:::::::::::::::::::::::::::::::::::::
; Занесём данные в массив с описаниями
mov [ecx].dwOldAddress, esi
mov [ecx].dwLength, eax
;::::::::::::::::::::::::::::::::::::
; Короткие условные прыжки меняем на длинные
; Они отличаются от длинных префиксом 00Fh
; в начале и +10h к текущему опкоду прыжка
; Пример:
; Было :00000000: 74 30
; 0F +10 30 00 00 00
; Стало:00000000: 0F 84 30 00 00 00
cmp byte ptr [esi], 070h
jl @F
cmp byte ptr [esi], 07Fh
ja @F
push eax
mov al, 00Fh
stosb
movzx eax, byte ptr [esi]
add eax, 10h
stosd
;:::::::::::::::::::::::::::::::::::::::
; Подсчитаем адрес куда указывает прыжок
push esi
call get_jump_address
;::::::::::::::::::::::::
; Занесём данные в массив
mov [ecx].dwJumpAddress, eax
pop eax
;::::::::::::::::::::::::::::::::::::
; Прибавим к общему размеру кода
; Длинну 00Fh XXh imm32, т.е. число 6
; где XX » [80h..8Fh]
add dwTotalCodeSize, 6
;::::::::::::::::::::::::::::::::::::
; Пропустим перенос маленького прыжка
; Переходим к следующей инструкции
jmp @_next_inst_
@@:
;::::::::::::::::::::::::::::::::::::
; Меняем...
; JMP imm8 -> JMP imm32
; Пример
; Было : 00000000: EB 33
; Стало: 00000000: E9 33 00 00 00
cmp byte ptr [esi], 0EBh
jne @F
push eax
mov al, 0E9h
stosb
xor eax, eax
stosd
;:::::::::::::::::::::::::::::::::::::::
; Подсчитаем адрес куда указывает прыжок
push esi
call get_jump_address
;::::::::::::::::::::::::
; Занесём данные в массив
mov [ecx].dwJumpAddress, eax
pop eax
;:::::::::::::::::::::::::::::::
; Прибавим к общему размеру кода
; Длинну E9 imm32, т.е. число 5
add dwTotalCodeSize, 5
jmp @_next_inst_
;::::::::::::::::::::::::::::::::::::
@@:
;::::::::::::::::::::::::::::::::::::
; Проверим на JMP imm32
cmp byte ptr [esi], 0E9h
jne @F
push eax
push esi
call get_jump_address
mov [ecx].dwJumpAddress, eax
pop eax
jmp @_replace_instr_
;::::::::::::::::::::::::::::::::::::
@@:
;::::::::::::::::::::::::::::::::::::
; Проверим на CALL
cmp byte ptr [esi], 0E8h
jne @F
push eax
push esi
call get_jump_address
mov [ecx].dwJumpAddress, eax
pop eax
jmp @_replace_instr_
;::::::::::::::::::::::::::::::::::::
@@:
;::::::::::::::::::::::::::::::::::::
; 00Fh XX imm32
cmp byte ptr [esi], 00Fh
jne @F
cmp byte ptr [esi + 1], 080h
jl @F
cmp byte ptr [esi + 1], 08Fh
ja @F
push eax
push esi
call get_jump_address
mov [ecx].dwJumpAddress, eax
pop eax
;::::::::::::::::::::::::::::::::::::
@@:
@_replace_instr_:
;::::::::::::::::::::::::::::::::::::::::::
; Переносим инструкцию в новый буффер.
; Этот код выполниться в том случае
; Если мы не меняли оригинальные инструкции
push esi
push ecx
mov ecx, eax
rep movsb
pop ecx
pop e