PE라고 하는 윈도우 하에 실행되는 모든 실행파일의 헤더(프로그램이 실행될때 전체 프로그램 구조의 미니맵과 같은 역할을 하는 것을 PE라고 한다.) 를 읽어들여서 분석하고, 손상된 PE가 발견되었을경우 Rebuild해주는 막강한 기능을 가지고 있다.
성군.story
- LordPE Deluxe 2008.04.26
- UPX SHELL 2008.04.25
- UPX 언패킹 (수작업) 2008.04.25 2
- UPX unpacking 하는방법 두가지 2008.04.25
- vbaStrCmp v2.1슬픔다 2008.04.25
- vbde 라는 프로그램 2008.04.25
- Programming from the Ground Up 2008.04.25
- 어셈 명령어 | 2008.04.24
- 강력한 테스크탑 뮤직 플레이어 송버드(Songbird) 2008.04.24
- 어셈 자료 모두 영문 자료이다.. 2008.04.23
LordPE Deluxe
PE라고 하는 윈도우 하에 실행되는 모든 실행파일의 헤더(프로그램이 실행될때 전체 프로그램 구조의 미니맵과 같은 역할을 하는 것을 PE라고 한다.) 를 읽어들여서 분석하고, 손상된 PE가 발견되었을경우 Rebuild해주는 막강한 기능을 가지고 있다.
UPX SHELL
UPX Shell 은 UPX 의 EXE 파일 버전입니다.
UPX Shell 은 EXE 나 DLL 과 같은 파일의 용량을 최대 90%까지 압축하며, 압축 해제도 가능합니다.
압축시 용량은 팍~ 줄어들고 실행 타임이 약 0.1초 늦어진다는 점을 감안하면 엄청난 압축 능력인거죠~
ㅎㅎ 이제 제 Portable 프로그램들이 완벽을 향해 달립니다~
UPX 언패킹 (수작업)
하지만 우리는 손으로 직접풀기를 원한다.
손으로 직접푸는 압축을 MUC라고 부른다. (Manually UnPack)
OllyDBG로 타깃프로그램을 불러왔다. 경고가 뜬다. 내용을 읽어보니 타깃프로그램이 압축되어서 잘못된 정보가 보여질수 있다 라고 한다. 이런경우 100% 압축이다.
압축이 되어 있을경우 우선 PEID툴로 해당 타깃프로그램을 불러온다. 여기서 PEID 아래쪽 설명을 보면 압축방식이 나오는데 UPX 샬라샬라 라는 글자가 보인다.!! 자 이런경우 우리는 압축방식이 UPX로 되어 있는것임을 알수 있다.
이제 압축을 풀기위해 도구가 필요하다. OllyDBG, OllyDump, Lord PE, 그리고 방금 사용한 PEID
우선 OllyDBG로 타깃을 연다. 그러면 오류가 뜨고 계속 할래 말래 물어본다. 여기서 계속 진행함을 선택하면, 잘못된 코드 정보가 보인다. 그 이유는 압축된 코드를 다시 어셈블리어로 번역한것이라 잘못된 정보라는것이다. 여기에서 스크롤을 내려 가장 아래쪽 코드를 보자. 00,00,00,00 ........
무수히 많은 00이 보인다. 그럼 00이 시작되는 곳의 경계를 찾아보자.
UPX방식은 압축후에 압축전 진입포인트를 파일 마지막에 기록하는것 같다. 00은 파일에서 데이터가 없는부분이다. 자 그럼 파일 마지막의 00이 아닌곳을 찾고 코드를 보자.
JMP 명령이 보이는가? 00이 아닌코드들 위로 3줄만 훑어보면 바로 JMP명령이 보일것이다. UPX형태의 압축은 압축을 풀고나서 파일 마지막의 JMP문을 통해 압축푼 프로그램으로 접근한다. 그렇기에 JMP구문의 주소를 따라가면 되는것이다.
우선 파일 마지막의 JMP구문에 F2를 눌러 브레이크포인트(앞으로 브포)를 걸어준다. F9키를 누르면 브포 영역까지 순차적으로 진행한다. 진행중에 브레이크포인트로 잡아놓은 부분에 멈췄다.
우선 JMP루틴에서 멈췄으므로 따라가보자. F8 키를 누르면 한단계 진행할 수 있다. F7은 함수가 있을때 함수 안으로 따라 들어가기, F8은 함수를 따라 들어가진 않고 현재 블락에서 한단계 진행을 의미한다.
방금전 JMP루틴에서 한단계를 진행하고 나면 어떤 코드와 맞닥들이게 된다. 여기에서 마우스 오른쪽 클릭을 하자. 그러면 ADD-IN 항목을 찾을수 있는데 그곳에서 OllyDump를 선택한다. OllyDump 는 Tool 설명에서 이미 설명했다. 새로 뜨는 창에서 Rebuild Import 체크를 없애준다. 그리고 바로 덤프 시작.
설명을 하자면 우리는 압축루틴을 그냥 F9로 다 스킵해버리고 압축이 메모리에 풀린 어느 시점에 JMP명령을 브포걸어서 잡아놓고, 그 JMP명령을 따라 시작되는 압축풀린 프로그램의 첫 코드부터 쭈우우우욱 덤프해버린 것이다.
자 그럼 덤프해버린 프로그램을 exe파일로 저장했다면, 실행해보자. 띠딩! 오류가 난다. 물론이다. 프로그램 엔트리 포인트(진입점)을 찾지 못하기 때문이다. 그럼 이 진입점을 어떻게 찾아주느냐?
Lord PE 라는 프로그램을 사용하겠다. 이 프로그램역시 Tool 설명에서 설명했다.
이 프로그램으로 망가진 exe를 고쳐보자. 우선 Lord PE프로그램을 실행하고, Rebuild PE 버튼을 누르고, exe파일을 넣어보자. 메시지가 뜨면서. 완료..
exe파일을 실행해보자. 여기서 잘 실행된다면 우리는 압축된 프로그램을 압축 풀어버린것이다.
UPX unpacking 하는방법 두가지
실험 실행파일 : CrackMe2.exe
첫번째 : upx 툴을 이용한다. 가장 빠르고 쉬운 방법..
명령 프롬프트에서 다음과 같이 입력한다.
upx -d [filename]
끝~ -_-; 같은 파일이름으로 unpacking 되어 저장된다.
두번째 : ollydbg 이용하기.
맨 뒤쯤 가면 jmp 문이 있다. 그곳에 bp를 걸고 실행(F9)한다. F8로 넘어가보면 그곳이 OEP이다. 이곳에서 우클릭하고 Dump debugged proccess를 선택하고 [ ] Rebuild Import의 체크를 해제한다. 그리고 Dump.
이제 Lord PE로 와서 Rebuild PE를 누른후 덤프한 파일을 선택한다.
[After Unpacking]
vbaStrCmp v2.1슬픔다
비쥬얼베이직으로 만들어진 프로그램이 있는곳에
폴더 안에 있는 vbaStrCmp2.dll, vbaStrCmp2.ini, msvbvm60.dll를 넣어주시고 실행하면..
스트링 비교하는게 다 보입니다..
vbde 라는 프로그램
vbde... 0.85 by iorior
Programming from the Ground Up
한번쯤 시간 내서 읽어 보도록 하자..
http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/Assembly/Documents/ProgrammingGroundUp/index.html
어셈 명령어 |
명 령 어 |
설 명 | |
Data Transfer | ||
MOV |
Move |
데이터 이동 (전송) |
PUSH |
Push |
오퍼랜드의 내용을 스택에 쌓는다 |
POP |
Pop |
스택으로부터 값을 뽑아낸다. |
XCHG |
Exchange Register/memory with Register |
첫 번째 오퍼랜드와 두 번째 오퍼랜드 교환 |
IN |
Input from AL/AX to Fixed port |
오퍼랜드로 지시된 포트로부터 AX에 데이터 입력 |
OUT |
Output from AL/AX to Fixed port |
오퍼랜드가 지시한 포트로 AX의 데이터 출력 |
XLAT |
Translate byte to |
BX:AL이 지시한 데이블의 내용을 AL로 로드 |
LEA |
Load Effective Address to Register |
메모리의 오프셋값을 레지스터로 로드 |
LDS |
Load Pointer to DS |
REG←(MEM), DS←(MEM+2) |
LES |
Load Pointer ti ES |
REG←(MEM), ES←(MEM+2) |
LAHF |
Load AH with Flags |
플래그의 내용을 AH의 특정 비트로 로드 |
SAHF |
Store AH into Flags |
AH의 특정 비트가 플래그 레지스터로 전송 |
PUSHF |
Push Flags |
플래그 레지스터의 내용을 스택에 쌓음 |
POPF |
Pop Flags |
스택으로부터 플래그 레지스터로 뽑음 |
Arithmetic | ||
ADD |
Add |
캐리를 포함하지 않은 덧셈 |
SBB |
Subtract with Borrow |
캐리를 포함한 뺄셈 |
DEC |
Decrement |
오퍼랜드 내용을 1 감소 |
NEG |
Change Sign |
오퍼랜드의 2의 보수, 즉 부호 반전 |
CMP |
Compare |
두 개의 오퍼랜드를 비교한다 |
ADC |
Add with Carry |
캐리를 포함한 덧셈 |
INC |
Increment |
오퍼랜드 내용을 1 증가 |
AAA |
ASCII adjust for Add |
덧셈 결과 AL값을 UNPACK 10진수로 보정 |
DAA |
Decimal adjust for Add |
덧셈 결과의 AL값을 PACK 10진수로 보정 |
SUB |
Subtract |
캐리를 포함하지 않은 뺄셈 |
AAS |
ASCII adjust for Subtract |
뺄셈 결과 AL값을 UNPACK 10진수로 보정 |
DAS |
Decimal adjust for Subtract |
뺄셈 결과의 AL값을 PACK 10진수로 보정 |
MUL |
Multiply (Unsigned) |
AX와 오퍼랜드를 곱셈하여 결과를 AX 또는 DX:AX에 저장 |
IMUL |
Integer Multiply (Signed) |
부호화된 곱셈 |
AAM |
ASCII adjust for Multiply |
곱셈 결과 AX값을 UNPACK 10진수로 보정 |
DIV |
Divide (Unsigned) |
AX 또는 DX:AX 내용을 오퍼랜드로 나눔. 몫은 AL, AX 나머지는 AH, DX로 저장 |
IDIV |
Integer Divide (Signed) |
부호화된 나눗셈 |
AAD |
ASCII adjust for Divide |
나눗셈 결과 AX값을 UNPACK 10진수로 보정 |
CBW |
Convert byte to word |
AL의 바이트 데이터를 부호 비트를 포함하여 AX 워드로 확장 |
CWD |
Convert word to double word |
AX의 워드 데이터를 부호를 포함하여 DX:AX의 더블 워드로 변환 |
Logic | ||
NOT |
Invert |
오퍼랜드의 1의 보수, 즉 비트 반전 |
SHL/SAL |
Shift logical / arithmetic Left |
왼쪽으로 오퍼랜드만큼 자리 이동 (최하위 비트는 0) |
SHR |
Shift logical Right |
오른쪽으로 오퍼랜드만큼 자리 이동 (최상위 비트 0) |
SAR |
Shift arithmetic Right |
오른쪽 자리이동, 최상위 비트는 유지 |
ROL |
Rotate Left |
왼쪽으로 오퍼랜드만큼 회전 이동 |
ROR |
Rotate Right |
오른쪽으로 오퍼랜드만큼 회전 이동 |
RCL |
Rotate through Carry Left |
캐리를 포함하여 왼쪽으로 오퍼랜드만큼 회전 이동 |
RCR |
Rotate through Carry Right |
캐리를 포함하여 오른쪽으로 오퍼랜드만큼 회전 이동 |
AND |
And |
논리 AND |
TEST |
And function to Flags, no result |
첫 번째 오퍼랜드와 두 번째 오퍼랜드를 AND하여 그 결과로 플래그 세트 |
OR |
Or |
논리 OR |
XOR |
Exclusive Or |
배타 논리 합 (OR) |
String Manipulation | ||
REP |
Repeat |
REP 뒤에 오는 스트링 명령을 CX가 0이 될 때까지 반복 |
MOVS |
Move String |
DS:SI가 지시한 메모리 데이터를 ES:DI가지시한 메모리로 전송 |
CMPS |
Compare String |
DS:SI와 ES:DI의 내용을 비교하고 결과에 따라 플래그 설정 |
SCAS |
Scan String |
AL 또는 AX와 ES:DI가 지시한 메모리 내용 비교하고 결과에 따라 플래그 설정 |
LODS |
Load String |
SI 내용을 AL 또는 AX로 로드 |
STOS |
Store String |
AL 또는 AX를 ES:DI가 지시하는 메모리에 저장 |
Control Transfer | ||
CALL |
Call |
프로시저 호출 |
JMP |
Unconditional Jump |
무조건 분기 |
RET |
Return from CALL |
CALL로 스택에 PUSH된 주소로 복귀 |
JE/JZ |
Jump on Equal / Zero |
결과가 0이면 분기 |
JL/JNGE |
Jump on Less / not Greater or Equal |
결과가 작으면 분기 (부호화된 수) |
JB/JNAE |
Jump on Below / not Above or Equal |
결과가 작으면 분기 (부호화 안 된 수) |
JBE/JNA |
Jump on Below or Equal / not Above |
결과가 작거나 같으면 분기 (부호화 안 된 수) |
JP/JPE |
Jump on Parity / Parity Even |
패리티 플레그가 1이면 분기 |
JO |
Jump on Overflow |
오버플로가 발생하면 분기 |
JS |
Jump on Sign |
부호 플레그가 1이면 분기 |
JNE/JNZ |
Jump on not Equal / not Zero |
결과가 0이 아니면 분기 |
JNL/JGE |
Jump on not Less / Greater or Equal |
결과가 크거나 같으면 분기 (부호화된 수) |
JNLE/JG |
Jump on not Less or Equal / Greater |
결과가 크면 분기 (부호화된 수) |
JNB/JAE |
Jump on not Below / Above or Equal |
결과가 크거나 같으면 분기 (부호화 안 된 수) |
JNBE/JA |
Jump on not Below or Equal / Above |
결과가 크면 분기 (부호화 안 된 수) |
JNP/JPO |
Jump on not Parity / Parity odd |
패리티 플레그가 0이면 분기 |
JNO |
Jump on not Overflow |
오버플로우가 아닌 경우 분기 |
JNS |
Jump on not Sign |
부호 플레그가 0이면 분기 |
|
Loop CX times |
CX를 1감소하면서 0이 될 때까지 지정된 라벨로 분기 |
LOOPZ/LOOPE |
|
제로 플레그가 1이고 CX≠0이면 지정된 라벨로 분기 |
LOOPNZ/LOOPNE |
|
제로 플레그가 0이고 CX≠0이면 지정된 라벨로 분기 |
JCXZ |
Jump on CX Zero |
CX가 0이면 분기 |
INT |
Interrupt |
인터럽트 실행 |
INTO |
Interrupt on Overflow |
오버플로우가 발생하면 인터럽트 실행 |
IRET |
Interrupt Return |
인터럽트 복귀 (리턴) |
Processor Control | ||
CLC |
Clear Carry |
캐리 플레그 클리어 |
CMC |
Complement Carry |
캐리 플레그를 반전 |
CLD |
Clear Direction |
디렉션 플레그를 클리어 |
CLI |
Clear Interrupt |
인터럽트 플레그를 클리어 |
HLT |
Halt |
정지 |
LOCK |
Bus Lock prefix |
|
STC |
Set Carry |
캐리 플레그 셋 |
NOP |
No operation |
|
STD |
Set Direction |
디렉션 플레그 셋 |
STI |
Set Interrupt |
인터럽트 인에이블 플레그 셋 |
WAIT |
Wait |
프로세서를 일지 정지 상태로 한다 |
ESC |
Escape to External device |
이스케이프 명령 |
Push: sp 레지스터를 조작하는 명령어중의 하나이다.
스택에 데이터를 저장하는데 쓰인다.
ex:) Push eax
:스택에 Eax의 값을 스택에 저장한다.
ex:) Push 20
:즉석값인 20을 스택에 저장한다.
ex:) Push 401F47
:메모리 오프셋 401F47의 값을 스택에 저장한다.
Pop: 이또한 sp 레지스터를 조작하는 명령어중 하나
이다. 스택에서 데이터를 꺼내는데 쓰인다.
ex:) Pop eax
:스택에 가장 상위에 있는 값을 꺼내애서 eax에 저장
주의점: Push 의 역순으로 값은 스택에서 Pop 된다.
Moo 메모리나 레지스터의 값을 옮길떄[로 만들떄]
쓰인다.
ex:) Mov eax,ebx
:ebx 레지스터의 값을 eax로 옮긴다[로 만든다].
ex:) Mov eax,20
:즉석값인 20을 eax레지스터 에 옮긴다[로 만든다].
ex:) Mov eax,dword ptr[401F47]
:메모리 오프셋 401F47 의 값을 eax에 옮긴다[로 만든다]
Lea: 오퍼렌드1의 값을 오퍼렌드2의 값으로 만들어준다.
ex:) Lea eax,ebx
:eax레지스터의 값을 ebx의 값으로 만든다.
Inc: 레지스터의 값을 1증가 시킨다.
ex:) Inc eax
:Eax 레지스터의 값을 1증가 시킨다.
Dec: 레지스터의 값을 1 감소 시킨다.
ex:) Dec eax
:Eax 레지스터의 값을 1 감소 시킨다.
Add: 레지스터나 메모리의 값을 덧셈할떄 쓰임.
ex:) Add eax,ebx
:Eax 레지스터의 값에 ebx 값을 더한다.
ex:) Add eax,50
:Eax 레지스터에 즉석값인 50을 더한다.
ex:) Add eax,dword ptr[401F47]
:Eax 레지스터에 메모리 오프셋 401F47의 값을 더한다.
강력한 테스크탑 뮤직 플레이어 송버드(Songbird)

모질라 재단의 프로젝트인 만큼, 보다 웹의 장점을 충실히 반영한 다양한 기능을 포함하고 있습니다.

아직은 개발 버전이어서 그런지 실제 활용에는 다소 무리가 있으나, 한번쯤 관심갖고 지켜보신다면 추후 Mozilla Firefox 못지 않은 강력한 프로그램으로 많은 이들에게 반드시 사랑받을 것이라 생각합니다. :)
http://songbirdnest.com/
어셈 자료 모두 영문 자료이다..
그외 어셈자료..
pcasm-book.pdf