hctf 2018

周末队里的几个小伙伴抽空打了下今年的HCTF,最后排在第十名。以下是WP

Bin

seven

给了一个.sys系统驱动,ida依次点开几个函数,在sub_1400012F0中看到一段可疑代码:

__int64 __fastcall sub_1400012F0(__int64 a1, __int64 a2)
{
  __int64 v2; // rbx
  __int64 v3; // rsi
  unsigned __int64 v4; // rdx
  int p; // ecx
  __int16 *p_input; // rdi
  __int64 time; // rbp
  __int16 input; // dx
  char map_content; // dl
  CHAR *info; // rcx

  v2 = a2;
  if ( *(_DWORD *)(a2 + 48) >= 0 )
  {
    v3 = *(_QWORD *)(a2 + 24);
    v4 = (unsigned __int64)(*(unsigned __int64 *)(a2 + 56) * (unsigned __int128)0xAAAAAAAAAAAAAAABui64 >> 64) >> 3;
    if ( (_DWORD)v4 )
    {
      p = saved_p;
      p_input = (__int16 *)(v3 + 2);
      time = (unsigned int)v4;
      while ( *(_WORD *)(v3 + 4) )
      {
LABEL_30:
        p_input += 6;
        if ( !--time )
          goto LABEL_31;
      }
      map[p] = '.';
      input = *p_input;
      if ( *p_input == 0x11 )
      {
        if ( p & 0xFFFFFFF0 )
        {
          p -= 16;
          goto LABEL_13;
        }
        p += 0xD0;
        saved_p = p;
      }
      if ( input != 0x1F )
        goto LABEL_14;
      if ( (p & 0xFFFFFFF0) == 0xD0 )
        p -= 0xD0;
      else
        p += 16;
LABEL_13:
      saved_p = p;
LABEL_14:
      if ( input == 0x1E )
      {
        if ( p & 0xF )
          --p;
        else
          p += 15;
        saved_p = p;
      }
      if ( input == 0x20 )
      {
        if ( (p & 0xF) == 15 )
          p -= 15;
        else
          ++p;
        saved_p = p;
      }
      map_content = map[p];
      if ( map_content == '*' )
      {
        info = "-1s\n";
      }
      else
      {
        if ( map_content != '7' )
        {
LABEL_29:
          map[p] = 'o';
          goto LABEL_30;
        }
        info = "The input is the flag!\n";
      }
      saved_p = 16;
      DbgPrint(info);
      p = saved_p;
      goto LABEL_29;
    }
  }
LABEL_31:
  if ( *(_BYTE *)(v2 + 65) )
    *(_BYTE *)(*(_QWORD *)(v2 + 184) + 3i64) |= 1u;
  return *(unsigned int *)(v2 + 48);
}

可以看出这是一个走迷宫游戏,迷宫可以在data段中找到:

****************
o..............*
**************.*
************...*
***********..***
**********..****
*********..*****
********..******
*******..*******
******..********
*****..*********
****..**********
****7***********
****************

从代码中看出上左下右分别对应0x11,0x1e,0x1f,0x20,搜索得到系统驱动中各个按键对应的值,即wasd,根据题目描述使用小写,得到flag:hctf{ddddddddddddddssaasasasasasasasasas}

Lucky star

运行程序,输出了LuckyStar!,IDAshift+f12找字符串引用发现在TlsCallback_0中。

关于TlsCallback,只需要知道它会在程序运行之前被执行就行了。

TlsCallback开头做了一段奇怪的哈希检查,然后有一段检测进程的反调:

do
    {
      v9 = 0;
      do
      {
        if ( !lstrcmpW(off_403508[v9], v8[15]) )
          goto LABEL_13;
        ++v9;
      }
      while ( v9 < 6 );
      v8 = (LPCWSTR *)((char *)v8 + (_DWORD)*v8);
    }
    while ( *v8 );

其中off_403508中有ida,ollydbg等,随便改掉(hex view f12修改,然后edit-patch program-apply...,也可以010直接改)。

这时可以先运行程序看看,大体就是等一段时间,然后就是常规的flag check,于是我们可以继续看代码逻辑。

后面一段代码,根据一个固定种子,生成随机数来异或脱壳一个函数401780

srand(0x61616161u);
v11 = (char *)&loc_401780;
v12 = 0x1B8;
do
{
  ++v11;
  result = byte_417000[rand() % 8216];
  *(v11 - 1) ^= result;
  --v12;
}
while ( v12 );

可以自己写程序脱壳,更简单的是直接运行程序然后dump内存(任务管理器右键创建转储文件即可),即可得到脱壳后的函数(直接搜索附近的hex可以直接定位)

观察sub_401780,发现它又异或脱壳了一个函数:

do
    *((_BYTE *)sub_4015E0 + v1++) ^= byte_417000[rand() % 8216];
  while ( v1 < 383 );

同样从刚才的dump中找到函数(直接覆盖原exe的函数用ida看即可)。

可以看出,我们的输入通过sub_4015E0函数加密,然后与一个data值做比较。

于是观察sub_4015E0函数,根据==*4/3,和一些标志性的位运算可以猜测前面的一段是base64 encode

len = strlen(flag);
  v4 = 0;
  v20 = 4 * len / 3;
  if ( v20 > 0 )
  {
    do
    {
      v5 = v4 & 3;
      if ( v4 & 3 )
      {
        v8 = flag[v2 - 1];
        if ( v5 == 1 )
        {
          v9 = flag[v2++];
          v7 = (v9 >> 4) | 16 * (v8 & 3);
        }
        else if ( v5 == 2 )
        {
          v10 = flag[v2++];
          v7 = (v10 >> 6) | 4 * (v8 & 0xF);
        }
        else
        {
          v7 = v8 & 0x3F;
        }
      }
      else
      {
        v6 = &flag[v2++];
        v7 = *v6 >> 2;
      }
      enc[v4++] = base64[v7];
    }
    while ( v4 < v20 );
  }
  if ( strlen(flag) % 3 == 1 )
  {
    v11 = 4 * len / 3;
    v12 = 16 * (flag[v2 - 1] & 3);
    *(_WORD *)&enc[v20 + 1] = '==';
    v13 = base64[v12];
  }
  else
  {
    if ( strlen(flag) % 3 != 2 )
      goto LABEL_15;
    v11 = 4 * len / 3;
    v13 = base64[4 * (flag[v2 - 1] & 0xF)];
    enc[v20 + 1] = '=';
  }
  enc[v11] = v13;
LABEL_15:
  enc[strlen(enc)] = 0;

但是码表与常规base64不同:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/

接下来程序又生成随机数异或了base64编码的输入:

if ( base64_len > 0 )
{
do
{
  v16 = 6;
  do
  {
    v17 = rand() % 4;
    v18 = v16;
    v16 -= 2;
    xor_key = (_BYTE)v17 << v18;
    enc[p] ^= xor_key;
  }
  while ( v16 > -2 );
  ++p;
}
while ( p < base64_len );
}

同样,随机数可以写程序得到,但是我写出来总是不对,于是同样地dump内存:

在程序中输入24个w(因为最终比较的串是32位,所以base64前是24位),在程序结束前会system(‘pause’),这时加密值还在栈上,同时栈上也有那串data49e6...,搜索这个可以在附近找到加密后的输入。

用它与24个w的base64进行异或得到一串随机数,再跟那串data异或即可还原出flag的base64,base64 decode得到flag。(注意base64是自定义码表)

from string import maketrans

base='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
diy_base='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/'
t=maketrans(base,diy_base)
t2=maketrans(diy_base, base)

def cus_base64_enc(x):
    return x.encode('base64').translate(t)

def cus_base64_dec(x):
    return x.translate(t2).decode('base64')

ss=[0x4c,0xb2,0x7d,0xbe,0x04,0x3a,0x06,0x27,0x94,0xc1,0xdc,0x55,0x77,0xe5,0x8d,0x81,0x85,0xa6,0xf2,0x2d,0x83,0x1e,0x58,0xdc,0x96,0x81,0x1b,0x55,0xc8,0x8a,0xb5,0x0b]
enc=[0x49, 0xE6, 0x57, 0xBD, 0x3A, 0x47, 0x11, 0x4C, 0x95, 0xBC, 0xEE, 0x32, 0x72, 0xA0, 0xF0, 0xDE, 0xAC, 0xF2, 0x83, 0x56, 0x83, 0x49, 0x6E, 0xA9, 0xA6, 0xC5, 0x67, 0x3C, 0xCA, 0xC8, 0xCC, 0x05]
inp = cus_base64_enc('w'*24)
flag=''
for i in range(32):
    flag+=chr(ss[i]^ord(inp[i])^enc[i])
print cus_base64_dec(flag)

运行得到flag:

hctf{1zumi_K0nat4_Mo3}

PolishDuck

程序给了hex,使用hex2bin可以还原出binary,首先可以看到一串字符串:
Arduino LLC Arduino Leonardo

notepad.exe44646 + ( 64094 + ( 71825 * ( ( 15873 + ( 21793 * ( 7234 + ( 17649 * ( ( 2155 + ( 74767 * ( 35392 + ( 88216 * ( 83920 + ( 16270 + ( 20151 * ( 5268 + ( 90693 * ( 82773 + ( 716 + 27377 * ( 44329 + ( 49366 * ( ( ( 38790 + ( 70247 * ( 97233 + ( 18347 + ( 22117 * ( ( ( 72576 + ( ( 47541 + ( 46975 + ( 53769 * ( 94005 + ( ( 72914 + ( 5137 + ( 87544 * 71583 + ( 20370 + ( 37968 * ( 17478 + ( ( 40532 + ( 10089 + ( 13332 * ( ( 24170 + ( 46845 * ( 16048 + 23142 * ( 31895 + ( 62386 * ( 12179 ( 94552 + ( ( ( 52918 + ( 91580 + ( ( ( 38412 + ( 91537 * ( 70 + ( 98594 * ( ( 35275 + ( 62912 * ( 4755 + ( 16737 * ( 27595 + ( ( 43551 + ( 64482 * 3550 ) ) - 21031 ) ) ) ) ) ) - 57553 ) ) - 89883 ) - 38900 ) ) ) - 19517 ) - 79082 ) ) ) ) ) ) ) ) - 70643 ) ) 55350 ) ) ) ) ) - 40301 ) ) ) ) - 83065 ) ) ) ) ) - 52460 ) ) - 49428 ) - 94686 ) ) ) ) ) ) - 1653 ) - 65217 ) ) ) - 43827 ) 66562 ) )

根据经验可以推测出是badusb,可以参考这篇文章,题目思路基本一致。

首先搜索Arduino Leonardo得到atmega32u4,用IDA Atmel AVR架构,设备设置为atmega32u4

sub_9A8函数中可以看出,程序首先通过win+r快捷键打开运行窗口,然后一直重复writeln和delay,writeln的参数r25和r24即为字符串的偏移,可以猜测出0x140即为notepad.exe的开头:

ROM:0A4E                 ldi     r22, 0x83       ; win
ROM:0A4F                 ldi     r24, 0x86
ROM:0A50                 ldi     r25, 5
ROM:0A51                 call    key_input
ROM:0A53                 ldi     r22, 0x72 ; 'r' ; r
ROM:0A54                 ldi     r24, 0x86
ROM:0A55                 ldi     r25, 5
ROM:0A56                 call    key_input
ROM:0A58                 sts     0x58C, r1
ROM:0A5A                 sts     0x58D, r1
ROM:0A5C                 sts     0x58E, r1
ROM:0A5E                 sts     0x58F, r1
ROM:0A60                 sts     0x590, r1
ROM:0A62                 sts     0x591, r1
ROM:0A64                 sts     0x58A, r1
ROM:0A66                 ldi     r22, 0x8A
ROM:0A67                 ldi     r23, 5
ROM:0A68                 ldi     r24, 0x86
ROM:0A69                 ldi     r25, 5
ROM:0A6A                 call    key_release
ROM:0A6C                 ldi     r22, 0xF4
ROM:0A6D                 ldi     r23, 1
ROM:0A6E                 ldi     r24, 0
ROM:0A6F                 ldi     r25, 0
ROM:0A70                 call    delay
ROM:0A72                 ldi     r24, 0x40 ; '@'
ROM:0A73                 ldi     r25, 1
ROM:0A74                 call    key_writeln
ROM:0A76                 ldi     r22, 0xF4
ROM:0A77                 ldi     r23, 1
ROM:0A78                 ldi     r24, 0
ROM:0A79                 ldi     r25, 0
ROM:0A7A                 call    delay
ROM:0A7C                 ldi     r24, 0x4C ; 'L'
ROM:0A7D                 ldi     r25, 1
ROM:0A7E                 call    key_writeln
ROM:0A80                 ldi     r22, 0xF4
ROM:0A81                 ldi     r23, 1
ROM:0A82                 ldi     r24, 0
ROM:0A83                 ldi     r25, 0
ROM:0A84                 call    delay

懒得写idapython脚本,直接从IDA中复制伪代码,用正则把偏移拿出来(data即为notepad开始的那串字符串):

l=[0x14C ,0x153 ,0x162 ,0x177 ,0x18B,0x1A9,0x1C8,0x1D3,0x1EB,0x1FE,0x25E ,0x207,0x21C,0x227 ,0x246 ,0x261 ,0x270 ,0x28B,0x298,0x2A3,0x2B1,0x25C ,0x2BA,0x2C5,0x2D0,0x2D7,0x2F2,0x307,0x310,0x25E ,0x327 ,0x346 ,0x3DC,0x34D ,0x364 ,0x373 ,0x38F,0x3A6,0x3B3,0x3BF,0x3D0,0x3DF,0x3EF,0x400,0x44B ,0x413,0x42C ,0x43B ,0x44F ,0x452 ,0x490,0x45F ,0x46C ,0x47D ,0x48E,0x497,0x49E,0x4B5,0x4CB,0x445 ,0x445 ,0x4D6,0x44D ,0x44D ,0x494,0x4E5,0x44F]
l=map(lambda x:x-0x140, l)
flag=''
s=open('data','rb').read()
for i in range(len(l) ):
    st = l[i]
    ed = st+1
    while ed<len(s):
        if s[ed] == '\x00':
            break
        ed+=1
    flag+=s[st:ed]
print flag

打印出来的flag是个表达式,直接python eval得到结果转hex再decode hex即可得到flag:

>>> eval('44646 + ( 64094 + ( 71825 * ( ( 15873 + ( 21793 * ( 7234 + ( 17649 * ( ( 2155 + ( 74767 * ( 35392 + ( 88216 * ( 83920 + ( 16270 + ( 20151 * ( 5268 + ( 90693 * ( 82773 + ( 716 + ( 27377 * ( 44329 + ( 49366 * ( ( ( 38790 + ( 70247 * ( 97233 + ( 18347 + ( 22117 * ( ( ( 72576 + ( ( 47541 + ( 46975 + ( 53769 * ( 94005 + ( ( 72914 + ( 5137 + ( 87544 * ( ( 71583 + ( 20370 + ( 37968 * ( 17478 + ( ( 40532 + ( 10089 + ( 13332 * ( ( 24170 + ( 46845 * ( 16048 + ( 23142 * ( 31895 + ( 62386 * ( 12179 + ( 94552 + ( ( ( 52918 + ( 91580 + ( ( ( 38412 + ( 91537 * ( 70 + ( 98594 * ( ( 35275 + ( 62912 * ( 4755 + ( 16737 * ( 27595 + ( ( 43551 + ( 64482 * 3550 ) ) - 21031 ) ) ) ) ) ) - 57553 ) ) ) ) ) - 89883 ) - 38900 ) ) ) - 19517 ) - 79082 ) ) ) ) ) ) ) ) ) - 70643 ) ) ) ) - 55350 ) ) ) ) ) - 40301 ) ) ) ) - 83065 ) ) ) ) ) - 52460 ) ) - 49428 ) - 94686 ) ) ) ) ) ) - 1653 ) - 65217 ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) - 43827 ) ) ) ) ) - 66562 ) ) )')
245160825372454180181035013425094268426669928853472000168466067114757309065141074622457247656884957267064733565L
>>> hex(245160825372454180181035013425094268426669928853472000168466067114757309065141074622457247656884957267064733565)
'0x686374667b50306c3173685f4475636b5f5461737433735f44336c3163693075735f44305f555f5468316e6b3f7dL'
>>> '686374667b50306c3173685f4475636b5f5461737433735f44336c3163693075735f44305f555f5468316e6b3f7d'.decode('hex')
'hctf{P0l1sh_Duck_Tast3s_D3l1ci0us_D0_U_Th1nk?}'

PS:题目一开始放出来的时候是另外一个奇怪的式子:

notepad.exe44646 64094 71825 66562 15873 21793 7234 17649 43827 2155 74767 35392 88216 83920 16270 20151 5268 90693 82773 716 27377 44329 49366 65217 1653 38790 70247 97233 18347 22117 94686 49428 72576 52460 47541 46975 53769 94005 83065 72914 5137 87544 40301 71583 20370 37968 17478 55350 40532 10089 13332 70643 24170 46845 16048 23142 31895 62386 12179 94552 79082 19517 52918 91580 38900 89883 38412 91537 70 98594 57553 35275 62912 4755 16737 27595 21031 43551 64482 3550 *++-+*+*++-*+*++-+-+++-+-++*+*+*++-*+++-+*+++-*+++-+*+++-++-+-*++*++-+-*+*++*+*++*+*++-*+*++-*++

根据题目名称猜测是波兰式、逆波兰式一类的,但是运算数和运算符数量匹配不起来,看了一下午没想出来。

后来与作者沟通,原来要把式子里的+-->-,然后就能解出,不过作者最后还是换成正常表达式了2333

Spiral

IDA打开,第一关判断了系统版本:

v1 = GetVersion();
  return (unsigned __int8)v1 == 5 && HIBYTE(v1) == 1;

这里我的系统版本过不了,于是直接patch掉。

下一关判断了命令行参数(即flag)长度为73,然后再sub_448726函数中对前46位做了一个check:
首先通过sub_44AFA8对flag加密,然后在sub_44F5B0与一个固定data做比较,大致就是data里面偶数位是opcode,奇数位是oprand,照着模拟一下即可得到flag的前半部分:

data0=[0x07, 0xE7, 0x07, 0xE4, 0x01, 0x19, 0x03, 0x50, 0x07, 0xE4, 0x01, 0x20, 0x06, 0xB7, 0x07, 0xE4, 0x01, 0x22, 0x00, 0x28, 0x00, 0x2A, 0x02, 0x54, 0x07, 0xE4, 0x01, 0x1F, 0x02, 0x50, 0x05, 0xF2, 0x04, 0xCC, 0x07, 0xE4, 0x00, 0x28, 0x06, 0xB3, 0x05, 0xF8, 0x07, 0xE4, 0x00, 0x28, 0x06, 0xB2, 0x07, 0xE4, 0x04, 0xC0, 0x00, 0x2F, 0x05, 0xF8, 0x07, 0xE4, 0x04, 0xC0, 0x00, 0x28, 0x05, 0xF0, 0x07, 0xE3, 0x00, 0x2B, 0x04, 0xC4, 0x05, 0xF6, 0x03, 0x4C, 0x04, 0xC0, 0x07, 0xE4, 0x05, 0xF6, 0x06, 0xB3, 0x01, 0x19, 0x07, 0xE3, 0x05, 0xF7, 0x01, 0x1F, 0x07, 0xE4]
s=''
for i in range(0, len(data0), 2):
    x = data0[i]
    x2 = data0[i+1]
    if x == 0:
        x2-=34
    if x == 1:
        x2-=19
    if x == 2:
        x2-=70
    if x == 3:
        x2-=66
    if x == 4:
        x2^=0xca
    if x == 5:
        x2^=0xfe
    if x == 6:
        x2^=0xbe
    if x == 7:
        x2^=0xef
    #print x, x2, x|((x2<<3)&0x78)
    s+=chr(x|((x2<<3)&0x78))
print s

后半部分写在一个驱动文件中,我的电脑无法直接运行,于是逆一下,发现主要逻辑从sub_403310开始,大致就是开了一个奇怪的vm(找到一个类似的题),其中sub_4030b0中的一串相当于vm code:

void vmcalls()
{
  rdmsr(0x176);
  invd(0x4433);
  vmcall(0x30133403);
  vmcall(0x3401CC01);
  vmcall(0x36327A09);
  vmcall(0x3300CC00);
  vmcall(0x3015CC04);
  vmcall(0x35289D07);
  vmcall(0x3027CC06);
  vmcall(0x3412CC03);
  vmcall(0x3026CD06);
  vmcall(0x34081F01);
  vmcall(0x3311C302);
  vmcall(0x3625CC05);
  vmcall(0x3930CC07);
  vmcall(0x37249405);
  vmcall(0x34027200);
  vmcall(0x39236B04);
  vmcall(0x34317308);
  vmcall(0x3704CC02);
  invd(0x4434);
  vmcall(0x38531F11);
  vmcall(0x3435CC09);
  vmcall(0x3842CC0A);
  vmcall(0x3538CB0B);
  vmcall(0x3750CC0D);
  vmcall(0x3641710D);
  vmcall(0x3855CC0F);
  vmcall(0x3757CC10);
  vmcall(0x3740000C);
  vmcall(0x3147010F);
  vmcall(0x3146CC0B);
  vmcall(0x3743020E);
  vmcall(0x36360F0A);
  vmcall(0x3152CC0E);
  vmcall(0x34549C12);
  vmcall(0x34511110);
  vmcall(0x3448CC0C);
  vmcall(0x3633CC08);
  invd(0x4437);
  vmcall(0x3080CC17);
  vmcall(0x37742C16);
  vmcall(0x3271CC14);
  vmcall(0x3983CC19);
  vmcall(0x3482BB17);
  vmcall(0x3567BC15);
  vmcall(0x3188041A);
  vmcall(0x3965CC12);
  vmcall(0x32869C19);
  vmcall(0x3785CC1A);
  vmcall(0x3281CC18);
  vmcall(0x3262DC14);
  vmcall(0x3573CC15);
  vmcall(0x37566613);
  vmcall(0x3161CC11);
  vmcall(0x3266CC13);
  vmcall(0x39844818);
  vmcall(0x3777CC16);
  vmcall(0xFFEEDEAD);
}

sub_402880函数是对应的解释函数:

int sub_402880()
{
  int opcode; // [esp+4h] [ebp-Ch]
  int v2; // [esp+Ch] [ebp-4h]

  opcode = vmread(0x4402);
  v2 = vmread(0x440C);
  r4 = vmread(0x681C);
  r8_ = vmread(0x681E);
  r9_ = vmread(0x6802);
  if ( !inited )
  {
    vm_init();
    inited = 1;
  }
  switch ( opcode )
  {
    case 0xA:
      mod_opcodes();
      break;
    case 0xD:
      switch_opcodes();
      break;
    case 0x12:
      vm_calc();
      break;
    case 0x1C:
      sub_4023E0();
      break;
    case 0x1F:
      sub_402190();
      break;
    case 0x20:
      write_reg_r0();
      break;
    default:
      break;
  }
  vmwrite(0x681E, v2 + r8_);
  return vmwrite(0x681C, r4);
}

虽然不知道上面几种指令对应哪个分支,不过根据参数和逻辑大体猜测vmcall对应vm_calc,invd对应switch_opcodes,rdmsr对应mod_opcodes。(函数重命名过)
可以先看vm_calc:

void vm_calc()
{
  int (*v0)(void); // ST2C_4
  unsigned int eax_; // [esp+18h] [ebp-14h]
  int idx; // [esp+28h] [ebp-4h]

  eax_ = (unsigned int)r0 >> 24;
  idx = (BYTE2(r0) & 0xF) + 9 * (((((unsigned int)r0 >> 16) & 0xFF) >> 4) & 0xF);
  if ( (unsigned __int16)r0 >> 8 == 0xCC )
    p_flag = (char *)&flag;
  else
    p_flag = (char *)&flag_rev;
  if ( eax_ == op_load_[0] )
  {
    regs_p[idx] = *(_DWORD *)&p_flag[4 * (unsigned __int8)r0];
    do_nothing(regs_p[idx], idx);
  }
  else if ( eax_ == op_add[0] )
  {
    regs_p[idx] += *(_DWORD *)&p_flag[4 * (unsigned __int8)r0];
    regs_p[idx] &= 0xFFu;
    do_nothing(regs_p[idx], idx);
  }
  else if ( eax_ == op_minus )
  {
    regs_p[idx] -= *(_DWORD *)&p_flag[4 * (unsigned __int8)r0];
    regs_p[idx] &= 0xFFu;
    do_nothing(regs_p[idx], idx);
  }
  else if ( eax_ == 

       
       
       

    

Hacking more

...