[Grupo Dragón Azul de la Copa Wangding 2020] singal
paso
- Inspección de rutina, programa de 32 bits, sin shell
- Prueba el programa localmente
- Se carga ida de 32 bits. Primero, busque la función principal y determine el estilo de la cadena de indicadores. Indicador {……}
De acuerdo con la cadena de solicitud del punto de entrada, busque la función correspondiente y confirme que la longitud de la cadena es 15
haga clic derecho en la función y busque la llamada El lugar de esta función llega a la función vm_operad (). Mire la función principal para saber que el parámetro v4 en vm_operad llama a la función qmemcpy en la línea superior. Baidu dice que qmemcpy = memcpy en la dirección inversa es la función de copia de memcpy en el lenguaje C., Copie 0x1C8 bytes de datos en unk_403040 a v4
unk_403040 Esta dirección tiene una gran cantidad de datos copia 0x1C8 se
selecciona a 0x403208 , shift + e se convierte en una matriz de
4 bytes igual a un int, el procesador interl es almacenamiento little-endian, justo El valor de la matriz a1 es el número hexadecimal antes de los tres 00. Para ordenarlo,
v4=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1]
preste atención al orden little-endian cuando el 32 -El programa de bits está almacenado. No invertiré el orden. Busquemos el procesamiento en la memoria. Algunos datos en ese momento
Luego llame a la matriz y 114 ingrese la función vm_operad
int __cdecl vm_operad(int *a1, int _114)
{
int result; // eax
char Str[200]; // [esp+13h] [ebp-E5h] BYREF
char v4; // [esp+DBh] [ebp-1Dh]
int v5; // [esp+DCh] [ebp-1Ch]
int v6; // [esp+E0h] [ebp-18h]
int v7; // [esp+E4h] [ebp-14h]
int v8; // [esp+E8h] [ebp-10h]
int v9; // [esp+ECh] [ebp-Ch]
v9 = 0;
v8 = 0;
v7 = 0;
v6 = 0;
v5 = 0;
while ( 1 )
{
result = v9;
if ( v9 >= _114 )
return result;
switch ( a1[v9] )
{
case 1:
Str[v6 + 100] = v4;
++v9;
++v6;
++v8;
break;
case 2:
v4 = a1[v9 + 1] + Str[v8];
v9 += 2;
break;
case 3:
v4 = Str[v8] - LOBYTE(a1[v9 + 1]);
v9 += 2;
break;
case 4:
v4 = a1[v9 + 1] ^ Str[v8];
v9 += 2;
break;
case 5:
v4 = a1[v9 + 1] * Str[v8];
v9 += 2;
break;
case 6:
++v9;
break;
case 7:
if ( Str[v7 + 100] != a1[v9 + 1] )
{
printf("what a shame...");
exit(0);
}
++v7;
v9 += 2;
break;
case 8:
Str[v5] = v4;
++v9;
++v5;
break;
case 10:
read(Str);
++v9;
break;
case 11:
v4 = Str[v8] - 1;
++v9;
break;
case 12:
v4 = Str[v8] + 1;
++v9;
break;
default:
continue;
}
}
}
Cuando el valor es igual a 7, el valor de la matriz str se comparará con el siguiente bit de la matriz a1 y la igualdad continuará sin esperar un error. El número después de 7 es el valor que debe compararse con la entrada correcta después del cifrado, solo el valor de 7 está al final de la matriz a1, extraiga esta cadena de valores
str=[]
a1=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1, 7, 34, 7, 63, 7, 52, 7, 50, 7, 114, 7, 51, 7, 24, 7, 167, 255, 255, 255, 7, 49, 7, 241, 255, 255, 255, 7, 40, 7, 132, 255, 255, 255, 7, 193, 255, 255, 255, 7, 30, 7, 122]
for i in range(0,len(a1)):
if a1[i]==7:
str.append(a1[i+1])
print(a1)
str = [34, 63, 52, 50, 114, 51, 24, 167, 49, 241, 40, 132, 193, 30, 122]
Luego, las otras opciones de caso en switch son operaciones en la matriz str, y finalmente obtienen El valor en str, el algoritmo inverso para resolver
Hay una función llamada LOBYTE en él. Cuando lo hice, fui a Baidu. Algunos dijeron que era la más a la derecha y otros dijeron que los cuatro dígitos de la derecha. No hay una declaración unificada. Encontré el wp de otros maestros y dijo que esta es una función de ida. Ignore esta función. rax es un registro de 64 bits, eax es un registro de 32 bits, ax es un registro de 16 bits, al son los 8 bits inferiores del registro ax y ah son los 8 bits superiores del registro ax.
a1=[]
v4=[10, 4, 16, 8, 3, 5, 1, 4, 32, 8, 5, 3, 1, 3, 2, 8, 11, 1, 12, 8, 4, 4, 1, 5, 3, 8, 3, 33, 1, 11, 8, 11, 1, 4, 9, 8, 3, 32, 1, 2, 81, 8, 4, 36, 1, 12, 8, 11, 1, 5, 2, 8, 2, 37, 1, 2, 54, 8, 4, 65, 1, 2, 32, 8, 5, 1, 1, 5, 3, 8, 2, 37, 1, 4, 9, 8, 3, 32, 1, 2, 65, 8, 12, 1, 7, 34, 7, 63, 7, 52, 7, 50, 7, 114, 7, 51, 7, 24, 7, 167, 255, 255, 255, 7, 49, 7, 241, 255, 255, 255, 7, 40, 7, 132, 255, 255, 255, 7, 193, 255, 255, 255, 7, 30, 7, 122]
for i in range(0,len(v4)):
if v4[i]==7:
a1.append(v4[i+1])
#print(a1)
a1 = [34, 63, 52, 50, 114, 51, 24, 167, 49, 241, 40, 132, 193, 30, 122]
a1.reverse()
v4.reverse()
v9 = 0
us = 0
v5 = 0
flag = []
for i in range(0, len(v4)):
if i == len(v4) - 1:
flag.append(us)
if v4[i] == 1 and v4[i - 1] != 1:
v5 = a1[v9]
v9 += 1
flag.append(us)
if v4[i] == 2:
if (v4[i + 1] != 3 and v4[i + 1] != 4 and v4[i + 1] != 5):
us = v5 - v4[i - 1]
# print(us,v5,a[i-1])
if v4[i] == 3:
if (v4[i + 1] != 2 and v4[i + 1] != 4 and v4[i + 1] != 5):
us = v5 + v4[i - 1] # LOBYTE是al有8位,参与运算的5、33、32是全值,所以LOBYTE可省略
if v4[i] == 4:
if (v4[i + 1] != 3 and v4[i + 1] != 2 and v4[i + 1] != 5):
us = v5 ^ v4[i - 1]
if v4[i] == 5:
if (v4[i + 1] != 3 and v4[i + 1] != 4 and v4[i + 1] != 2):
us = int(v5 / v4[i - 1])
if v4[i] == 8:
v5 = us
if v4[i] == 11:
us = v5 + 1
if v4[i] == 12:
us = v5 - 1
# print("12:",us)
flag.reverse()
out = ''
for j in flag:
out += chr(j)
print("flag{" + out + "}")
bandera {757515121f3d478}