레이블이 어셈블리인 게시물을 표시합니다. 모든 게시물 표시
레이블이 어셈블리인 게시물을 표시합니다. 모든 게시물 표시

2012년 9월 3일 월요일

어셈블리 명령어





어셈블리 명령어를 공부하며 정리한 글입니다.



INC(Increase)


피연산자에 1을 더한다
연산 결과에 따라 ZF나 OF가 세트될 수 있다

ex)
INC reg
INC mem


DEC(Decrease)


피연산자에 1을 뺀다
연산 결과에 따라 ZF나 OF가 세트될 수 있다

ex)
DEC reg
DEC mem



ADD(Add)


Destination에 Source의 값을 더해서 Destination에 저장하는 명령어이다.
연산 결과에 따라 ZF, OF, CF가 세트될 수 있다

ex)
ADD destination, source
ADD eax, 123


SUB(subtract)


Destination에 Source의 값을 빼서 Destination에 저장하는 명령어이다.
연산 결과에 따라 ZF, OF, CF가 세트될 수 있다

ex)

SUB destination, source
SUB eax, 123



MUL(unsigned Integer Multiply)


부호 없는 al, ax, eax의 값을 피연산자오 곱한다
피연산자가 8비트이면 al과 곱해서 ax에 저장되고, 16비트이면 ax와 곱하고 dx:ax에 저장된다.

ex)
MUL reg
MUL mem


IMUL(Integer Multiplication)


부호 있는 al, ax, eax의 값을 피연산자와 곱한다.
결과에따라 CF, OF가 세트될 수 있다.

ex)
IMUL r/m8   // 단일 피연산자이고 피연산자를 al, ax, eax에 곱한다

IMUL destination, value   // value를 al, ax, eax와 곱해서 destination에 저장한다

IMUL destination, value, value   // value끼리 곱해서 destination에 저장한다.

연산 결과가 destination 레지스터의 크기보다 크다면 OF, CF가 세트된다.


DIV(Unsigned Integer Divide)


8, 16, 32비트 부호 없는 정수의 나눗셈을 수행한다.

ex)
DIV reg
DIV mem


MOV(Move)


Source에서 Destination으로 데이터를 복사한다

ex)
MOV Destination, Source
MOV reg, reg


MOVS(Move String)


Source에서 Destination으로 데이터를 복사한다


ex)
MOVS Destination, Source


MOVSB, MOVSW, MOVSD (Move String)


SI 또는 ESI 레지스터에 의해 지정된 메모리 주소의 내용을 DI 또는 EDI 레지스터에 의해 지정되는 메모리 주소로 복사한다.

B : Byte 단위 복사
W : Word 단위 복사
D : Dword 단위 복사

DF(방향 플래그)가 1로 세트 되어 있으면 ESI와 EDI는 복사 시에 감소한다.
DF가 0으로 세트 되어 있으면 ESI와 EDI는 복사 시에 증가하게 된다.

ex)
MOVSB
MOVSW
MOVSD

INT(Interrupt)


소프트웨어 인터럽트를 발생시켜 운영체제의 서브루틴을 호출한다.

ex)
INT imm
INT 3


INT(Interrupt)


소프트웨어 인터럽트를 발생시켜 운영체제의 서브루틴을 호출한다.

ex)
INT imm
INT 3


AND(Logical AND)


Destination과 Source 피연산자의 각 비트가 AND 연산된다.

AND 연산은 각 비트가 모두 1일 때만 결과 값이 1이 된다.

AND 연산을 통해서 OF,CF가 0으로 세트 되고, 결과에 따라서 ZF가 1로 세트될 수 있다

ex)
AND reg, reg

OR(Inclusive OR)


Destination과 Source 피연산자의 각 비트가 OR 연산된다

OR 연산은 각 비트가 모두 0이면  결과가 0이고 모두 0이 아니면 결과가 1이 된다

OR 연산을 통해서 OF,CF가 0으로 세트 되고, 결과에 따라서 ZF가 1로 세트될 수 있다

ex)
OR reg,reg

XOR(Exclusive OR)



Destination과 Source 피연산자의 각 비트가 XOR 연산된다

XOR 연산은 각 비트가 서로 다른 값일때 만 결과가 1이다. 같은 값이라면 결과는 0이 된다.

XOR 연산을 통해서 OF,CF가 0으로 세트 되고, 결과에 따라서 ZF가 1로 세트될 수 있다

레지스터를 0으로 초기화 시킬때 XOR reg, reg를 많이 사용한다.

ex)
XOR reg, reg

TEST(Test)


두 피여산자 사이에 놀리적인 AND 연산을 수행하여 플래그 레지스터에 영향을 주지만 결과값은 저장하지 않는다.

OF, CF는 항상 0으로 세트되고 TEST 연산 결과값이 0이면 ZF가 1로, 0이 아니면 ZF가 0으로 세트된다.

ex)
TEST reg, reg

PUSH(Push on Stack)



스택에 값을 넣는다.

ESP의 값이 4만큼 줄어들고 이 위치에 새로운 값이 채워진다.

ex)
PUSH reg16

PUSHAD(Push All)


EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP 레지스터의 값을 스택에 PUSH 한다

레지스터들의 값을 보관해야 할 필요가 있을 때 사용한다.

ex)
PUSHAD

PUSHFD(Push Flags)


플래그 레지스터를 스택에 PUSH한다.

플래그 레지스터의 값을 보관해야 할 필요가 있을 떄 사용한다

ex)
PUSHFD

POP(Pop from Stack)


ESP레지스터가 가리키고 있는 위치의 스택 공간에서 4byte 만큼을 Destination 피연산자에 복사한다.

그리고 ESP 레지스터의 값에 4를 더한다.

ex)
POP destination

POPAD(Pop All Flags from Stack)



스택에 존재하는 값을 EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP 레지스터로 POP한다.

PUSHAD 명령어로 스택에 보관해 놓은 레지스터 정보를 다시 이용하려고 할 때 사용한다.

ex)
POP destination



POPFD(Pop Flags from Stack)




스택에 존재하는 값을 플래그 레지스터로 POP 한다.

PUSHFD 명령어로 스택에 보관해 놓은 레지스터 정보를 다시 이용하려고 할 때 사용한다.

ex)
POPFD


XCHG(Exchange)




두 피연산자의 내용이 서로 교환된다.

XCHG 명령은 imm 값이 피연산자로 올 수 없다.

ex)
XCHG reg, reg


NEG(Negate)



피연산자의 2의 보수를 계산하여 결과를 피연산자에 저장한다.

ex)
NEG reg
NEG mem

PTR



피연산자의 크기를 재설정한다.

ex)
MOV eax, DWORD PTR value

위의 명령어는 value의 크기르 DWORD 크기로 재설정하여 eax 레지스터에 복사한다는 의미다.


OFFSET


세그먼트의 시작으로부터 변수가 위치한 거리까지의 상대적 거리를 리턴한다.

ex)
MOV esi, OFFSET value

위 명령어는 value가 존재하는 위치를 세그먼트 시작 지점부터의 상대적 거리로 구해서 esi 레지스터에 복사하라는
의미이다.


LEA(Load Effective Address)


Source 피연산자의 유효 주소를 계산하여 Destination 피연산자에 복사한다

간단히 주소를 알아내서 복사하는 명령어라고 생각하면 쉽다.

ex)
LEA reg, mem

REP(Repeat String)




ECX 레지스터를 카운터로 사용해서 문자열 관련 명령을 ECX>0인 동안 반복한다.

ex)
REP MOVS destination, source

JMP(Jump Unconditionally to Lable)




피연산자의 위치로 실행 흐름이 변경된다.

피연산자가 가리키는 코드로 점프 뛰어서 실행한다고 생각하면 된다.

ex)
JMP reg16

CALL(Call a Procedure)




함수 호출시 사용된다.

JMP 명령어와 같이 프로그램의 실행 흐름이 변경되지만 JMP 명령어와 달리 돌아올 리턴 에드레스(CALL 다음 명령)를

스택에 저장한다

되돌아올 주소를 저장하기 때문에 함수 호출 후 원래 위치로 실행 흐름을 되돌릴 수 있다.

ex)
CALL 함수 주소
CALL <JMP to APU> 특정 api 지목
CALL DWORD PTR[EAX+5]

CMP(Compare)



두 피연산자를 비교하는 작업을 한다.

Destination 피연산자에서 Source 피연산자를 묵시적으로 빼서 값을 비교한다.

두 피연산자의 값이 같다면 결과는 0이 되고 ZF가 1로 세트된다.

다르다면 ZF는 0으로 세트된다.

ex)
CMP reg, reg


NOP(No Operation)


아무 일도 하지 않는 명령어이다.

리버싱 작업에서 목적에 따라 유용하게 사용될 수 있다.

ex)
NOP


조건 점프 명령


조건 점프 명령은 JMP 명령어와는 다르게 CMP 명령같이 특정 플래그 레지스터를 변경시킬 수 있는 명령어를

통해서 특정 조건이 만족하게 된다면 점프를 수행하게 되는 명령어이다.


명령어
명령어의 의미
명령어가 수행되기 위한 플래그
레지스터와 범용 레지스터의 상태
JA
Jump if (unsigned) above
CF=0 and ZF=0
JAE
Jump if (unsigned) above or equal
CF=0
JB
Jump if (unsigned) below
CF=1
JBE
Jump if (unsigned) below or equal
CF=1 or ZF=1
JC
Jump if carry flag set
CF=1
JCXZ
Jump if CX is 0
CX=0
JE
Jump if equal
ZF=1
JECXZ
Jump if ECX is 0
ECX=0
JG
Jump if (signed) greater
ZF=0 and SF=0
JGE
Jump if (signed) greater or equal
SF=OF
JL
Jump if (signed) less
SF!=OF
JLE
Jump if (signed) less or equal
ZF=1 and OF!=OF
JNA
Jump if (unsigned) not above
CF=1 or ZF=1
JNAE
Jump if (unsigned) not above or equal
CF=1
JNB
Jump if (unsigned) not below
CF=0
JNBE
Jump if (unsigned) not below or equal
CF=0 and ZF=0
JNC
Jump if carry flag not set
CF=0
JNE
Jump if not equal
ZF=0
JNG
Jump if (signed) not greater
ZF=1 or SF!=OF
JNGE
Jump if (signed) not greater or equal
SF!=OF
JNL
Jump if (signed) not less
SF=OF
JNLE
Jump if (signed) not less or equal
ZF=0 and SF=OF
JNO
Jump if overflow flag not set
OF=0
JNP
Jump if parity flag not set
PF=0
JNS
Jump if sign flag not set
SF=0
JNZ
Jump if not zero
ZF=0
JO
Jump if overflow flag is set
OF=1
JP
Jump if parity flag set
PF=1
JPE
Jump if parity is equal
PF=1
JPO
Jump if parity is odd
PF=0
JS
Jump if sign flag is set
SF=1
JZ
Jump is zero
ZF=1







참고 : 리버스엔지니어링 : 역분석 구조와 원리 박병익/이강석 공저





2012년 8월 28일 화요일

악성코드 분석 - Bundestrojaner [4]




트로이 목마 악성코드를 분석한 과정과 결과를 정리하려고 합니다.








winsys32.sys 파일을 생성하는 함수를 빠져 나오면



 LoadLibrary 함수를 통해 advapi32.dll를 로드하며



CreateService 함수의 주소를 획득하는 명령어가 나타납니다.

CreateService 함수는 advapi32.dll에 포함되어 있으며,




이 함수를 통해 winsys32.sys라는 서비스를 생성합니다.



이 함수를 빠져 나오면 winsys32.sys의 Filetime을 mfc422.dll의 FileTime으로 변경합니다.

이것 또한 분석가를 혼란스럽게 만들기 위한 작업니다.



이후 Skype, SkypePM 등의 파일을 실행하며 스카이프와 관련된 작업을 하는것 처럼 보입니다만

정확한 분석은 하지 못했습니다.


skype 문자들을 넘기고 나면 403FE5에서 4017C0으로 이동해



시스템의 Temp 디렉토리에 접근하고, ~acrd~tmp.exe 라는 새로운 파일을 만듭니다.

이 파일이 어떠한 작업을 하는지 알 수 없지만 나중에 다시 분석해 볼 생각입니다.



마지막으로 기존의 악성코드 파일은 MoveFileExW 함수를 통해 자기자신을 삭제됩니다.



그 후 ExitProcess 함수 호출로 프로세스를 종료하게 됩니다.




Bundestrojaner이 정확하게 어떤 활동을 하는지는 분석하지 않았지만

Dropper인 secuinist.exe가 어떤 함수를 통해 어떤 파일을 만들며

악성코드 제작자가 분석을 어렿게 하기 위해 몇가지 트릭을 설치해 놓은것까지 확인할 수 있었습니다.
다음번엔 Bundestrojaner가 어떻게 타겟의 정보를 획득하고

서버로 전송하는지에 대한 분석을 진행하도록 하겠습니다.


참고 : http://resources.infosecinstitute.com/german-trojan/


악성코드 분석 - Bundestrojaner [3]






트로이 목마 악성코드를 분석한 과정과 결과를 정리하려고 합니다.








이제 GetSystemDirectory 함수를 통해 시스템 디렉토리 정보를 얻고 동적 분석에서 확인했던 파일들을 만들기 시작합니다.


분석하시다 보면 4010F0에서 파일을 생성하는 CreateFile 함수를 통해



동적 분석에서 확인한 C:\Windows\System32\mfc42ul.dll 파일을

생성하는 것을 확인하실 수 있습니다.

지금 만들어진 mfc42ul.dll은 빈 파일로, 4010CF 함수에서 파일 내용이 채워집니다.


조금 더 내려가면 403EC4에서 함수 401E60이 Call 되며 이때 mfc42.dll와 mfc42ul.dll이 스택에 저장되어 전달됩니다.

mfc42.dll은 System32 폴더에 존재하는 윈도우즈 dll이며, mfc42ul.dll은 악성코드가 만든 파일 이름입니다.


함수 401E60에서는 401DC0로 Call이 발생하며



여기서 GetFileTime 함수를 통해 mfc42.dll의 Filetime 정보를 얻습니다.


이제 00401E10 함수에서



함수 SetFileTime을 통해 mfc42ul.dll의 파일시간이 방금 얻은 mfc42.dll의 FileTime으로 변경됩니다.


setFileTime 함수가 실행되기 전에 system32 폴더에서 확인하면 Data Modified 시간이 다르지만


setFileTime 함수 실행 후  Data Modified 시간이 같은 것을 확인할 수 있습니다.

이러한 기법을 사용해서 포렌식에서 새로 만들어진 파일을 찾기 어렵게 만듭니다.



다시 F8을 통해 명령어를 분석하다 보면 403F0E에서 OllyDbg의 코멘트 winsys32.sys를 보실 수 있습니다.

악성코드 제작자는 종종 이런 코멘트를 통해 악성코드 분석가의 관심을 다른곳으로 돌려

잘못된 코드 분석을 유도하기도 하지만, 이 경우엔 그렇지 않았습니다.



여기서 조금 내려가면 403F37에서 4011C0으로의 함수 Call이 있으며 여기서 isWow64 함수를 통해

프로세스가 32비트 환경에서 실행되는지 64비트 환경에서 실행되고 있는지를 확인합니다.


다음은, mfc42ul.dll의 경우 처럼 winsys32 파일을 생성하는 함수가 호출되며



호출되는 과정에서 403F49에서 Call이 실행되고 계속 step into 하면 401160 에서 32비트 환경에서

만들어진 프로그램을 64비트 환경에서 실행하기 위해 리다이렉트되는 것을 막는 함수가 보입니다. (정확하지 않음)

이 과정은 winsys32.sys가 32비트 혹은 64비트 환경에서만 작동하는 드라이버이기 때문에 발생하고 있는것 같습니다.

이 과정은 악성코드의 작용과는 별 상관이 없으므로 넘어가도록 하겠습니다.



계속 명령어를 넘기다 보면 CreateFile 함수 Call이 일어나며 System32 폴더에 빈 winsys32.sys 파일을 만듭니다.


위의 사진은 system32 폴더에 생성된 winsys32.sys 파일입니다.



mfc42ul.dll 의 내용을 채울때 처럼 WriteFile 함수를 통해서 winsys32.sys 파일의 내용을 채웁니다.



악성코드 분석 - Bundestrojaner [4] :