picoCTF - asm2 write up

source: https://play.picoctf.org/practice/challenge/16?category=3&page=1

Problem

Description
What does asm2(0xb,0x2e) return? Submit the flag as a hexadecimal value (starting with '0x'). NOTE: Your submission for this question will NOT be in the normal flag format.

asm2:
<+0>:    push   ebp
<+1>:    mov    ebp,esp
<+3>:    sub    esp,0x10
<+6>:    mov    eax,DWORD PTR [ebp+0xc]
<+9>:    mov    DWORD PTR [ebp-0x4],eax
<+12>:    mov    eax,DWORD PTR [ebp+0x8]
<+15>:    mov    DWORD PTR [ebp-0x8],eax
<+18>:    jmp    0x509 <asm2+28>
<+20>:    add    DWORD PTR [ebp-0x4],0x1
<+24>:    sub    DWORD PTR [ebp-0x8],0xffffff80
<+28>:    cmp    DWORD PTR [ebp-0x8],0x63f3
<+35>:    jle    0x501 <asm2+20>
<+37>:    mov    eax,DWORD PTR [ebp-0x4]
<+40>:    leave  
<+41>:    ret    

Solution

[ebp-0x4] was assigned [ebp+0xc], [ebp+0xc] was assigned 0x2e
[ebp-0x8] was assigned [ebp+0x8], [ebp+0x8] was assigned 0xb
After analysis of the codes, I found that it is actually a while loop.
it could be written in java in the following code

static int ams2(int a, int b)
{
    int c = a;
    int d = b;
    while(c <= 25587)
    {
        d++;
        c+=128;
    }
    return d;
}

a = [ebp+0x8]
b = [ebp+0xc]
c = [ebp-0x8]
d = [ebp-0x4]

0xffffff80 = "-0x80" b/c 0xffffff80 xor 0xffffffff + 0 x 1 = 0x80

So, the Flag is "0xf6"

Intel文档中关于VT的重要部分索引

以下采用的文档为

Intel® 64 and IA-32 Architectures
Software Developer’s Manual

Combined Volumes:
1, 2A, 2B, 2C, 2D, 3A, 3B, 3C, 3D and 4

Order Number: 325462-072US

May 2020

讨论的是32位cpu

vmread 和 vmwrite 指令

vmread:读取当前VMCS中的数据
vmwrite:向当前VMCS中写入数据

指令说明

vmread在4113页(Vol.3C 30-21)
vmwrite在4116页(Vol.3C 30-24)

用法

以vmread举例
vmread r/m32,r32
operand 1 为 field
operand 2 为 value
field的值可以在4517页查阅(Vol.3D B-1)

rdmsr 和 wrmsr 指令

rdmsr:读模式定义寄存器(msr)
wrmsr:写模式定义寄存器(msr)

指令说明

rdmsr在1708页(Vol.2B 4-534)
wrmsr在2482页(Vol.2C 5-586)

用法

ecx中写入MSR的地址
rdmsr:返回相应的MSR 中64bit信息到(EDX:EAX)寄存器中
wrmsr:把要写入的信息存入(EDX:EAX)中,执行写指令后,即可将相应的信息存入ECX指定的MSR中。
MSR的地址可以在4551页查阅(Vol.4 2-3)

TEB和PEB

以下讨论的是32位系统win

TEB

线程环境块
每一个线程都有一个TEB
在应用层而不是系统层中

线性地址

一个进程又很多线程,每一个线程又都有一个TEB,这些TEB都在进程的0x7FFDE000的线性内存处开始,每4KB为一个TEB

查看TEB结构

不同的windows版本种TEB结构会不同
TEB结构的开头是个NT_TIB结构,这个结构的0x018是个指向NT_TIB自己的指针

通过段寄存器访问TEB

FS段寄存器指向当前线程的TEB,所以fs:[18h]就是TEB的指针

mov eax,dword ptr fs:[18h]

eax就是TEB的指针

PEB

进程环境块
每个进程有一个PEB
在应用层而不是系统层中

通过段寄存器访问PEB

由于TEB中的0x30偏移处是指向PEB的指针,可以直接通过fs:[30h]获得PEB的指针

mov eax,dword ptr fs:[30h]

eax就是PEB的指针

通过BeingDebugged进行反调试

PEB结构中有一个BeingDebugged字段,当进程被调试时会变成1,否则为0,这个字段可用于反调试
更多反调试方法专门再写一篇进行总结