no image
CodeEngn Advance 15
문제확인이번 문제는 독특하게도 Unlock Code가 존재한다. 문제를 실행 시켜서 About을 통해 확인을 해보았을 때 올바른 Unlock Code를 찾은 후에 진행을 해야 하는 것 같다. The Serial-generation code in this crackme is obfuscated and there are no signatures this time.After the Unlock Code has been found, type it in and it will de-obfuscate the serial generation code.Then it should be straight forward. Rules:- No patching- Find the correct unlock code- Write a ..
2015.07.30
x86 Instruction Set Reference
x86 Instruction Set ReferenceDerived from the September 2014 version of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, volumes 2A and 2B.More info at zneak/x86docThis reference is not perfect. It's been mechanically separated into distinct files by a dumb script. It may be enough to replace the official documentation on your weekend reverse engineering project, but in doubt, ..
2015.07.29
no image
CodeEngn Advance 14
문제 확인이번문제도 시리얼이 주어지고 이에 해당하는 Name을 구하는 것이 문제이다. 이제 14번 이전까지 문제를 풀었던 사람들이라면 충분히 손쉽게 문제를 풀 수가 있는 문제이다. 분석우선 성공분기점을 찾는다. 아래와 같이 IDA를 통해서 봤을 때 LStrCmp()를 통하여 성공의 분기를 결정하는 것을 확인 할 수가 있다. 그렇다면 저 부분을 기준으로 이전의 명령어들을 살펴보자. 우선 프로그램을 디버거로 열어보면 아래의 지점으로 EIP가 구성이 된다. 그리고 총 5개의 호출함수가 보인다. 여기서 우리가 알아야할 것은 바로 4번쨰에 있는 함수로써 프로그램의 버튼을 클릭하였을 경우 이루어질 동작에 대해 정의된 곳이다.그 이전의 부분들은 GUI를 구성하는 작업을 하는 것이므로 굳이 힘들게 분석할 필요는 없는 ..
2015.07.24
no image
CodeEngn Advance 12
문제확인이번문제는 참 오래걸렸다. VB 특성상 MSVBVM60.DLL에 의하여 동작이 되기 때문에 개인적으로 다른 것에 비하여 분석하기가 까다로웠다. 풀이우선 시작부터 너무나 많이 왔다갔다하기때문에 중요한 부분만 사진으로 보겠다. 아래의 사진을 보면 ABCD를 입력하였을 경우 그에 해당하는 10진수의 값을 하나하나 주소에 적는 과정을 나타내고 있다. 이렇게 입력한 Name에 따라서 기록이 된다. 그렇게 입력된 값을 가지고 우리는 Value[5:9] 의 값이 밑에 rtcMidCharBstr에 의하여 4글자만 가지고 올 수 있게 된다. 밑에선 65666768에서 6768이 바로 그 값이 된다. 이 값은 나중에 시리얼에서 가운데 부분을 구성하게 된다. 위에서 나온 값을 가지고 아래의 부분에서 Loop가 진행이..
2015.07.22
no image
CodeEngn Advance 11
문제확인 확인 Name에 따른 시리얼이 형성되는 부분은 쉽게 찾을 수가 있다. 내가 입력한 name은 0000 serial은 11111111로 입력하였을때 아래와 같이 시러일이 비교되는 부분이 있다. 그리고 그 위에 이러한 키 값이 형성되는 부분이 존재 한다. 위에 있는 덤프창에 드래그 해 놓은 부분이 바로 키 값 형성에서 if 문을 결정짓게 해주는 요소들이다. 그리고 아래의 사진은 수많은 if문들이 존재한다. 실제로는 16~20개의 if 문이 존재한다. 하지만 여기서부터 문제가 시작되었다. 이번문제의 가장 큰 시사점은 작은 그림이 아니라 큰 그림을 보아야 한다는 것이다. 저러한 if문들을 계속 하나하나 따라가다보면 정말 미궁으로 빠져버린다. 본인은 미궁에서 2일을 소비했다...바로 위의 if문을 보는 ..
2015.07.17
no image
VisualSstudio 2013 Error : Class not registered. Looking for object with CLSID: {3B6A8A95-60A9-4EFC-AB17-DD892979B105}
Error:Visual Studio 2013Class not registered. Looking for object with CLSID: {3B6A8A95-60A9-4EFC-AB17-DD892979B105}. Solution:CMDcd C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDEdevenv.exe /setup
2015.07.17
no image
CodeEngn Advance 10
문제 확인 기초 확인 위의 사진은 주석과 같이 name을 입력 받고 name의 길이를 확인 하는 과정입니다. 이번에는 Serial을 입력받고 그 길이를 확인하는 과정입니다. 길이는 12글자여야 합니다. 참고로 이 접어놓은 부분은 문제의 의도를 잘못파악하고 단순노동을 작업하였다. 매우 삽질스러우니 한가할떄만 열어보자.키 값 형성 찾기우선 키 값이 어디선 형성되는지 찾기 위하여 정말로 많은 노가다를 하였다. 잘못 Step into하게 되어 헤매기를 얼마나 헤맸는지 결국 찾기는 하였다. 우선 계속 해서 우리는 Step Into를 통하여 안으로 들어갈 것이다.Step Into Step Into Step Into Step Into Step Into 드디어 키 값이 형성 되는 곳을 찾았다. 여기서 보아야 할 것은 ..
2015.07.13
no image
CodeEngn Advance 09
문제 확인문제를 확인해보면 참 설명이 간단하게 나와있다. Password는 무엇인가?이다. 그렇다면 시리얼값을 구하는 것일까했지만 여기서 문제는 우리가 직접 ID까지 알아내야한다는 것이다. 프로그램을 바로 실행시키면 아이디로 무엇을 입력해야할지 당황스럽다. 하지만 막상 디버거로 프로그램을 열면 바로 덤프 창에 This is the Username : DonaldDucK 이라고 적혀있는 것을 볼 수가 있다. 이것이 바로 우리의 ID 값이다. p.s 사실 굳이 이것을 발견하지 못해도 이후에 DonaldDuck과의 문자를 비교하는 Loop 구간이 있기에 처음에 발견하지 못하더라도 나중에 발견할 수가 있을 것이다. 풀이 우선 프로그램을 진행하다보면 위와 같이 내가 입력한 키값 123 (0x7B)와 실제 값인 0..
2015.07.12

문제확인


이번 문제는 독특하게도 Unlock Code가 존재한다. 문제를 실행 시켜서 About을 통해 확인을 해보았을 때 올바른 Unlock Code를 찾은 후에 진행을 해야 하는 것 같다.

The Serial-generation code in this crackme is obfuscated and there are no signatures this time.

After the Unlock Code has been found, type it in and it will de-obfuscate the serial generation code.

Then it should be straight forward.


Rules:

- No patching

- Find the correct unlock code

- Write a keygen

- Write a tutorial explaining how you solved this one and please include your code


i really look forward to seeing your solutions!



Unpacking - 1


Ollydbg를 통해서 문제를 열자마자 난해하게 되어 있다. 패킹이 되어 있는 것 같다. 이를 해제하기 위해선 그냥 단순하게 쭉 따라서 가도 괜찮지만  나는 그렇게 시간이 오래걸리는 방법을 선호하지는 않는다. 그렇기에 PE 구조도 최근에 공부한김에 이를 통해서 해보기로 했다.


우선 현재 EIP는 바로 저 부분으로 제대로 설정이 되어있다. 아래의 사진에서 보듯이 .text 영역은 흔히 Code 영역으로 실행에 쓰이는 Opcode들이 존재하고 있다. 이러한 .text 섹션의 시작 주소는 1000이다. 즉 ImageBase 까지 더한다고 생각하면 401000으로 이동을 해보자.


그 후 이 부분에 BP를 걸고 F9를 통해 진행을 할 경우 두번째 사진과 같이 패킹이 해제 되는 것을 확인 할 수가 있다. 이러한 방법 외에도 다양한 방법이 있는 것 같으니 직접 찾아보는 것을 추천드립니다.



Unpacking -2 


프로세스를 진행하다 보면 아래와 같이 2개의 호출문을 볼 수가 있다. 첫 번째 호출문은 Unlock Code를 가지고 어떠한 연산을 진행하는 부분이고, 두 번째 호출문은 0x7B 번 어떠한 연산을 진행하는 과정이다. 하나하나 살펴보자.


호출문 - 1

이 함수 내에는 Loop가 존재하는 이러한 반복문은 항상 수상히 여겨야 한다. 바로 내가 입력한 UnlockCode를 가져와서 연산을 진행한다. 연산에 대한 과정은 아래에 직접 타이핑한 것을 보면 어떻게 Loop가 진행하는지 충분히 이해를 할 수가 있다.

여기서 중요한 것은 바로 붉은 상자에 표시한 부분인데 저 부분이 최종적으로 나온 값이 저장되는 곳이다. 이 값은 후에 쓰이게 된다.

<Loop - 1 참고>


호출문 - 2

여기에는 위에서 나온 값을 통해 연산이 진행이 된다. 우선 lstrlen을 통해 Unlock Code의 길이가 1보다 큰지를 확인하고 만약 아니라면 바로 실패문을 출력을 한다. 이 부분을 넘어가면 바로 0040111C 에서부터 0040123C까지 이미 지정된 값을 위에서 나온 값과 XOR 연산을 진행하는 작업이다.

여기서 이 XOR에 쓰일 위의 값이 중요한 이유는 바로 감춰진 명령어들을 우리가 복구해야하기 때문이다.


특정한 값과 XOR연산이 진행된 후에 해당 주소의 값은 모두 변해 있다. 아래의 Dump 부분에 드래그 한 곳부터 나중에 호출이 되므로 이후에 참고하자.




Name을 통한 값 생성


위의 XOR 과정을 통해서 생성된 4011E8부분을 호출한다. 여기서 중요한 것은 결국 위의 XOR 값이 잘못된 값일 경우에는 이상한 명령어들로 복구시키므로 인하여 제대로 동작이 하지 않을 수가 있다. 즉 UnlockCode에 어떠한 값을 넣는지에 따라 전혀 다른 진행이 이루어 진다는 것이다.

처음에 나는 JMP문을 통해 어떠한 부분으로 가는 명령어들을 생성해야하는지 알고 삽질을 하였으나, 지인의 조언을 통하여 결국 새로운 함수를 호출하는 부분이므로 결국 그 함수에 진입을 하였을땐 스택프레임을 구성하는 작업이 이루어질것이라는 말이였다. 

즉 PUSH EBP; MOV EBP,ESP 가 이루어져야 하기에 위에서 4011E8의 코드를 55 8B EC에 초점을 맞추고 XOR 연산을 진행하였다. 그 결과 모두 0x25와 XOR을 진행했을 경우에 아래와 같이 정상적인 코드가 복구되는 것을 확인 할 수가 있다.


아래는 정상적으로 복구된 코드의 부분이다. 우선 GenerateSerial 이라고는 했지만 저 부분에서 최종 키 값이 형성이 되는 것이 아니라 그 최종 키 값 형성에 쓰이는 값을 형성하는 부분이므로 중요하다.


안을 들여다 보면 아래와 같이 Name을 통해 특정한 값을 생성한다. 구성은 아래의 Loop-2를 참고하면 조금 이해하기 편할 것 같다. 입력한 Name을 한 글자씩 읽은 다음에 Count 값과 같이 연산을 진행하는 구성이다. 



Serial 생성


위의 함수를 빠져나오면 바로 다시 새로운 Loop를 만나게 된다. 여기선 위에서 최종적으로 나온 값을 통해 Count와 연산을 진행하는 작업이 진행이 된다. 이 역시 자세한 구성은 아래의 Loop - 3을 참고하는 것이 편할 것이다.


그리고 성공문을 체크하는 곳으로 가면 아래와 같이 내가 입력한 Serial과 Name에 따라 생긴 Key 값이 한글자씩 비교가 되는 부분을 확인 할 수가 있다.



느낀점


이번 문제를 풀면서 역시 자살충동이 솟아났다. 도저히 혼자서 jmp문을 고집했다면 죽어도 못풀문제였다. 이번에 확실히 느낀건 여러 문제나 파일을 접하면서 직접 많이 해보는 것이 가장 좋은 방법같다. 앞으론 패킹이 되어있는 파일이 언패킹되는 과정을 좀더 유심히 보게 될것 같다.




'Reversing > CodeEngn' 카테고리의 다른 글

CodeEngn Advance 02  (0) 2015.07.30
CodeEngn Advance 14  (0) 2015.07.24
CodeEngn Advance 12  (1) 2015.07.22
CodeEngn Advance 11  (0) 2015.07.17
CodeEngn Advance 10  (0) 2015.07.13

x86 Instruction Set Reference

Derived from the September 2014 version of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, volumes 2A and 2B.

More info at zneak/x86doc

This reference is not perfect. It's been mechanically separated into distinct files by a dumb script. It may be enough to replace the official documentation on your weekend reverse engineering project, but in doubt, go get the official and freely available documentation.


x86.zip



AAAASCII Adjust After Addition
AADASCII Adjust AX Before Division
AAMASCII Adjust AX After Multiply
AASASCII Adjust AL After Subtraction
ADCAdd with Carry
ADCXUnsigned Integer Addition of Two Operands with Carry Flag
ADDAdd
ADDPDAdd Packed Double-Precision Floating-Point Values
ADDPSAdd Packed Single-Precision Floating-Point Values
ADDSDAdd Scalar Double-Precision Floating-Point Values
ADDSSAdd Scalar Single-Precision Floating-Point Values
ADDSUBPDPacked Double-FP Add/Subtract
ADDSUBPSPacked Single-FP Add/Subtract
ADOXUnsigned Integer Addition of Two Operands with Overflow Flag
AESDECPerform One Round of an AES Decryption Flow
AESDECLASTPerform Last Round of an AES Decryption Flow
AESENCPerform One Round of an AES Encryption Flow
AESENCLASTPerform Last Round of an AES Encryption Flow
AESIMCPerform the AES InvMixColumn Transformation
AESKEYGENASSISTAES Round Key Generation Assist
ANDLogical AND
ANDNLogical AND NOT
ANDNPDBitwise Logical AND NOT of Packed Double-Precision Floating-Point Values
ANDNPSBitwise Logical AND NOT of Packed Single-Precision Floating-Point Values
ANDPDBitwise Logical AND of Packed Double-Precision Floating-Point Values
ANDPSBitwise Logical AND of Packed Single-Precision Floating-Point Values
ARPLAdjust RPL Field of Segment Selector
BEXTRBit Field Extract
BLENDPDBlend Packed Double Precision Floating-Point Values
BLENDPSBlend Packed Single Precision Floating-Point Values
BLENDVPDVariable Blend Packed Double Precision Floating-Point Values
BLENDVPSVariable Blend Packed Single Precision Floating-Point Values
BLSIExtract Lowest Set Isolated Bit
BLSMSKGet Mask Up to Lowest Set Bit
BLSRReset Lowest Set Bit
BOUNDCheck Array Index Against Bounds
BSFBit Scan Forward
BSRBit Scan Reverse
BSWAPByte Swap
BTBit Test
BTCBit Test and Complement
BTRBit Test and Reset
BTSBit Test and Set
BZHIZero High Bits Starting with Specified Bit Position
CALLCall Procedure
CBWConvert Byte to Word/Convert Word to Doubleword/Convert Doubleword to Quadword
CDQConvert Word to Doubleword/Convert Doubleword to Quadword
CDQEConvert Byte to Word/Convert Word to Doubleword/Convert Doubleword to Quadword
CLACClear AC Flag in EFLAGS Register
CLCClear Carry Flag
CLDClear Direction Flag
CLFLUSHFlush Cache Line
CLIClear Interrupt Flag
CLTSClear Task-Switched Flag in CR0
CMCComplement Carry Flag
CMOVccConditional Move
CMPCompare Two Operands
CMPPDCompare Packed Double-Precision Floating-Point Values
CMPPSCompare Packed Single-Precision Floating-Point Values
CMPSCompare String Operands
CMPSBCompare String Operands
CMPSDCompare String Operands
CMPSDCompare Scalar Double-Precision Floating-Point Values
CMPSQCompare String Operands
CMPSSCompare Scalar Single-Precision Floating-Point Values
CMPSWCompare String Operands
CMPXCHGCompare and Exchange
CMPXCHG16BCompare and Exchange Bytes
CMPXCHG8BCompare and Exchange Bytes
COMISDCompare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS
COMISSCompare Scalar Ordered Single-Precision Floating-Point Values and Set EFLAGS
CPUIDCPU Identification
CQOConvert Word to Doubleword/Convert Doubleword to Quadword
CRC32Accumulate CRC32 Value
CVTDQ2PDConvert Packed Dword Integers to Packed Double-Precision FP Values
CVTDQ2PSConvert Packed Dword Integers to Packed Single-Precision FP Values
CVTPD2DQConvert Packed Double-Precision FP Values to Packed Dword Integers
CVTPD2PIConvert Packed Double-Precision FP Values to Packed Dword Integers
CVTPD2PSConvert Packed Double-Precision FP Values to Packed Single-Precision FP Values
CVTPI2PDConvert Packed Dword Integers to Packed Double-Precision FP Values
CVTPI2PSConvert Packed Dword Integers to Packed Single-Precision FP Values
CVTPS2DQConvert Packed Single-Precision FP Values to Packed Dword Integers
CVTPS2PDConvert Packed Single-Precision FP Values to Packed Double-Precision FP Values
CVTPS2PIConvert Packed Single-Precision FP Values to Packed Dword Integers
CVTSD2SIConvert Scalar Double-Precision FP Value to Integer
CVTSD2SSConvert Scalar Double-Precision FP Value to Scalar Single-Precision FP Value
CVTSI2SDConvert Dword Integer to Scalar Double-Precision FP Value
CVTSI2SSConvert Dword Integer to Scalar Single-Precision FP Value
CVTSS2SDConvert Scalar Single-Precision FP Value to Scalar Double-Precision FP Value
CVTSS2SIConvert Scalar Single-Precision FP Value to Dword Integer
CVTTPD2DQConvert with Truncation Packed Double-Precision FP Values to Packed Dword Integers
CVTTPD2PIConvert with Truncation Packed Double-Precision FP Values to Packed Dword Integers
CVTTPS2DQConvert with Truncation Packed Single-Precision FP Values to Packed Dword Integers
CVTTPS2PIConvert with Truncation Packed Single-Precision FP Values to Packed Dword Integers
CVTTSD2SIConvert with Truncation Scalar Double-Precision FP Value to Signed Integer
CVTTSS2SIConvert with Truncation Scalar Single-Precision FP Value to Dword Integer
CWDConvert Word to Doubleword/Convert Doubleword to Quadword
CWDEConvert Byte to Word/Convert Word to Doubleword/Convert Doubleword to Quadword
DAADecimal Adjust AL after Addition
DASDecimal Adjust AL after Subtraction
DECDecrement by 1
DIVUnsigned Divide
DIVPDDivide Packed Double-Precision Floating-Point Values
DIVPSDivide Packed Single-Precision Floating-Point Values
DIVSDDivide Scalar Double-Precision Floating-Point Values
DIVSSDivide Scalar Single-Precision Floating-Point Values
DPPDDot Product of Packed Double Precision Floating-Point Values
DPPSDot Product of Packed Single Precision Floating-Point Values
EMMSEmpty MMX Technology State
ENTERMake Stack Frame for Procedure Parameters
EXTRACTPSExtract Packed Single Precision Floating-Point Value
F2XM1Compute 2x–1
FABSAbsolute Value
FADDAdd
FADDPAdd
FBLDLoad Binary Coded Decimal
FBSTPStore BCD Integer and Pop
FCHSChange Sign
FCLEXClear Exceptions
FCMOVccFloating-Point Conditional Move
FCOMCompare Floating Point Values
FCOMICompare Floating Point Values and Set EFLAGS
FCOMIPCompare Floating Point Values and Set EFLAGS
FCOMPCompare Floating Point Values
FCOMPPCompare Floating Point Values
FCOSCosine
FDECSTPDecrement Stack-Top Pointer
FDIVDivide
FDIVPDivide
FDIVRReverse Divide
FDIVRPReverse Divide
FFREEFree Floating-Point Register
FIADDAdd
FICOMCompare Integer
FICOMPCompare Integer
FIDIVDivide
FIDIVRReverse Divide
FILDLoad Integer
FIMULMultiply
FINCSTPIncrement Stack-Top Pointer
FINITInitialize Floating-Point Unit
FISTStore Integer
FISTPStore Integer
FISTTPStore Integer with Truncation
FISUBSubtract
FISUBRReverse Subtract
FLDLoad Floating Point Value
FLD1Load Constant
FLDCWLoad x87 FPU Control Word
FLDENVLoad x87 FPU Environment
FLDL2ELoad Constant
FLDL2TLoad Constant
FLDLG2Load Constant
FLDLN2Load Constant
FLDPILoad Constant
FLDZLoad Constant
FMULMultiply
FMULPMultiply
FNCLEXClear Exceptions
FNINITInitialize Floating-Point Unit
FNOPNo Operation
FNSAVEStore x87 FPU State
FNSTCWStore x87 FPU Control Word
FNSTENVStore x87 FPU Environment
FNSTSWStore x87 FPU Status Word
FPATANPartial Arctangent
FPREMPartial Remainder
FPREM1Partial Remainder
FPTANPartial Tangent
FRNDINTRound to Integer
FRSTORRestore x87 FPU State
FSAVEStore x87 FPU State
FSCALEScale
FSINSine
FSINCOSSine and Cosine
FSQRTSquare Root
FSTStore Floating Point Value
FSTCWStore x87 FPU Control Word
FSTENVStore x87 FPU Environment
FSTPStore Floating Point Value
FSTSWStore x87 FPU Status Word
FSUBSubtract
FSUBPSubtract
FSUBRReverse Subtract
FSUBRPReverse Subtract
FTSTTEST
FUCOMUnordered Compare Floating Point Values
FUCOMICompare Floating Point Values and Set EFLAGS
FUCOMIPCompare Floating Point Values and Set EFLAGS
FUCOMPUnordered Compare Floating Point Values
FUCOMPPUnordered Compare Floating Point Values
FWAITWait
FXAMExamine ModR/M
FXCHExchange Register Contents
FXRSTORRestore x87 FPU, MMX, XMM, and MXCSR State
FXSAVESave x87 FPU, MMX Technology, and SSE State
FXTRACTExtract Exponent and Significand
FYL2XCompute y ∗ log2x
FYL2XP1Compute y ∗ log2(x +1)
HADDPDPacked Double-FP Horizontal Add
HADDPSPacked Single-FP Horizontal Add
HLTHalt
HSUBPDPacked Double-FP Horizontal Subtract
HSUBPSPacked Single-FP Horizontal Subtract
IDIVSigned Divide
IMULSigned Multiply
INInput from Port
INCIncrement by 1
INSInput from Port to String
INSBInput from Port to String
INSDInput from Port to String
INSERTPSInsert Packed Single Precision Floating-Point Value
INSWInput from Port to String
INT 3Call to Interrupt Procedure
INT nCall to Interrupt Procedure
INTOCall to Interrupt Procedure
INVDInvalidate Internal Caches
INVLPGInvalidate TLB Entries
INVPCIDInvalidate Process-Context Identifier
IRETInterrupt Return
IRETDInterrupt Return
JMPJump
JccJump if Condition Is Met
LAHFLoad Status Flags into AH Register
LARLoad Access Rights Byte
LDDQULoad Unaligned Integer 128 Bits
LDMXCSRLoad MXCSR Register
LDSLoad Far Pointer
LEALoad Effective Address
LEAVEHigh Level Procedure Exit
LESLoad Far Pointer
LFENCELoad Fence
LFSLoad Far Pointer
LGDTLoad Global/Interrupt Descriptor Table Register
LGSLoad Far Pointer
LIDTLoad Global/Interrupt Descriptor Table Register
LLDTLoad Local Descriptor Table Register
LMSWLoad Machine Status Word
LOCKAssert LOCK# Signal Prefix
LODSLoad String
LODSBLoad String
LODSDLoad String
LODSQLoad String
LODSWLoad String
LOOPLoop According to ECX Counter
LOOPccLoop According to ECX Counter
LSLLoad Segment Limit
LSSLoad Far Pointer
LTRLoad Task Register
LZCNTCount the Number of Leading Zero Bits
MASKMOVDQUStore Selected Bytes of Double Quadword
MASKMOVQStore Selected Bytes of Quadword
MAXPDReturn Maximum Packed Double-Precision Floating-Point Values
MAXPSReturn Maximum Packed Single-Precision Floating-Point Values
MAXSDReturn Maximum Scalar Double-Precision Floating-Point Value
MAXSSReturn Maximum Scalar Single-Precision Floating-Point Value
MFENCEMemory Fence
MINPDReturn Minimum Packed Double-Precision Floating-Point Values
MINPSReturn Minimum Packed Single-Precision Floating-Point Values
MINSDReturn Minimum Scalar Double-Precision Floating-Point Value
MINSSReturn Minimum Scalar Single-Precision Floating-Point Value
MONITORSet Up Monitor Address
MOVMove
MOVMove to/from Control Registers
MOVMove to/from Debug Registers
MOVAPDMove Aligned Packed Double-Precision Floating-Point Values
MOVAPSMove Aligned Packed Single-Precision Floating-Point Values
MOVBEMove Data After Swapping Bytes
MOVDMove Doubleword/Move Quadword
MOVDDUPMove One Double-FP and Duplicate
MOVDQ2QMove Quadword from XMM to MMX Technology Register
MOVDQAMove Aligned Double Quadword
MOVDQUMove Unaligned Double Quadword
MOVHLPSMove Packed Single-Precision Floating-Point Values High to Low
MOVHPDMove High Packed Double-Precision Floating-Point Value
MOVHPSMove High Packed Single-Precision Floating-Point Values
MOVLHPSMove Packed Single-Precision Floating-Point Values Low to High
MOVLPDMove Low Packed Double-Precision Floating-Point Value
MOVLPSMove Low Packed Single-Precision Floating-Point Values
MOVMSKPDExtract Packed Double-Precision Floating-Point Sign Mask
MOVMSKPSExtract Packed Single-Precision Floating-Point Sign Mask
MOVNTDQStore Double Quadword Using Non-Temporal Hint
MOVNTDQALoad Double Quadword Non-Temporal Aligned Hint
MOVNTIStore Doubleword Using Non-Temporal Hint
MOVNTPDStore Packed Double-Precision Floating-Point Values Using Non-Temporal Hint
MOVNTPSStore Packed Single-Precision Floating-Point Values Using Non-Temporal Hint
MOVNTQStore of Quadword Using Non-Temporal Hint
MOVQMove Doubleword/Move Quadword
MOVQMove Quadword
MOVQ2DQMove Quadword from MMX Technology to XMM Register
MOVSMove Data from String to String
MOVSBMove Data from String to String
MOVSDMove Data from String to String
MOVSDMove Scalar Double-Precision Floating-Point Value
MOVSHDUPMove Packed Single-FP High and Duplicate
MOVSLDUPMove Packed Single-FP Low and Duplicate
MOVSQMove Data from String to String
MOVSSMove Scalar Single-Precision Floating-Point Values
MOVSWMove Data from String to String
MOVSXMove with Sign-Extension
MOVSXDMove with Sign-Extension
MOVUPDMove Unaligned Packed Double-Precision Floating-Point Values
MOVUPSMove Unaligned Packed Single-Precision Floating-Point Values
MOVZXMove with Zero-Extend
MPSADBWCompute Multiple Packed Sums of Absolute Difference
MULUnsigned Multiply
MULPDMultiply Packed Double-Precision Floating-Point Values
MULPSMultiply Packed Single-Precision Floating-Point Values
MULSDMultiply Scalar Double-Precision Floating-Point Values
MULSSMultiply Scalar Single-Precision Floating-Point Values
MWAITMonitor Wait
MULXUnsigned Multiply Without Affecting Flags
MWAITMonitor Wait
NEGTwo's Complement Negation
NOPNo Operation
NOTOne's Complement Negation
ORLogical Inclusive OR
ORPDBitwise Logical OR of Double-Precision Floating-Point Values
ORPSBitwise Logical OR of Single-Precision Floating-Point Values
OUTOutput to Port
OUTSOutput String to Port
OUTSBOutput String to Port
OUTSDOutput String to Port
OUTSWOutput String to Port
PABSBPacked Absolute Value
PABSDPacked Absolute Value
PABSWPacked Absolute Value
PACKSSDWPack with Signed Saturation
PACKSSWBPack with Signed Saturation
PACKUSDWPack with Unsigned Saturation
PACKUSWBPack with Unsigned Saturation
PADDBAdd Packed Integers
PADDDAdd Packed Integers
PADDQAdd Packed Quadword Integers
PADDSBAdd Packed Signed Integers with Signed Saturation
PADDSWAdd Packed Signed Integers with Signed Saturation
PADDUSBAdd Packed Unsigned Integers with Unsigned Saturation
PADDUSWAdd Packed Unsigned Integers with Unsigned Saturation
PADDWAdd Packed Integers
PALIGNRPacked Align Right
PANDLogical AND
PANDNLogical AND NOT
PAUSESpin Loop Hint
PAVGBAverage Packed Integers
PAVGWAverage Packed Integers
PBLENDVBVariable Blend Packed Bytes
PBLENDWBlend Packed Words
PCLMULQDQCarry-Less Multiplication Quadword
PCMPEQBCompare Packed Data for Equal
PCMPEQDCompare Packed Data for Equal
PCMPEQQCompare Packed Qword Data for Equal
PCMPEQWCompare Packed Data for Equal
PCMPESTRIPacked Compare Explicit Length Strings, Return Index
PCMPESTRMPacked Compare Explicit Length Strings, Return Mask
PCMPGTBCompare Packed Signed Integers for Greater Than
PCMPGTDCompare Packed Signed Integers for Greater Than
PCMPGTQCompare Packed Data for Greater Than
PCMPGTWCompare Packed Signed Integers for Greater Than
PCMPISTRIPacked Compare Implicit Length Strings, Return Index
PCMPISTRMPacked Compare Implicit Length Strings, Return Mask
PDEPParallel Bits Deposit
PEXTParallel Bits Extract
PEXTRBExtract Byte/Dword/Qword
PEXTRDExtract Byte/Dword/Qword
PEXTRQExtract Byte/Dword/Qword
PEXTRWExtract Word
PHADDDPacked Horizontal Add
PHADDSWPacked Horizontal Add and Saturate
PHADDWPacked Horizontal Add
PHMINPOSUWPacked Horizontal Word Minimum
PHSUBDPacked Horizontal Subtract
PHSUBSWPacked Horizontal Subtract and Saturate
PHSUBWPacked Horizontal Subtract
PINSRBInsert Byte/Dword/Qword
PINSRDInsert Byte/Dword/Qword
PINSRQInsert Byte/Dword/Qword
PINSRWInsert Word
PMADDUBSWMultiply and Add Packed Signed and Unsigned Bytes
PMADDWDMultiply and Add Packed Integers
PMAXSBMaximum of Packed Signed Byte Integers
PMAXSDMaximum of Packed Signed Dword Integers
PMAXSWMaximum of Packed Signed Word Integers
PMAXUBMaximum of Packed Unsigned Byte Integers
PMAXUDMaximum of Packed Unsigned Dword Integers
PMAXUWMaximum of Packed Word Integers
PMINSBMinimum of Packed Signed Byte Integers
PMINSDMinimum of Packed Dword Integers
PMINSWMinimum of Packed Signed Word Integers
PMINUBMinimum of Packed Unsigned Byte Integers
PMINUDMinimum of Packed Dword Integers
PMINUWMinimum of Packed Word Integers
PMOVMSKBMove Byte Mask
PMOVSXPacked Move with Sign Extend
PMOVZXPacked Move with Zero Extend
PMULDQMultiply Packed Signed Dword Integers
PMULHRSWPacked Multiply High with Round and Scale
PMULHUWMultiply Packed Unsigned Integers and Store High Result
PMULHWMultiply Packed Signed Integers and Store High Result
PMULLDMultiply Packed Signed Dword Integers and Store Low Result
PMULLWMultiply Packed Signed Integers and Store Low Result
PMULUDQMultiply Packed Unsigned Doubleword Integers
POPPop a Value from the Stack
POPAPop All General-Purpose Registers
POPADPop All General-Purpose Registers
POPCNTReturn the Count of Number of Bits Set to 1
POPFPop Stack into EFLAGS Register
POPFDPop Stack into EFLAGS Register
POPFQPop Stack into EFLAGS Register
PORBitwise Logical OR
PREFETCHWPrefetch Data into Caches in Anticipation of a Write
PREFETCHWT1Prefetch Vector Data Into Caches with Intent to Write and T1 Hint
PREFETCHhPrefetch Data Into Caches
PSADBWCompute Sum of Absolute Differences
PSHUFBPacked Shuffle Bytes
PSHUFDShuffle Packed Doublewords
PSHUFHWShuffle Packed High Words
PSHUFLWShuffle Packed Low Words
PSHUFWShuffle Packed Words
PSIGNBPacked SIGN
PSIGNDPacked SIGN
PSIGNWPacked SIGN
PSLLDShift Packed Data Left Logical
PSLLDQShift Double Quadword Left Logical
PSLLQShift Packed Data Left Logical
PSLLWShift Packed Data Left Logical
PSRADShift Packed Data Right Arithmetic
PSRAWShift Packed Data Right Arithmetic
PSRLDShift Packed Data Right Logical
PSRLDQShift Double Quadword Right Logical
PSRLQShift Packed Data Right Logical
PSRLWShift Packed Data Right Logical
PSUBBSubtract Packed Integers
PSUBDSubtract Packed Integers
PSUBQSubtract Packed Quadword Integers
PSUBSBSubtract Packed Signed Integers with Signed Saturation
PSUBSWSubtract Packed Signed Integers with Signed Saturation
PSUBUSBSubtract Packed Unsigned Integers with Unsigned Saturation
PSUBUSWSubtract Packed Unsigned Integers with Unsigned Saturation
PSUBWSubtract Packed Integers
PTESTLogical Compare
PUNPCKHBWUnpack High Data
PUNPCKHDQUnpack High Data
PUNPCKHQDQUnpack High Data
PUNPCKHWDUnpack High Data
PUNPCKLBWUnpack Low Data
PUNPCKLDQUnpack Low Data
PUNPCKLQDQUnpack Low Data
PUNPCKLWDUnpack Low Data
PUSHPush Word, Doubleword or Quadword Onto the Stack
PUSHAPush All General-Purpose Registers
PUSHADPush All General-Purpose Registers
PUSHFPush EFLAGS Register onto the Stack
PUSHFDPush EFLAGS Register onto the Stack
PXORLogical Exclusive OR
RCL—Rotate
RCPPSCompute Reciprocals of Packed Single-Precision Floating-Point Values
RCPSSCompute Reciprocal of Scalar Single-Precision Floating-Point Values
RCR—Rotate
RDFSBASERead FS/GS Segment Base
RDGSBASERead FS/GS Segment Base
RDMSRRead from Model Specific Register
RDPMCRead Performance-Monitoring Counters
RDRANDRead Random Number
RDSEEDRead Random SEED
RDTSCRead Time-Stamp Counter
RDTSCPRead Time-Stamp Counter and Processor ID
REPRepeat String Operation Prefix
REPERepeat String Operation Prefix
REPNERepeat String Operation Prefix
REPNZRepeat String Operation Prefix
REPZRepeat String Operation Prefix
RETReturn from Procedure
ROL—Rotate
ROR—Rotate
RORXRotate Right Logical Without Affecting Flags
ROUNDPDRound Packed Double Precision Floating-Point Values
ROUNDPSRound Packed Single Precision Floating-Point Values
ROUNDSDRound Scalar Double Precision Floating-Point Values
ROUNDSSRound Scalar Single Precision Floating-Point Values
RSMResume from System Management Mode
RSQRTPSCompute Reciprocals of Square Roots of Packed Single-Precision Floating-Point Values
RSQRTSSCompute Reciprocal of Square Root of Scalar Single-Precision Floating-Point Value
SAHFStore AH into Flags
SALShift
SARShift
SARXShift Without Affecting Flags
SBBInteger Subtraction with Borrow
SCASScan String
SCASBScan String
SCASDScan String
SCASWScan String
SETccSet Byte on Condition
SFENCEStore Fence
SGDTStore Global Descriptor Table Register
SHLShift
SHLDDouble Precision Shift Left
SHLXShift Without Affecting Flags
SHRShift
SHRDDouble Precision Shift Right
SHRXShift Without Affecting Flags
SHUFPDShuffle Packed Double-Precision Floating-Point Values
SHUFPSShuffle Packed Single-Precision Floating-Point Values
SIDTStore Interrupt Descriptor Table Register
SLDTStore Local Descriptor Table Register
SMSWStore Machine Status Word
SQRTPDCompute Square Roots of Packed Double-Precision Floating-Point Values
SQRTPSCompute Square Roots of Packed Single-Precision Floating-Point Values
SQRTSDCompute Square Root of Scalar Double-Precision Floating-Point Value
SQRTSSCompute Square Root of Scalar Single-Precision Floating-Point Value
STACSet AC Flag in EFLAGS Register
STCSet Carry Flag
STDSet Direction Flag
STISet Interrupt Flag
STMXCSRStore MXCSR Register State
STOSStore String
STOSBStore String
STOSDStore String
STOSQStore String
STOSWStore String
STRStore Task Register
SUBSubtract
SUBPDSubtract Packed Double-Precision Floating-Point Values
SUBPSSubtract Packed Single-Precision Floating-Point Values
SUBSDSubtract Scalar Double-Precision Floating-Point Values
SUBSSSubtract Scalar Single-Precision Floating-Point Values
SWAPGSSwap GS Base Register
SYSCALLFast System Call
SYSENTERFast System Call
SYSEXITFast Return from Fast System Call
SYSRETReturn From Fast System Call
TESTLogical Compare
TZCNTCount the Number of Trailing Zero Bits
UCOMISDUnordered Compare Scalar Double-Precision Floating-Point Values and Set EFLAGS
UCOMISSUnordered Compare Scalar Single-Precision Floating-Point Values and Set EFLAGS
UD2Undefined Instruction
UNPCKHPDUnpack and Interleave High Packed Double-Precision Floating-Point Values
UNPCKHPSUnpack and Interleave High Packed Single-Precision Floating-Point Values
UNPCKLPDUnpack and Interleave Low Packed Double-Precision Floating-Point Values
UNPCKLPSUnpack and Interleave Low Packed Single-Precision Floating-Point Values
VBROADCASTBroadcast Floating-Point Data
VCVTPH2PSConvert 16-bit FP Values to Single-Precision FP Values
VCVTPS2PHConvert Single-Precision FP value to 16-bit FP value
VERRVerify a Segment for Reading or Writing
VERWVerify a Segment for Reading or Writing
VEXTRACTF128Extract Packed Floating-Point Values
VEXTRACTI128Extract packed Integer Values
VFMADD132PDFused Multiply-Add of Packed Double-Precision Floating-Point Values
VFMADD132PSFused Multiply-Add of Packed Single-Precision Floating-Point Values
VFMADD132SDFused Multiply-Add of Scalar Double-Precision Floating-Point Values
VFMADD132SSFused Multiply-Add of Scalar Single-Precision Floating-Point Values
VFMADD213PDFused Multiply-Add of Packed Double-Precision Floating-Point Values
VFMADD213PSFused Multiply-Add of Packed Single-Precision Floating-Point Values
VFMADD213SDFused Multiply-Add of Scalar Double-Precision Floating-Point Values
VFMADD213SSFused Multiply-Add of Scalar Single-Precision Floating-Point Values
VFMADD231PDFused Multiply-Add of Packed Double-Precision Floating-Point Values
VFMADD231PSFused Multiply-Add of Packed Single-Precision Floating-Point Values
VFMADD231SDFused Multiply-Add of Scalar Double-Precision Floating-Point Values
VFMADD231SSFused Multiply-Add of Scalar Single-Precision Floating-Point Values
VFMADDSUB132PDFused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values
VFMADDSUB132PSFused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values
VFMADDSUB213PDFused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values
VFMADDSUB213PSFused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values
VFMADDSUB231PDFused Multiply-Alternating Add/Subtract of Packed Double-Precision Floating-Point Values
VFMADDSUB231PSFused Multiply-Alternating Add/Subtract of Packed Single-Precision Floating-Point Values
VFMSUB132PDFused Multiply-Subtract of Packed Double-Precision Floating-Point Values
VFMSUB132PSFused Multiply-Subtract of Packed Single-Precision Floating-Point Values
VFMSUB132SDFused Multiply-Subtract of Scalar Double-Precision Floating-Point Values
VFMSUB132SSFused Multiply-Subtract of Scalar Single-Precision Floating-Point Values
VFMSUB213PDFused Multiply-Subtract of Packed Double-Precision Floating-Point Values
VFMSUB213PSFused Multiply-Subtract of Packed Single-Precision Floating-Point Values
VFMSUB213SDFused Multiply-Subtract of Scalar Double-Precision Floating-Point Values
VFMSUB213SSFused Multiply-Subtract of Scalar Single-Precision Floating-Point Values
VFMSUB231PDFused Multiply-Subtract of Packed Double-Precision Floating-Point Values
VFMSUB231PSFused Multiply-Subtract of Packed Single-Precision Floating-Point Values
VFMSUB231SDFused Multiply-Subtract of Scalar Double-Precision Floating-Point Values
VFMSUB231SSFused Multiply-Subtract of Scalar Single-Precision Floating-Point Values
VFMSUBADD132PDFused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values
VFMSUBADD132PSFused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values
VFMSUBADD213PDFused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values
VFMSUBADD213PSFused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values
VFMSUBADD231PDFused Multiply-Alternating Subtract/Add of Packed Double-Precision Floating-Point Values
VFMSUBADD231PSFused Multiply-Alternating Subtract/Add of Packed Single-Precision Floating-Point Values
VFNMADD132PDFused Negative Multiply-Add of Packed Double-Precision Floating-Point Values
VFNMADD132PSFused Negative Multiply-Add of Packed Single-Precision Floating-Point Values
VFNMADD132SDFused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values
VFNMADD132SSFused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values
VFNMADD213PDFused Negative Multiply-Add of Packed Double-Precision Floating-Point Values
VFNMADD213PSFused Negative Multiply-Add of Packed Single-Precision Floating-Point Values
VFNMADD213SDFused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values
VFNMADD213SSFused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values
VFNMADD231PDFused Negative Multiply-Add of Packed Double-Precision Floating-Point Values
VFNMADD231PSFused Negative Multiply-Add of Packed Single-Precision Floating-Point Values
VFNMADD231SDFused Negative Multiply-Add of Scalar Double-Precision Floating-Point Values
VFNMADD231SSFused Negative Multiply-Add of Scalar Single-Precision Floating-Point Values
VFNMSUB132PDFused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values
VFNMSUB132PSFused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values
VFNMSUB132SDFused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values
VFNMSUB132SSFused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values
VFNMSUB213PDFused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values
VFNMSUB213PSFused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values
VFNMSUB213SDFused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values
VFNMSUB213SSFused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values
VFNMSUB231PDFused Negative Multiply-Subtract of Packed Double-Precision Floating-Point Values
VFNMSUB231PSFused Negative Multiply-Subtract of Packed Single-Precision Floating-Point Values
VFNMSUB231SDFused Negative Multiply-Subtract of Scalar Double-Precision Floating-Point Values
VFNMSUB231SSFused Negative Multiply-Subtract of Scalar Single-Precision Floating-Point Values
VGATHERDPDGather Packed DP FP Values Using Signed Dword/Qword Indices
VGATHERDPSGather Packed SP FP values Using Signed Dword/Qword Indices
VGATHERQPDGather Packed DP FP Values Using Signed Dword/Qword Indices
VGATHERQPSGather Packed SP FP values Using Signed Dword/Qword Indices
VINSERTF128Insert Packed Floating-Point Values
VINSERTI128Insert Packed Integer Values
VMASKMOVConditional SIMD Packed Loads and Stores
VPBLENDDBlend Packed Dwords
VPBROADCASTBroadcast Integer Data
VPERM2F128Permute Floating-Point Values
VPERM2I128Permute Integer Values
VPERMDFull Doublewords Element Permutation
VPERMILPDPermute Double-Precision Floating-Point Values
VPERMILPSPermute Single-Precision Floating-Point Values
VPERMPDPermute Double-Precision Floating-Point Elements
VPERMPSPermute Single-Precision Floating-Point Elements
VPERMQQwords Element Permutation
VPGATHERDDGather Packed Dword Values Using Signed Dword/Qword Indices
VPGATHERDQGather Packed Qword Values Using Signed Dword/Qword Indices
VPGATHERQDGather Packed Dword Values Using Signed Dword/Qword Indices
VPGATHERQQGather Packed Qword Values Using Signed Dword/Qword Indices
VPMASKMOVConditional SIMD Integer Packed Loads and Stores
VPSLLVDVariable Bit Shift Left Logical
VPSLLVQVariable Bit Shift Left Logical
VPSRAVDVariable Bit Shift Right Arithmetic
VPSRLVDVariable Bit Shift Right Logical
VPSRLVQVariable Bit Shift Right Logical
VTESTPDPacked Bit Test
VTESTPSPacked Bit Test
VZEROALLZero All YMM Registers
VZEROUPPERZero Upper Bits of YMM Registers
WAITWait
WBINVDWrite Back and Invalidate Cache
WRFSBASEWrite FS/GS Segment Base
WRGSBASEWrite FS/GS Segment Base
WRMSRWrite to Model Specific Register
XABORTTransactional Abort
XACQUIREHardware Lock Elision Prefix Hints
XADDExchange and Add
XBEGINTransactional Begin
XCHGExchange Register/Memory with Register
XENDTransactional End
XGETBVGet Value of Extended Control Register
XLATTable Look-up Translation
XLATBTable Look-up Translation
XORLogical Exclusive OR
XORPDBitwise Logical XOR for Double-Precision Floating-Point Values
XORPSBitwise Logical XOR for Single-Precision Floating-Point Values
XRELEASEHardware Lock Elision Prefix Hints
XRSTORRestore Processor Extended States
XRSTORSRestore Processor Extended States Supervisor
XSAVESave Processor Extended States
XSAVECSave Processor Extended States with Compaction
XSAVEOPTSave Processor Extended States Optimized
XSAVESSave Processor Extended States Supervisor
XSETBVSet Extended Control Register
XTESTTest If In Transactional Execution


'Reversing > Theory' 카테고리의 다른 글

Code Virtualized - 코드 가상화 참고자료  (0) 2015.08.17
Practical Malware Analysis - 1  (0) 2015.07.31
RVA to RAW 쉽게 생각해보기  (1) 2015.03.20
범용 CPU 레지스터  (1) 2015.03.04
Assembly Basic Commands  (0) 2015.01.23

문제 확인


이번문제도 시리얼이 주어지고 이에 해당하는 Name을 구하는 것이 문제이다. 이제 14번 이전까지 문제를 풀었던 사람들이라면 충분히 손쉽게 문제를 풀 수가 있는 문제이다.



분석


우선 성공분기점을 찾는다. 아래와 같이 IDA를 통해서 봤을 때 LStrCmp()를 통하여 성공의 분기를 결정하는 것을 확인 할 수가 있다. 그렇다면 저 부분을 기준으로 이전의 명령어들을 살펴보자.


우선 프로그램을 디버거로 열어보면 아래의 지점으로 EIP가 구성이 된다. 그리고 총 5개의 호출함수가 보인다. 여기서 우리가 알아야할 것은 바로 4번쨰에 있는 함수로써 프로그램의 버튼을 클릭하였을 경우 이루어질 동작에 대해 정의된 곳이다.

그 이전의 부분들은 GUI를 구성하는 작업을 하는 것이므로 굳이 힘들게 분석할 필요는 없는 것 같다.


Run() 함수로 진입하여 살펴보다보면 아래와 같이 내가 입력한 Name과 Serial들을 가지고 확인작업을 하는 것을 볼 수가 있다. 설명은 주석으로 달아놓았지만 그래도 모든 부분을 다 포함하기에는 너무나 길기 떄문에 IDA-Hexray로 대체하겠다.


밑에 보는 것과 같이 특정한 자리에 특정한 값이 오는지를 확인하기도 한다. 이러한 중간에 하나라도 조건에 부합하지 않는다면 바로 실패구문으로 넘어가게 된다. 그리고 이러한 구문을 모두 거친 뒤에서야 비교문이 나오게 된다.



풀이


위의 많은 조건들을 통과하면 아래와 같이 Create_Serial()을 호출하는 부분을 발견할 수가 있다. 이 부분에서 바로 Name에 따른 Key 값이 형성이 된다.


우선 Name을 1111로 입력하였을 경우 Name이 총 16글자로 맞추어 지는 것을 확인 할 수가 있다. 그렇게 형성된 16글자를 가지고 "NH KeyGenMe6"와 함께 한 글자씩 ADD 연산을 통하여 연산을 진행한 후에 생기는 값들을 통하여 최종적으로 키 값을 형성한다.


이러한 루프를 모두 거치면 아래와 같이 007F0079...등 많은 숫자들이 있다. 하지만 여기서 키 값에 사용되는 것은 바로 앞의 12글자이다. 따라서 우리가 필요한 글자는 3글자이며 나머지는 모두 무시된다는 것을 확인할 수가 있다.

하지만 그렇다해서 Name을 3자리만 입력하라는 것은 아니다. Create_Serial()로 오기 이전의 조건문에 의하여 name의 수는 4의 배수여야하는 것 같다.


아래는 Name 을 1234로 했을 경우에 구하는 소스이다. 이제 이렇게 구했으므로 우리는 역으로 뺄셈을 통하여 쉽게 답을 찾을 수가 있다.


Create_Serial()을 통과한 후에 lStrCmp()를 통하여 내가 입력한 시리얼과 Name에 따른 KEY값이 비교되는 것을 확인 할 수가 있다.



따라서 우리는 3글자만 알면되기에 아래와 같이 3글자를 채워주고 마지막 한글자는 아무거나로 채우면 성공문을 확인 할 수가 있을 것이다.


'Reversing > CodeEngn' 카테고리의 다른 글

CodeEngn Advance 02  (0) 2015.07.30
CodeEngn Advance 15  (0) 2015.07.30
CodeEngn Advance 12  (1) 2015.07.22
CodeEngn Advance 11  (0) 2015.07.17
CodeEngn Advance 10  (0) 2015.07.13

문제확인


이번문제는 참 오래걸렸다. VB 특성상 MSVBVM60.DLL에 의하여 동작이 되기 때문에 개인적으로 다른 것에 비하여 분석하기가 까다로웠다. 





풀이


우선 시작부터 너무나 많이 왔다갔다하기때문에 중요한 부분만 사진으로 보겠다. 아래의 사진을 보면 ABCD를 입력하였을 경우 그에 해당하는 10진수의 값을 하나하나 주소에 적는 과정을 나타내고 있다. 이렇게 입력한 Name에 따라서 기록이 된다.


그렇게 입력된 값을 가지고 우리는 Value[5:9] 의 값이 밑에 rtcMidCharBstr에 의하여 4글자만 가지고 올 수 있게 된다. 밑에선 65666768에서 6768이 바로 그 값이 된다. 이 값은 나중에 시리얼에서 가운데 부분을 구성하게 된다.


위에서 나온 값을 가지고 아래의 부분에서 Loop가 진행이 된다. 한글자씩 가지고 연산을 하는 것이다. 이에 대한 설명은 예를 들어서 4949 일경우에 python으로 코드가 출력되게 한것이다.

자세히 보면 Loop후에 NEG EDX가 나오는데 이로 인하여 0-value를 하므로 인하여 우리가 원하는 값을 얻을 수가 있다.


그리고 이 밑에 부분이 가장 중요한 부분이라고 할 수 있다. 실제로 분석을 하다보면 너무 많은 분기문으로 인하여 지치게 된다. 그래서 저도 정말 많이 포기하고 싶었습니다.. 그래서 치트엔진, VB Decompiler, IDA 까지 동원하여 최대한 찾기위해 노력하였습니다. 

항상 어떤 중요한 변동이 있을떄마다 바로 이 부분을 지났기때문이다. 주석 또한 정말 위에도 강조하고 아래에서도 강조하게 된것은 한번만이 아니라 저 부분에서 핵심적으로 동작이 이루어지기 떄문이다.


이제 계속 실행을 하다보면 레지스터에 아래와 같이 정렬이 되며 E590는 위에서 연산을 통해 나온 가운데 시리얼 값이다.  추가적으로 실행하다보면 두번쨰 사진과 같이 한 글자가 사라지기도 하고 계속 이런식으로 변동이 이루어진다.


그리고 이 밑에 부분은 시리얼의 맨 앞자리 값을 결정 짓게해주는 부분이다. 어찌보면 가장 중요한 부분인데 fld fcom 등등 모르는 부분이 너무 많았다... 확실한 것은 저 부분에 들어가기 전에 모든 ECX에 5가 존재하고 그 5에 30을 더하여 EAX로 옮기는 것 같다. 


위를 통하여 14라는 숫자가 나온다. 거기에 6768-E590에서 맨 앞자리를 지우고 14를 앞에 붙여준다. 이렇게 해서 첫번째 시리얼 부분이 형성이 된 것이다. 참고로 여기서 5번째 글자를 없애면 된다.

그리고 마지막 부분의 시리얼 값은 맨 앞자리의 '1'의 10진수 값인 '49'가 나온다.

그리고 그 뒤에 0을 붙이고 맨 마지막 자리는 Len(name)+5의 값으로 형성이 된다.

이렇게 해서 ABCD일 경우의 Serial은 아래와 같다.

아래의 사진은 AAAA로 했을 경우의 성공문이다.



느낀점


이번 문제를 풀면서 정말 많은 자괴감에 빠져버렸다. 아무리 찾아도 찾아도 나오지가 않기에 리버싱이 내 적성이 아닌가 싶기도 느낄 정도였다. 이번문제의 답을 구하긴 했지만 이것도 완벽한 분석으로 구한 것이 아니다. 가운데 시리얼을 통해서 'od'라는 글자가 나왔을때 왠지 CodeEngn일거 같아서 한건데 성공해버렸다. 

그래서 다른 블로그를 참고하면서까지 이번문제를 풀었다. 정말 문제를 풀었으면 보통 기뻐야하는데 기분이 찝찝하다...다음엔 더 열공해서 풀 수 있길..ㅠㅠ


'Reversing > CodeEngn' 카테고리의 다른 글

CodeEngn Advance 15  (0) 2015.07.30
CodeEngn Advance 14  (0) 2015.07.24
CodeEngn Advance 11  (0) 2015.07.17
CodeEngn Advance 10  (0) 2015.07.13
CodeEngn Advance 09  (0) 2015.07.12

문제확인





확인




Name에 따른 시리얼이 형성되는 부분은 쉽게 찾을 수가 있다. 내가 입력한 name은 0000 serial은 11111111로 입력하였을때 아래와 같이 시러일이 비교되는 부분이 있다. 그리고 그 위에 이러한 키 값이 형성되는 부분이 존재 한다. 



위에 있는 덤프창에 드래그 해 놓은 부분이 바로 키 값 형성에서 if 문을 결정짓게 해주는 요소들이다. 그리고 아래의 사진은 수많은 if문들이 존재한다. 실제로는 16~20개의 if 문이 존재한다. 하지만 여기서부터 문제가 시작되었다. 

이번문제의 가장 큰 시사점은 작은 그림이 아니라 큰 그림을 보아야 한다는 것이다. 저러한 if문들을 계속 하나하나 따라가다보면 정말 미궁으로 빠져버린다. 본인은 미궁에서 2일을 소비했다...

바로 위의 if문을 보는 것이 아니라 아래와 같이 Dump를 지속적으로 확인해주어야 한다. 402538의 부분을 보면서 계속 진행을 하다보면 아래와 같이 3B10  31  6D  64  38 이 존재하고 있는 것을 확인 할 수가 있다. 여기서 31은 내가 입력한 serial인 ('1111')의 한 글자이다. 


위와 같이 셋팅이 된후에는 바로 연산이 진행된다. 3B10  +  31*(64+38)과 같은 식으로 진행이 된다. 그렇게 나온 값이 Sum = CF1BC이다. 이제 이와같이 이러한 연산이 key[]에 있는 모든 배열들을 순차적으로 더할 때까지 반복이 된다.

그렇게 해서 나온 값이 바로 sum = 3315C0이다. 이제 이 값을 가지고 다른 연산이 진행이 된다. 바로 F로 나누는 것이다.


F로 나눈 후에 3315C0 / F = 367D9 ... 9가 남는다.

이제 이 9에 0x30을 더 해준 후에 키 값으로 올려버린다.

그리고 남아있던 367D9에는 2를 곱하여 준다.

이렇게 더이상 F로 나누어 질 수 없을 때 까지 반복이 된다.

하지만 계속 반복이 되는 중에 만약 나머지가 0x3A~0x40일 경 밑에 2번쨰 처럼 '0~9,A~Z'가 아닌 특수문자가 나오게 되는데 이를 방지하기 위하여 A~E가 나머지로 나올 경우 +8을 해준다.


이렇게 계속 반복을 하다가 더이상 F로 나눌 수 없는 값이 될때까지 반복을 한 후에 마지막 나머지 또한 key값으로 보낸다.

위에 말이 너무 복잡하게 설명이 되어있는데 코드로 본다면 아래와 같이 간결하게 나열이 된다.




풀이


위에서 구한 방법을 통하여 94E7DB1B를 뒤에서 부터 다시 올라오면 된다. 그렇게 되면 D2A734이 나오는데 이는 맨 처음의 SUM 값인 0X3B10이 더해져있는 값이다. 따라서 KEY[]를 구하는 방법은 KEY[] = (D2A734 - 3B10) / 426C 이다. 이제 이렇게 나온 값은 0x32B이며 KEY[]의 모든 ASCII의 조합이 이렇게 나오면 된다는 것이다.

정답은 많은 경우의 수가 존재하므로 그 중에서 하나를 골라서 게시판에 비공개로 올리면 정답으로 처리가 될 것이다.


'Reversing > CodeEngn' 카테고리의 다른 글

CodeEngn Advance 14  (0) 2015.07.24
CodeEngn Advance 12  (1) 2015.07.22
CodeEngn Advance 10  (0) 2015.07.13
CodeEngn Advance 09  (0) 2015.07.12
CodeEngn Advance 08  (50) 2015.07.01

Error:

Visual Studio 2013

Class not registered. Looking for object with CLSID: {3B6A8A95-60A9-4EFC-AB17-DD892979B105}. 


Solution:

CMD<admin>

cd C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE

devenv.exe /setup




'Programming > C' 카테고리의 다른 글

[C & C++] Search a file - 파일 탐색  (0) 2016.08.24
C 언어 정리  (0) 2015.08.16
getaddr.c  (0) 2015.05.06
EggShell.c  (0) 2015.05.06
MsgBox.dll  (1) 2015.03.22

제 확인







기초 확인



위의 사진은 주석과 같이 name을 입력 받고 name의 길이를 확인 하는 과정입니다.


이번에는 Serial을 입력받고 그 길이를 확인하는 과정입니다. 길이는 12글자여야 합니다.


참고로 이 접어놓은 부분은 문제의 의도를 잘못파악하고 단순노동을 작업하였다. 매우 삽질스러우니 한가할떄만 열어보자.



분석


IDA를 통하여 HEX-Ray 기능을 통하여 성공 구문이 있는 곳을 확인 하였을때, 아래와 같이 check_serial 이라는 부분이 있는 것을 확인 할 수가 있다. 정말 누가 봐도 저곳을 확인해달라는 말인 것을 알 수가 있다.


Check_Serial() 내부로 들어오면 아래와 같이 확인을 할 수가 있는데, 여기서 확인을 해야 할 것은 붉게 표시한 3곳을 잘 보아야한다. stringFindSecond 함수를 두번 호출하고 그 반환 값들의 차를 구하여 그 값이 5가 넘지 않을 경우에 v28 에 0을 준다는 것이다. 이게 구체적으로 어떻게 생각해야 하는지는 아래에서 설명하겠다.


위의 부분이 바로 ida를 통하여 붉게 표시했던 3곳이다. 여기서 보아야 할 것은 첫번쨰 함수를 호출하기 전에 내가 입력한 serial 값의 한글자를 가져오는 작업이 이루어졌고, 두번째 호출을 하기 전에는 입력한 Name의 한글자를 가져오는 것을 확인 할 수가 있었다. 아래의 사진과 같이 설명을 하겠다.

만약 Name = 1111  serial = 000000000000 일경우를 생각해보자. 여기서 위의 순서대로 우선 serial 한글자인 0을 가지고 온다. 이 0을 첫번째 strFindSecond()를 통하여 호출을 하였을 경우 아래에 있는 키 순서값들중에서 0이 나올때까지 계속해서 한글자씩을 보낸다. 25번째에 '0'이라는 값이 있다. 

이번엔 두번쨰 호출에서 name의 한글자인 1을 생각해보자. 1의 경우는 30번쨰에 위치를 하고 있다. 이 둘의 범위는 5를 초과하지 않으므로 성공문이 출력이 된다. 이처럼 결국 name 1을 기준으로 한다면 '1'이 30번쨰이니 25~35번째 까지의 모든 단어가 성공문을 출력할 수 있게 해준다. 이것이 바로 CMP EAX, 5를 확인하는 이유이다. 

이제 키 값이 어떻게 형성되는지 확인 했으니 프로그래밍을 해보자.

'A.J.X.G.R.F.V.6.B.K.O.W.3.Y.9.T.M.4.S.2.Z.U. .I.7.0.H.5.Q.8.1.P.D.E.C.L.N'



프로그래밍



코드에 대한 설명은 주석에 구체적으로 해놓았다.


참고로 여기서 출력 되는 J - 'A'의 경우 위에 주석에서는 써놓았지만 a-z를 하면 소문자로 치환하고 해서 번거로우므로 그냥 대문자 자체로 출력되도록 하였다. 따라서 저기서 'A'는 'a'라고 생각하면 된다.

p.s 2일에 걸쳐서 삽질을하여 풀었다가, 우연히 카페에서 이 문제를 다시보는데 문득 생각이 들어서 풀 수가 있었다. 고로 리버싱문제는 인내를 갖고 여러 방면으로 생각을 해봐야 문제를 쉽게 풀 수 있을 것 같다.

10_Find_Key.py


'Reversing > CodeEngn' 카테고리의 다른 글

CodeEngn Advance 12  (1) 2015.07.22
CodeEngn Advance 11  (0) 2015.07.17
CodeEngn Advance 09  (0) 2015.07.12
CodeEngn Advance 08  (50) 2015.07.01
CodeEngn Advance 06  (0) 2015.06.28

문제 확인


문제를 확인해보면 참 설명이 간단하게 나와있다. Password는 무엇인가?이다. 그렇다면 시리얼값을 구하는 것일까했지만 여기서 문제는 우리가 직접 ID까지 알아내야한다는 것이다. 프로그램을 바로 실행시키면 아이디로 무엇을 입력해야할지 당황스럽다. 


하지만 막상 디버거로 프로그램을 열면 바로 덤프 창에 This is the Username : DonaldDucK 이라고 적혀있는 것을 볼 수가 있다. 이것이 바로 우리의 ID 값이다. p.s 사실 굳이 이것을 발견하지 못해도 이후에 DonaldDuck과의 문자를 비교하는 Loop 구간이 있기에 처음에 발견하지 못하더라도 나중에 발견할 수가 있을 것이다.




풀이



우선 프로그램을 진행하다보면 위와 같이 내가 입력한 키값 123 (0x7B)와 실제 값인 0x88228F를 비교하는 것을 확인 할 수가 이다. 그리고 조금 더 밑에는 주석에서와 같이 DonaldDuck인지를 비교하는 Loop 구간을 확인 할 수가 있다.

키 값을 알았지만 자꾸 실패문이 뜨는 것을 확인 할 수가 있었다. 이는 성공문을 출력하기 위해서는 우리가 패치를 해야한다는 것이다. 이러한 패치는 2가지 과정으로 이루어 질 것이다. 성공구문 근처에서 틀린 키값을 가지고 수정을 하는 과정과 옳은 키 값을 가지고 수정을 하는 과정이다. 


이와 같이 틀린 키 값을 가지고 프로그램을 진행하기 위해서는 2번의 명령어를 수정해야한다. 이를 통하여 우리는 틀린 키 값으로도 성공문을 확인 할 수가 있게 되었다. 


이번에는 옳은 키값을 가지고 수정을 하였다. 이번에는 한가지의 명령어만 수정을 하면 되었다. 그렇다는 것은 바로 저 부분만 고치면 옳은 키값을 넣을 경우에는 성공문으로 가게 되고 틀린 키 값을 넣으면 실패문이 출력되도록 할 수가 있다.




키 값 찾기



CMP EAX, PTR DS:[ECX] 에서 EAX에는 우리가 입력한 값이 전달되고 PTR 부분에 키 값이 저장되어 있다. 하지만 이 PTR의 주소는 실행을 할 때마다 다른곳에 위치하고 있다는 것을 확인 할 수가 있었다. 그렇다면 이는 어떠한 것 떄문에 그런지 확인을 해보자.


바로 위의 사진에서와 보듯이 우리는 MOV DWORD PTR DS:[BC4404],EAX를 통하여 BC4404의 주소에 키 값이 저장된 공간의 위치가 전달 되는 것을 확인 할 수가 있다. 이러한 키 값이 있는 곳의 주소는 VirtualAlloc 를 통하여 형성이 된다.  VirtualAlloc를 통하여 할당된 주소를 EAX에 반환하고 그 값에 ADD EAX,2A0를 통하여 최종적으로 전달할 공간의 주소를 형성한다.


위의 사진을 보자. Address 파라미터의 값이 NULL일 경우 시스템이 주소를 결정한다는 것이다. 바로 이것이 키 값이 저장된 위치가 실행할때마다 변화했던 이유이다.


앞에서 확인 했던 것과 같이 키 값이 있는 곳의 주소는 00BC4404에 기록이 된다. 저 해당 주소로 가면 우리가 성공문을 출력하는데 필요한 키 값이 위치하여 있다. 추가적으로 아래의 사진은 이번 문제를 삽질할때 보았던 Flag Register에 관해 짧게 써있는 것이다. 


'Reversing > CodeEngn' 카테고리의 다른 글

CodeEngn Advance 11  (0) 2015.07.17
CodeEngn Advance 10  (0) 2015.07.13
CodeEngn Advance 08  (50) 2015.07.01
CodeEngn Advance 06  (0) 2015.06.28
CodeEngn Advance 05  (0) 2015.06.28