%x
可以输出一个数的十六进制一样,在使用register_printf_function
后可以将指定spec与指定转换函数绑定,从而自定义输出行为。shellcode???
和楚慧杯的scalar
两道今年做到的赛题为例将解题方法运用到实战中。自定义printf
int register_printf_function (int spec, printf_function handler-function, printf_arginfo_function arginfo-function)
register_printf_function
函数用于注册新的输出转换,需要在printf虚拟机前执行,一般为了掩人耳目会放在init
中作为初始函数表的一部分。其参数含义如下:-
spec:格式占位符。
如spec为
'A'
时,该函数注册的是%A
的输出转换。可以覆盖如%x、%s等默认spec的定义,建议一般使用大写字母以示区分。 -
handler-function:处理该spec的转换函数。
int function (FILE *stream, const struct printf_info *info, const void *const *args)
简单来说,info是在解析到spec时获取的信息结构体,如解析到
%20A
时,info -> width = 20
(结构体的详细介绍见后文);args是获取的参数列表,通过上文的arginfo-function指定参数个数n以后,它会在printf的参数列表中依次获取n个参数。 -
arginfo-function:指定该spec所需的参数个数和参数类型。
size_t parse_printf_format (const char *template, size_t n, int *argtypes)
这里需要关注的是argtypes和返回值,argtypes是一个数组,分别指定了各参数的类型,如PA_INT、PA_CHAR等,最后返回该spec所需的参数个数。
解题方法
-
找到register_printf_function -
记录各格式占位符的作用 -
编写VM解释器将format字符串转换为汇编 -
阅读汇编代码求解flag
BRICS+CTF | shellcode???
main
函数里只有一句printf,大概会觉得很莫名其妙:.init_array
,分别查看这里的各个函数,就能发现第二个函数就是我们所要找的注册printf转换函数的地方:%f
,所以看'f'
的handler:undefined8 FUN_00401fe0(void) {
uint arg;
char *format;
int i;
for (i = 0; i < 0x34; i = i + 1) {
format = (char *)malloc(0x100);
arg = 0;
__isoc99_scanf("%s %d",format,&arg);
printf(format,(ulong)arg);
free(format);
}
printf("%w%V%b%s%V%m%J%s%R%H",0x1223f37,0x2af985a,0x2ba4c9,0x693d920,0x6f794f,0x62,0xfff1d63c,
0x623c513,0x2584,0x474f4b2,0x27d8f97);
printf("%w%V%b%s%V%m%J%s%R%H",0x3fe9fae,0x5d0a399,0x3c7c1e5,0x426e19e,0x3ac53d7,0x69,0xffee7c50,
0x9abb47,0x2b11,0x25242a2,0x2f511fb);
printf("%w%V%b%s%V%m%J%s%R%H",0x79bc35,0x1b7bd90,0x4383c74,0x580ac2a,0x73751d6,0x73,0xffe8d24e,
0x45161b0,0x33a9,0x2f87765,0x10ad040);
printf("%w%V%b%s%V%m%J%s%R%H",0xa6d19b,0x1a6a0d3,0x23784ab,0x170fb47,0x6279f4e,0x7b,0xffe3b18d,
0x18d51b8,0x3b19,0x22e1923,0x44c107e);
printf("%w%V%b%s%V%m%J%s%R%H",0x61d2d1a,0x2fd3ab5,0x3674d99,0x2ef1ece,0x4320e5,0x30,0xfffe7d90,
0x72efd70,0x900,0x5054985,0x8a2648);
printf("%w%V%b%s%V%m%J%s%R%H",0x73273e1,0x1ea1176,0x22750f6,0x43b6a7a,0x6fc9446,0x5f,0xfff32412,
0x36aa1c2,0x2341,0x2bdfa2d,0x19df6c1);
printf("%w%V%b%s%V%m%J%s%R%H",0x709b202,0x10c7776,0x1aca7bf,0x2846728,0x2acdfd,0x30,0xfffe6c39,
0x50aceaf,0x900,0x3fd6e93,0x6f1ae51);
printf("%w%V%b%s%V%m%J%s%R%H",0x2839ef3,0x14e6f45,0x3ac805f,0x3df8740,0x9ecc96,0x5f,0xfff3112a,
0x878285,0x2341,0x1465a45,0x61cb62);
printf("%w%V%b%s%V%m%J%s%R%H",0x48975af,0x3e4659f,0x2e62dba,0x43051c2,0x70c2c14,0x61,0xfff24223,
0x726a781,0x24c1,0x3c59ed9,0x7013f38);
printf("%w%V%b%s%V%m%J%s%R%H",0x5af8e8f,0x14a0790,0x11a0297,0x1639c3,0x2f4684f,0x5f,0xfff31a25,
0x69dcc81,0x2341,0x3d1ec81,0x4b5c9aa);
printf("%w%V%b%s%V%m%J%s%R%H",0x2384a5d,0x6023773,0x751b5a4,0x42906ae,0x2abc591,0x30,0xfffe8490,
0x1ba4382,0x900,0x4c841a0,0x5d6c676);
printf("%w%V%b%s%V%m%J%s%R%H",0x10f72b,0x4555f11,0x73006b8,0x4bd032f,0x21f61cb,0x5f,0xfff316c5,
0x130456c,0x2341,0x66232ed,0x24880b7);
printf("%w%V%b%s%V%m%J%s%R%H",0x61629be,0x142e4d1,0x6ef88f9,0x124e9d7,0x75323be,0x75,0xffe7c35c,
0x13e54b,0x3579,0x2055d85,0x40a037e);
printf("%w%V%b%s%V%m%J%s%R%H",0x1a974cb,0x4c13f72,0x3f91ead,0xc0b580,0x2ceb6c6,0x31,0xfffe57b0,
0x73751fd,0x961,0x2448dd2,0x35e7795);
printf("%w%V%b%s%V%m%J%s%R%H",0xd61454,0x5ea2480,0x638cf01,0xc1897,0x59b1f2b,0x70,0xffeaa081,
0x12d8934,0x3100,0x2507798,0x58616c);
printf("%w%V%b%s%V%m%J%s%R%H",0x2b7cfa7,0x27e600c,0x2aac5b2,0x58544a3,0x2b98aa3,0x72,0xffe99861,
0x60f21dd,0x32c4,0x7021d82,0x1ee19b5);
printf("%w%V%b%s%V%m%J%s%R%H",0x35491c5,0x2341b2f,0x21a5253,0x3d9b0ad,0x23c1e66,0x33,0xfffe1d16,
0x3e89c02,0xa29,0x5c82116,0x4129fef);
printf("%w%V%b%s%V%m%J%s%R%H",0x4e0a10d,0x71efc70,0x6092171,0x869088,0x63dba22,0x74,0xffe85900,
0x570839b,0x3490,0x1a2b21d,0x2e03a43);
printf("%w%V%b%s%V%m%J%s%R%H",0x296ee85,0x63d72c7,0x6d9cd72,0x70f9b7d,0x4dbbe1a,0x31,0xfffe6818,
0x48cad9,0x961,0x581996e,0x58772);
printf("%w%V%b%s%V%m%J%s%R%H",0x2fb0010,0x5c0791d,0x145d223,0xac2f74,0x5368a28,0x5f,0xfff31065,
0x55bca2a,0x2341,0x4b1ebf8,0x6a49a88);
printf("%w%V%b%s%V%m%J%s%R%H",0x70eecbd,0x36ecff2,0x4924a1d,0x1f74f07,0x11d896d,0x75,0xffe7ab43,
0x23f3af7,0x3579,0x72f2132,0x25a98d9);
printf("%w%V%b%s%V%m%J%s%R%H",0x2f1cb4,0x3f205f7,0x75aa10f,0x3e936c7,0x5188cee,0x5f,0xfff2fe92,
0x708fd26,0x2341,0x2749ae8,0x6257695);
printf("%w%V%b%s%V%m%J%s%R%H",0x4c7a950,0x5ec022e,0x4b9a7a4,0x2e278f4,0x6200e00,0x30,0xfffe8021,
0x63b7839,0x900,0x42dc8d5,0x13d670a);
printf("%w%V%b%s%V%m%J%s%R%H",0x47b6288,0x4f8f54e,0x142674c,0x8c3951,0x7037c99,100,0xfff0e101,
0x3ecce47,10000,0x66fbc4d,0x37bed26);
printf("%w%V%b%s%V%m%J%s%R%H",0x642ad16,0x740e6c5,0x258eae7,0x65e3017,0x586efb0,0x6a,0xffee03b9,
0x4afb046,0x2be4,0x4c31ce0,0x52abb1f);
printf("%w%V%b%s%V%m%J%s%R%H",0x55db7f6,0x6aef138,0x42210e5,0x72fd711,0xd8d75e,0x62,0xfff1e081,
0x1ca0e4d,0x2584,0x325351f,0x69c0c21);
putchar(0x59);
putchar(0x65);
putchar(0x73);
return 0;
}
"%w%V%b%s%V%m%J%s%R%H"
,而前面的for循环让我们输入字符串format作为指令和一个数字arg作为参数,姑且相当于是平时题目中的输入。%w
的handler:undefined8 FUN_00400ed4(void) {
long v1;
double v0;
ptr = ptr + -1;
v0 = pow((double)arr[ptr],2.0);
v1 = (long)ptr;
ptr = ptr + 1;
arr[v1] = (int)v0;
return 0;
}
arr[ptr-1] = arr[ptr-1] ** 2
POW [rsi-1], 2
;%w
;POW [rsi-1], 2
POP rax
POW rax, 2
PUSH rax
;%V
;mov [rsi], [rsi-2]
;inc rsi
PUSH [rsp-2]
;%b
;POW [rsi-1], 3
POP rax
POW rax, 3
PUSH rax
;%s
;sub [rsi-2], [rsi-1]
;dec rsi
POP rax
POP rbx
sub rbx, rax
PUSH rbx
;%V
;mov [rsi], [rsi-2]
;inc rsi
PUSH [rsp-2]
;%m
;mul [rsi-1], arg5
POP rax
MUL rax, arg5
PUSH rax
;%J
;sub arg6, [rsi-1]
;mov [rsi-1], arg6
POP rax
MOV rbx, arg6
SUB rbx, rax
PUSH rbx
;%s
;sub [rsi-2], [rsi-1]
;dec rsi
POP rax
POP rbx
sub rbx, rax
PUSH rbx
;%R
;cmp [rsi-1], arg8
;jnz "No"
;dec rsi
POP rax
cmp rax, arg8
;%H
;dec rsi
POP
def f(v5, v6, v8):
assert v8 == (arr[ptr-1] ** 2) - (arr[ptr-2] ** 3) - (v6 - (arr[ptr-2] * v5))
ptr -= 2
arr[ptr-1]
和arr[ptr-2]
,从而推出整个flag。s = '''
printf("%w%V%b%s%V%m%J%s%R%H",0x1223f37,0x2af985a,0x2ba4c9,0x693d920,0x6f794f,0x62,0xfff1d63c,0x623c513,0x2584,0x474f4b2,0x27d8f97);
printf("%w%V%b%s%V%m%J%s%R%H",0x3fe9fae,0x5d0a399,0x3c7c1e5,0x426e19e,0x3ac53d7,0x69,0xffee7c50,0x9abb47,0x2b11,0x25242a2,0x2f511fb);
printf("%w%V%b%s%V%m%J%s%R%H",0x79bc35,0x1b7bd90,0x4383c74,0x580ac2a,0x73751d6,0x73,0xffe8d24e,0x45161b0,0x33a9,0x2f87765,0x10ad040);
printf("%w%V%b%s%V%m%J%s%R%H",0xa6d19b,0x1a6a0d3,0x23784ab,0x170fb47,0x6279f4e,0x7b,0xffe3b18d,0x18d51b8,0x3b19,0x22e1923,0x44c107e);
printf("%w%V%b%s%V%m%J%s%R%H",0x61d2d1a,0x2fd3ab5,0x3674d99,0x2ef1ece,0x4320e5,0x30,0xfffe7d90,0x72efd70,0x900,0x5054985,0x8a2648);
printf("%w%V%b%s%V%m%J%s%R%H",0x73273e1,0x1ea1176,0x22750f6,0x43b6a7a,0x6fc9446,0x5f,0xfff32412,0x36aa1c2,0x2341,0x2bdfa2d,0x19df6c1);
printf("%w%V%b%s%V%m%J%s%R%H",0x709b202,0x10c7776,0x1aca7bf,0x2846728,0x2acdfd,0x30,0xfffe6c39,0x50aceaf,0x900,0x3fd6e93,0x6f1ae51);
printf("%w%V%b%s%V%m%J%s%R%H",0x2839ef3,0x14e6f45,0x3ac805f,0x3df8740,0x9ecc96,0x5f,0xfff3112a,0x878285,0x2341,0x1465a45,0x61cb62);
printf("%w%V%b%s%V%m%J%s%R%H",0x48975af,0x3e4659f,0x2e62dba,0x43051c2,0x70c2c14,0x61,0xfff24223,0x726a781,0x24c1,0x3c59ed9,0x7013f38);
printf("%w%V%b%s%V%m%J%s%R%H",0x5af8e8f,0x14a0790,0x11a0297,0x1639c3,0x2f4684f,0x5f,0xfff31a25,0x69dcc81,0x2341,0x3d1ec81,0x4b5c9aa);
printf("%w%V%b%s%V%m%J%s%R%H",0x2384a5d,0x6023773,0x751b5a4,0x42906ae,0x2abc591,0x30,0xfffe8490,0x1ba4382,0x900,0x4c841a0,0x5d6c676);
printf("%w%V%b%s%V%m%J%s%R%H",0x10f72b,0x4555f11,0x73006b8,0x4bd032f,0x21f61cb,0x5f,0xfff316c5,0x130456c,0x2341,0x66232ed,0x24880b7);
printf("%w%V%b%s%V%m%J%s%R%H",0x61629be,0x142e4d1,0x6ef88f9,0x124e9d7,0x75323be,0x75,0xffe7c35c,0x13e54b,0x3579,0x2055d85,0x40a037e);
printf("%w%V%b%s%V%m%J%s%R%H",0x1a974cb,0x4c13f72,0x3f91ead,0xc0b580,0x2ceb6c6,0x31,0xfffe57b0,0x73751fd,0x961,0x2448dd2,0x35e7795);
printf("%w%V%b%s%V%m%J%s%R%H",0xd61454,0x5ea2480,0x638cf01,0xc1897,0x59b1f2b,0x70,0xffeaa081,0x12d8934,0x3100,0x2507798,0x58616c);
printf("%w%V%b%s%V%m%J%s%R%H",0x2b7cfa7,0x27e600c,0x2aac5b2,0x58544a3,0x2b98aa3,0x72,0xffe99861,0x60f21dd,0x32c4,0x7021d82,0x1ee19b5);
printf("%w%V%b%s%V%m%J%s%R%H",0x35491c5,0x2341b2f,0x21a5253,0x3d9b0ad,0x23c1e66,0x33,0xfffe1d16,0x3e89c02,0xa29,0x5c82116,0x4129fef);
printf("%w%V%b%s%V%m%J%s%R%H",0x4e0a10d,0x71efc70,0x6092171,0x869088,0x63dba22,0x74,0xffe85900,0x570839b,0x3490,0x1a2b21d,0x2e03a43);
printf("%w%V%b%s%V%m%J%s%R%H",0x296ee85,0x63d72c7,0x6d9cd72,0x70f9b7d,0x4dbbe1a,0x31,0xfffe6818,0x48cad9,0x961,0x581996e,0x58772);
printf("%w%V%b%s%V%m%J%s%R%H",0x2fb0010,0x5c0791d,0x145d223,0xac2f74,0x5368a28,0x5f,0xfff31065,0x55bca2a,0x2341,0x4b1ebf8,0x6a49a88);
printf("%w%V%b%s%V%m%J%s%R%H",0x70eecbd,0x36ecff2,0x4924a1d,0x1f74f07,0x11d896d,0x75,0xffe7ab43,0x23f3af7,0x3579,0x72f2132,0x25a98d9);
printf("%w%V%b%s%V%m%J%s%R%H",0x2f1cb4,0x3f205f7,0x75aa10f,0x3e936c7,0x5188cee,0x5f,0xfff2fe92,0x708fd26,0x2341,0x2749ae8,0x6257695);
printf("%w%V%b%s%V%m%J%s%R%H",0x4c7a950,0x5ec022e,0x4b9a7a4,0x2e278f4,0x6200e00,0x30,0xfffe8021,0x63b7839,0x900,0x42dc8d5,0x13d670a);
printf("%w%V%b%s%V%m%J%s%R%H",0x47b6288,0x4f8f54e,0x142674c,0x8c3951,0x7037c99,100,0xfff0e101,0x3ecce47,10000,0x66fbc4d,0x37bed26);
printf("%w%V%b%s%V%m%J%s%R%H",0x642ad16,0x740e6c5,0x258eae7,0x65e3017,0x586efb0,0x6a,0xffee03b9,0x4afb046,0x2be4,0x4c31ce0,0x52abb1f);
printf("%w%V%b%s%V%m%J%s%R%H",0x55db7f6,0x6aef138,0x42210e5,0x72fd711,0xd8d75e,0x62,0xfff1e081,0x1ca0e4d,0x2584,0x325351f,0x69c0c21);
'''
import re
import math
args = []
for l in s.split('n'):
if l == '':
continue
hexes = re.findall(r'(?:0x[0-9a-f]{2,8})|(?:d+)', l)
arg = [hexes[5], hexes[6], hexes[8]]
for i in range(len(arg)):
if arg[i].startswith("0x"):
arg[i] = int(arg[i], 16)
else:
arg[i] = int(arg[i])
args.append(arg)
assert len(args) == 26
flag = []
for i in range(len(args)):
for x in range(0x100):
y2 = (args[i][2] + (x ** 3) + (args[i][1] - (x * args[i][0])))&0xFFFFFFFF
y = int(math.sqrt(y2))
if y**2 == y2 and y < 0x100:
flag += [x, y]
break
assert len(flag) == 52
print(bytes(flag))
flag:brics+{L0l_y0U_can_n0t_jus1_pArs3_th1s_buT_G0od_job}
%p
的函数是将参数逐个布置到arr上,依次用%p ASCII
两字节为一组倒序输入即可。楚慧杯 | scalar
init_array
同样能找到注册printf转换函数的函数:arginfo
返回0,代表不需要参数;sub_190C
和sub_1949
分别返回了3和4,代表分别需要3/4个参数,且指定了其中的argtypes均为PA_INT。main
函数,这里需要输入64字节的小写十六进制,在对输入unhex以后以指定顺序传入printf中,format作为使用输入进行运算的指令序列。__int64 __fastcall main(int a1, char **a2, char **a3)
{
int i; // [rsp+74h] [rbp-3Ch]
int j; // [rsp+74h] [rbp-3Ch]
int k; // [rsp+74h] [rbp-3Ch]
int m; // [rsp+74h] [rbp-3Ch]
int v8; // [rsp+78h] [rbp-38h]
int v9; // [rsp+78h] [rbp-38h]
int v10; // [rsp+7Ch] [rbp-34h]
char v11; // [rsp+7Ch] [rbp-34h]
unsigned int v12; // [rsp+7Ch] [rbp-34h]
puts("Welcome to the chall! give me your pass!");
__isoc99_scanf("%64s", input);
if ( strlen(input) != 64 )
return 0LL;
for ( i = 0; i <= 63; ++i )
{
if ( (input[i] <= 47 || input[i] > 57) && (input[i] <= 96 || input[i] > 102) )
return 0LL;
}
for ( j = 0; j <= 31; ++j )
{
if ( input[2 * j] <= 47 || input[2 * j] > 57 )
v8 = input[2 * j] - 87;
else
v8 = input[2 * j] - 48;
if ( input[2 * j + 1] <= 47 || input[2 * j + 1] > 57 )
v10 = input[2 * j + 1] - 87;
else
v10 = input[2 * j + 1] - 48;
unhex[j] = v10 | (16 * v8);
}
printf(
format,
(unsigned int)unhex[0],
(unsigned int)unhex[1],
(unsigned int)unhex[2],
(unsigned int)unhex[2],
(unsigned int)unhex[3],
(unsigned int)unhex[4],
(unsigned int)unhex[5],
(unsigned int)unhex[5],
(unsigned int)unhex[6],
(unsigned int)unhex[7],
(unsigned int)unhex[7],
(unsigned int)unhex[8],
(unsigned int)unhex[9],
(unsigned int)unhex[10],
(unsigned int)unhex[10],
(unsigned int)unhex[11],
(unsigned int)unhex[12],
(unsigned int)unhex[13],
(unsigned int)unhex[13],
(unsigned int)unhex[14],
(unsigned int)unhex[15],
(unsigned int)unhex[15],
(unsigned int)unhex[16],
(unsigned int)unhex[17],
(unsigned int)unhex[18],
(unsigned int)unhex[18],
(unsigned int)unhex[19],
(unsigned int)unhex[20],
(unsigned int)unhex[21],
(unsigned int)unhex[22],
(unsigned int)unhex[23],
(unsigned int)unhex[23],
(unsigned int)unhex[24],
(unsigned int)unhex[25],
(unsigned int)unhex[26],
(unsigned int)unhex[26],
(unsigned int)unhex[27],
(unsigned int)unhex[28],
(unsigned int)unhex[28],
(unsigned int)unhex[29],
(unsigned int)unhex[30],
(unsigned int)unhex[31]);
if ( unk_209D80 != 1LL )
return 0LL;
for ( k = 1; k <= 23; ++k )
{
if ( *(_QWORD *)&format[8 * k + 28000] )
return 0LL;
}
puts("Correct!");
for ( m = 0; m <= 15; ++m )
{
v9 = (unsigned __int8)(32 * LOBYTE(unhex[2 * m]) + unhex[2 * m + 1]);
v11 = v9 & 0xF;
if ( (v9 & 0xFu) > 9 )
hex[2 * m] = v11 + 87;
else
hex[2 * m] = v11 + 48;
v12 = (v9 >> 4) & 0xF;
if ( v12 > 9 )
hex[2 * m + 1] = v12 + 87;
else
hex[2 * m + 1] = v12 + 48;
}
printf("Here is your flag: %sn", hex);
return 0LL;
}
'M': movl
'N': add
'O': sub
'P': mul
'Q': div
'R': mod
'S': shl
'T': shr
'U': xor
'V': and
'W': or
'X': load3
'Y': load4
'A': movq
sub_190C
和sub_1949
,代表将参数依次拼接转换为小端序的整数。%M
:__int64 __fastcall func(FILE *stream, const struct printf_info *info, const void *const *args)
{
int width; // [rsp+20h] [rbp-18h]
int prec; // [rsp+24h] [rbp-14h]
char *v6; // [rsp+28h] [rbp-10h]
__int64 v7; // [rsp+30h] [rbp-8h]
width = info->width;
prec = info->prec;
if ( (*((_BYTE *)info + 12) & 0x20) != 0 )
{
v6 = &format[width];
}
else if ( (*((_BYTE *)info + 12) & 0x40) != 0 )
{
v6 = &format[reg[width]];
}
else
{
v6 = (char *)®[width];
}
v7 = 0LL;
if ( (*((_BYTE *)info + 13) & 2) != 0 )
{
v7 = *(int *)&format[prec];
}
else if ( (*((_BYTE *)info + 12) & 2) != 0 )
{
v7 = *(int *)&format[reg[prec]];
}
else if ( (*((_BYTE *)info + 12) & 1) != 0 )
{
v7 = prec;
}
else if ( (*((_BYTE *)info + 12) & 4) != 0 )
{
v7 = reg[prec];
}
*(_QWORD *)v6 = v7;
return 0LL;
}
%M
的作用是movl v6, v7
,v6由info->width
及相应标志位指定,v7由info->prec
及相应标志位指定,关于printf_info的定义如下:struct printf_info
{
int prec; /* Precision. */
int width; /* Width. */
wchar_t spec; /* Format letter. */
unsigned int is_long_double:1;/* L flag. */
unsigned int is_short:1; /* h flag. */
unsigned int is_long:1; /* l flag. */
unsigned int alt:1; /* # flag. */
unsigned int space:1; /* Space flag. */
unsigned int left:1; /* - flag. */
unsigned int showsign:1; /* + flag. */
unsigned int group:1; /* ' flag. */
unsigned int extra:1; /* For special use. */
unsigned int is_char:1; /* hh flag. */
unsigned int wide:1; /* Nonzero for wide character streams. */
unsigned int i18n:1; /* I flag. */
unsigned int is_binary128:1; /* Floating-point argument is ABI-compatible
with IEC 60559 binary128. */
unsigned int __pad:3; /* Unused so far. */
unsigned short int user; /* Bits for user-installed modifiers. */
wchar_t pad; /* Padding character. */
};
%M
就是: width = info->width;
prec = info->prec;
if (info->left != 0) {
v6 = &format[width];
} else if (info->showsign != 0) {
v6 = &format[reg[width]];
} else {
v6 = (char *)®[width];
}
v7 = 0LL;
if (info->is_char != 0) {
v7 = *(int *)&format[prec];
} else if (info->is_short != 0) {
v7 = *(int *)&format[reg[prec]];
} else if (info->is_long_double != 0) {
v7 = prec;
} else if (info->is_long != 0) {
v7 = reg[prec];
}
*(_QWORD *)v6 = v7;
import re
fm = "%0.27000llM%+0.1491575llM%0.4llN%+0.1863417llM%0.4llN%+0.1725080llM%0.4llN%+0.1009708llM%0.4llN%+0.39773llM%0.4llN%1.26000llM%3.2097151llM%0.X%0.3lV%+1.0lM%1.4llN%0.Y%0.5llT%0.3lV%+1.0lM%1.4llN%0.X%0.2llT%0.3lV%+1.0lM%1.4llN%0.Y%0.7llT%0.3lV%+1.0lM%1.4llN%0.Y%0.4llT%0.3lV%+1.0lM%1.4llN%0.X%0.1llT%0.3lV%+1.0lM%1.4llN%0.Y%0.6llT%0.3lV%+1.0lM%1.4llN%0.X%0.3llT%0.3lV%+1.0lM%1.4llN%0.X%0.3lV%+1.0lM%1.4llN%0.Y%0.5llT%0.3lV%+1.0lM%1.4llN%0.X%0.2llT%0.3lV%+1.0lM%1.4llN%0.Y%0.7llT%0.3lV%+1.0lM%1.4llN%29.28000llM%30.26000llM%31.27000llM%0.30hM%30.4llN%1.30hM%30.4llN%2.30hM%30.4llN%3.30hM%30.4llN%4.30hM%30.4llN%5.30hM%30.4llN%6.30hM%30.4llN%7.30hM%30.4llN%8.30hM%30.4llN%9.30hM%30.4llN%10.30hM%30.4llN%11.30hM%30.4llN%12.31hM%31.4llN%13.31hM%31.4llN%14.31hM%31.4llN%15.31hM%31.4llN%16.31hM%31.4llN%17.31hM%31.4llN%18.31hM%31.4llN%19.31hM%31.4llN%20.31hM%31.4llN%21.31hM%31.4llN%22.31hM%31.4llN%23.31hM%31.4llN%24.0llM%25.0lM%25.12lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.0lM%25.13lP%24.25lN%25.1lM%25.12lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.0lM%25.14lP%24.25lN%25.1lM%25.13lP%24.25lN%25.2lM%25.12lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.0lM%25.15lP%24.25lN%25.1lM%25.14lP%24.25lN%25.2lM%25.13lP%24.25lN%25.3lM%25.12lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.0lM%25.16lP%24.25lN%25.1lM%25.15lP%24.25lN%25.2lM%25.14lP%24.25lN%25.3lM%25.13lP%24.25lN%25.4lM%25.12lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.0lM%25.17lP%24.25lN%25.1lM%25.16lP%24.25lN%25.2lM%25.15lP%24.25lN%25.3lM%25.14lP%24.25lN%25.4lM%25.13lP%24.25lN%25.5lM%25.12lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.0lM%25.18lP%24.25lN%25.1lM%25.17lP%24.25lN%25.2lM%25.16lP%24.25lN%25.3lM%25.15lP%24.25lN%25.4lM%25.14lP%24.25lN%25.5lM%25.13lP%24.25lN%25.6lM%25.12lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.0lM%25.19lP%24.25lN%25.1lM%25.18lP%24.25lN%25.2lM%25.17lP%24.25lN%25.3lM%25.16lP%24.25lN%25.4lM%25.15lP%24.25lN%25.5lM%25.14lP%24.25lN%25.6lM%25.13lP%24.25lN%25.7lM%25.12lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.0lM%25.20lP%24.25lN%25.1lM%25.19lP%24.25lN%25.2lM%25.18lP%24.25lN%25.3lM%25.17lP%24.25lN%25.4lM%25.16lP%24.25lN%25.5lM%25.15lP%24.25lN%25.6lM%25.14lP%24.25lN%25.7lM%25.13lP%24.25lN%25.8lM%25.12lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.0lM%25.21lP%24.25lN%25.1lM%25.20lP%24.25lN%25.2lM%25.19lP%24.25lN%25.3lM%25.18lP%24.25lN%25.4lM%25.17lP%24.25lN%25.5lM%25.16lP%24.25lN%25.6lM%25.15lP%24.25lN%25.7lM%25.14lP%24.25lN%25.8lM%25.13lP%24.25lN%25.9lM%25.12lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.0lM%25.22lP%24.25lN%25.1lM%25.21lP%24.25lN%25.2lM%25.20lP%24.25lN%25.3lM%25.19lP%24.25lN%25.4lM%25.18lP%24.25lN%25.5lM%25.17lP%24.25lN%25.6lM%25.16lP%24.25lN%25.7lM%25.15lP%24.25lN%25.8lM%25.14lP%24.25lN%25.9lM%25.13lP%24.25lN%25.10lM%25.12lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.0lM%25.23lP%24.25lN%25.1lM%25.22lP%24.25lN%25.2lM%25.21lP%24.25lN%25.3lM%25.20lP%24.25lN%25.4lM%25.19lP%24.25lN%25.5lM%25.18lP%24.25lN%25.6lM%25.17lP%24.25lN%25.7lM%25.16lP%24.25lN%25.8lM%25.15lP%24.25lN%25.9lM%25.14lP%24.25lN%25.10lM%25.13lP%24.25lN%25.11lM%25.12lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.1lM%25.23lP%24.25lN%25.2lM%25.22lP%24.25lN%25.3lM%25.21lP%24.25lN%25.4lM%25.20lP%24.25lN%25.5lM%25.19lP%24.25lN%25.6lM%25.18lP%24.25lN%25.7lM%25.17lP%24.25lN%25.8lM%25.16lP%24.25lN%25.9lM%25.15lP%24.25lN%25.10lM%25.14lP%24.25lN%25.11lM%25.13lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.2lM%25.23lP%24.25lN%25.3lM%25.22lP%24.25lN%25.4lM%25.21lP%24.25lN%25.5lM%25.20lP%24.25lN%25.6lM%25.19lP%24.25lN%25.7lM%25.18lP%24.25lN%25.8lM%25.17lP%24.25lN%25.9lM%25.16lP%24.25lN%25.10lM%25.15lP%24.25lN%25.11lM%25.14lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.3lM%25.23lP%24.25lN%25.4lM%25.22lP%24.25lN%25.5lM%25.21lP%24.25lN%25.6lM%25.20lP%24.25lN%25.7lM%25.19lP%24.25lN%25.8lM%25.18lP%24.25lN%25.9lM%25.17lP%24.25lN%25.10lM%25.16lP%24.25lN%25.11lM%25.15lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.4lM%25.23lP%24.25lN%25.5lM%25.22lP%24.25lN%25.6lM%25.21lP%24.25lN%25.7lM%25.20lP%24.25lN%25.8lM%25.19lP%24.25lN%25.9lM%25.18lP%24.25lN%25.10lM%25.17lP%24.25lN%25.11lM%25.16lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.5lM%25.23lP%24.25lN%25.6lM%25.22lP%24.25lN%25.7lM%25.21lP%24.25lN%25.8lM%25.20lP%24.25lN%25.9lM%25.19lP%24.25lN%25.10lM%25.18lP%24.25lN%25.11lM%25.17lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.6lM%25.23lP%24.25lN%25.7lM%25.22lP%24.25lN%25.8lM%25.21lP%24.25lN%25.9lM%25.20lP%24.25lN%25.10lM%25.19lP%24.25lN%25.11lM%25.18lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.7lM%25.23lP%24.25lN%25.8lM%25.22lP%24.25lN%25.9lM%25.21lP%24.25lN%25.10lM%25.20lP%24.25lN%25.11lM%25.19lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.8lM%25.23lP%24.25lN%25.9lM%25.22lP%24.25lN%25.10lM%25.21lP%24.25lN%25.11lM%25.20lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.9lM%25.23lP%24.25lN%25.10lM%25.22lP%24.25lN%25.11lM%25.21lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.10lM%25.23lP%24.25lN%25.11lM%25.22lP%24.25lN%+29.24lM%29.8llN%24.0llM%25.11lM%25.23lP%24.25lN%+29.24lM%29.8llN%29.28000llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28016llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28032llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28048llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28064llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28080llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28096llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28112llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28128llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28144llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28160llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28176llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28008llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28024llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28040llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28056llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28072llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28088llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28104llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28120llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28136llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28152llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28168llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28088llM%30.28184llM%0.30hA%31.0lM%1.29hA%31.666643llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.470296llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.654183llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.997805llP%1.31lO%+29.1lM%29.8llN%31.0lM%1.29hA%31.136657llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.683901llP%1.31lO%+29.1lM%29.8llN%+30.0llM%29.28080llM%30.28176llM%0.30hA%31.0lM%1.29hA%31.666643llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.470296llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.654183llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.997805llP%1.31lO%+29.1lM%29.8llN%31.0lM%1.29hA%31.136657llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.683901llP%1.31lO%+29.1lM%29.8llN%+30.0llM%29.28072llM%30.28168llM%0.30hA%31.0lM%1.29hA%31.666643llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.470296llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.654183llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.997805llP%1.31lO%+29.1lM%29.8llN%31.0lM%1.29hA%31.136657llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.683901llP%1.31lO%+29.1lM%29.8llN%+30.0llM%29.28064llM%30.28160llM%0.30hA%31.0lM%1.29hA%31.666643llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.470296llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.654183llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.997805llP%1.31lO%+29.1lM%29.8llN%31.0lM%1.29hA%31.136657llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.683901llP%1.31lO%+29.1lM%29.8llN%+30.0llM%29.28056llM%30.28152llM%0.30hA%31.0lM%1.29hA%31.666643llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.470296llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.654183llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.997805llP%1.31lO%+29.1lM%29.8llN%31.0lM%1.29hA%31.136657llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.683901llP%1.31lO%+29.1lM%29.8llN%+30.0llM%29.28048llM%30.28144llM%0.30hA%31.0lM%1.29hA%31.666643llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.470296llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.654183llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.997805llP%1.31lO%+29.1lM%29.8llN%31.0lM%1.29hA%31.136657llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.683901llP%1.31lO%+29.1lM%29.8llN%+30.0llM%29.28048llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28064llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28080llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28096llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28112llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28128llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28056llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28072llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28088llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28104llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28120llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28040llM%30.28136llM%0.30hA%31.0lM%1.29hA%31.666643llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.470296llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.654183llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.997805llP%1.31lO%+29.1lM%29.8llN%31.0lM%1.29hA%31.136657llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.683901llP%1.31lO%+29.1lM%29.8llN%+30.0llM%29.28032llM%30.28128llM%0.30hA%31.0lM%1.29hA%31.666643llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.470296llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.654183llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.997805llP%1.31lO%+29.1lM%29.8llN%31.0lM%1.29hA%31.136657llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.683901llP%1.31lO%+29.1lM%29.8llN%+30.0llM%29.28024llM%30.28120llM%0.30hA%31.0lM%1.29hA%31.666643llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.470296llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.654183llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.997805llP%1.31lO%+29.1lM%29.8llN%31.0lM%1.29hA%31.136657llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.683901llP%1.31lO%+29.1lM%29.8llN%+30.0llM%29.28016llM%30.28112llM%0.30hA%31.0lM%1.29hA%31.666643llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.470296llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.654183llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.997805llP%1.31lO%+29.1lM%29.8llN%31.0lM%1.29hA%31.136657llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.683901llP%1.31lO%+29.1lM%29.8llN%+30.0llM%29.28008llM%30.28104llM%0.30hA%31.0lM%1.29hA%31.666643llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.470296llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.654183llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.997805llP%1.31lO%+29.1lM%29.8llN%31.0lM%1.29hA%31.136657llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.683901llP%1.31lO%+29.1lM%29.8llN%+30.0llM%29.28000llM%30.28096llM%0.30hA%31.0lM%1.29hA%31.666643llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.470296llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.654183llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.997805llP%1.31lO%+29.1lM%29.8llN%31.0lM%1.29hA%31.136657llP%1.31lN%+29.1lM%29.8llN%31.0lM%1.29hA%31.683901llP%1.31lO%+29.1lM%29.8llN%+30.0llM%29.28000llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28016llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28032llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28048llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28064llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28080llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28008llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28024llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28040llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28056llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28072llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM%29.28088llM%0.29hA%2.0lM%0.1048576llN%0.21llT%29.8llN%1.29hA%1.0lN%+29.1lM%0.21llS%2.0lO%29.8llO%+29.2lM"
ins_set = {'M': "movl {0}, {1}",
'N': "add {0}, {1}",
'O': "sub {0}, {1}",
'P': "mul {0}, {1}",
'Q': "div {0}, {1}",
'R': "mod {0}, {1}",
'S': "shl {0}, {1}",
'T': "shr {0}, {1}",
'U': "xor {0}, {1}",
'V': "and {0}, {1}",
'W': "or {0}, {1}",
'X': "load3 {0}",
'Y': "load4 {0}",
'A': "movq {0}, {1}",
}
output = open('assembly.txt', 'w')
pc = 0
ptn = r'%(?P<flags>[#+-0]*)(?P<width>d*).?(?P<precision>d*)(?P<length>[hljztqL]*)(?P<specifier>[AM-Z])'
while pc < len(fm):
reobj = re.search(ptn, fm[pc:])
try:
d = reobj.groupdict()
# default
d["width"] = '0' if d["width"] == '' else d["width"]
d["precision"] = '-1' if d["precision"] == '' else d["precision"]
# v6
if '-' in d["flags"]:
a = "fm[{0}]".format(d["width"])
elif '+' in d["flags"]:
a = "fm[r{0}]".format(d["width"])
else:
a = "r{0}".format(d["width"])
# v7
if d["specifier"] not in "XY":
if 'hh' in d["length"]:
b = "fm[{0}]".format(d["precision"])
elif 'h' in d["length"]:
b = "fm[r{0}]".format(d["precision"])
elif 'L' in d["length"]:
b = "{0}".format(d["precision"])
elif 'l' in d["length"]:
b = "r{0}".format(d["precision"])
else:
b = "0"
args = (a, b)
else:
args = (a,)
output.write(ins_set[d["specifier"]].format(*args) + 'n')
pc += reobj.end()
except Exception as e:
print("Something wrong?:", repr(e))
break
main
函数中会进行检验,如小端序(24字节)后为1则输入正确。/*
Input:
a[0]+256*a[1]+...+256^31*a[31] = a
b[0]+256*b[1]+...+256^31*b[31] = b
Output:
s[0]+256*s[1]+...+256^31*s[31] = (ab) mod l
where l = 2^252 + 27742317777372353535851937790883648493.
*/
void sc_mul(unsigned char *s, const unsigned char *a, const unsigned char *b) {
// int64_t a0 = 2097151 & load_3(a);
// int64_t a1 = 2097151 & (load_4(a + 2) >> 5);
// int64_t a2 = 2097151 & (load_3(a + 5) >> 2);
// int64_t a3 = 2097151 & (load_4(a + 7) >> 7);
// int64_t a4 = 2097151 & (load_4(a + 10) >> 4);
// int64_t a5 = 2097151 & (load_3(a + 13) >> 1);
// int64_t a6 = 2097151 & (load_4(a + 15) >> 6);
// int64_t a7 = 2097151 & (load_3(a + 18) >> 3);
// int64_t a8 = 2097151 & load_3(a + 21);
// int64_t a9 = 2097151 & (load_4(a + 23) >> 5);
// int64_t a10 = 2097151 & (load_3(a + 26) >> 2);
// int64_t a11 = (load_4(a + 28) >> 7);
// 这里已知数组a直接赋值,没有进行如上运算
a0 = 1491575;
a1 = 1863417;
a2 = 1725080;
a3 = 1009708;
a4 = 39773;
a5 = 0;
a6 = 0;
a7 = 0;
a8 = 0;
a9 = 0;
a10 = 0;
a11 = 0;
// 汇编第12行开始,b存的是一定运算后的输入;b+2之类的偏移通过控制printf的输入参数控制,即:
// unhex[0], unhex[1], unhex[2],
// unhex[2], unhex[3], unhex[4], unhex[5],
// unhex[5], unhex[6], unhex[7],
// unhex[7], unhex[8], unhex[9], unhex[10],
// unhex[10], unhex[11], unhex[12], unhex[13],
// unhex[13], unhex[14], unhex[15],
// unhex[15], unhex[16], unhex[17], unhex[18],
// unhex[18], unhex[19], unhex[20],
// unhex[21], unhex[22], unhex[23],
// unhex[23], unhex[24], unhex[25], unhex[26],
// unhex[26], unhex[27], unhex[28],
// unhex[28], unhex[29], unhex[30], unhex[31]
int64_t b0 = 2097151 & load_3(b);
int64_t b1 = 2097151 & (load_4(b + 2) >> 5);
int64_t b2 = 2097151 & (load_3(b + 5) >> 2);
int64_t b3 = 2097151 & (load_4(b + 7) >> 7);
int64_t b4 = 2097151 & (load_4(b + 10) >> 4);
int64_t b5 = 2097151 & (load_3(b + 13) >> 1);
int64_t b6 = 2097151 & (load_4(b + 15) >> 6);
int64_t b7 = 2097151 & (load_3(b + 18) >> 3);
int64_t b8 = 2097151 & load_3(b + 21);
int64_t b9 = 2097151 & (load_4(b + 23) >> 5);
int64_t b10 = 2097151 & (load_3(b + 26) >> 2);
int64_t b11 = (load_4(b + 28) >> 7);
int64_t s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, carry0, carry1, carry2, carry3, carry4, carry5, carry6, carry7, carry8, carry9, carry10, carry11, carry12, carry13, carry14, carry15, carry16, carry17, carry18, carry19, carry20, carry21, carry22;
// 汇编第123行开始
s0 = a0*b0;
s1 = (a0*b1 + a1*b0);
s2 = (a0*b2 + a1*b1 + a2*b0);
s3 = (a0*b3 + a1*b2 + a2*b1 + a3*b0);
s4 = (a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0);
s5 = (a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0);
s6 = (a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0);
s7 = (a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0);
s8 = (a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0);
s9 = (a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0);
s10 = (a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0);
s11 = (a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0);
s12 = (a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1);
s13 = (a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2);
s14 = (a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3);
s15 = (a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4);
s16 = (a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5);
s17 = (a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6);
s18 = (a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7);
s19 = (a8*b11 + a9*b10 + a10*b9 + a11*b8);
s20 = (a9*b11 + a10*b10 + a11*b9);
s21 = (a10*b11 + a11*b10);
s22 = a11*b11;
s23 = 0;
// 汇编第624行开始
carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21;
carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21;
carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21;
carry18 = (s18 + (1<<20)) >> 21; s19 += carry18; s18 -= carry18 << 21;
carry20 = (s20 + (1<<20)) >> 21; s21 += carry20; s20 -= carry20 << 21;
carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= carry22 << 21;
// 汇编第780行开始
carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21;
carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21;
carry17 = (s17 + (1<<20)) >> 21; s18 += carry17; s17 -= carry17 << 21;
carry19 = (s19 + (1<<20)) >> 21; s20 += carry19; s19 -= carry19 << 21;
carry21 = (s21 + (1<<20)) >> 21; s22 += carry21; s21 -= carry21 << 21;
// 汇编第923行开始
s11 += s23 * 666643;
s12 += s23 * 470296;
s13 += s23 * 654183;
s14 -= s23 * 997805;
s15 += s23 * 136657;
s16 -= s23 * 683901;
s23 = 0;
s10 += s22 * 666643;
s11 += s22 * 470296;
s12 += s22 * 654183;
s13 -= s22 * 997805;
s14 += s22 * 136657;
s15 -= s22 * 683901;
s22 = 0;
s9 += s21 * 666643;
s10 += s21 * 470296;
s11 += s21 * 654183;
s12 -= s21 * 997805;
s13 += s21 * 136657;
s14 -= s21 * 683901;
s21 = 0;
s8 += s20 * 666643;
s9 += s20 * 470296;
s10 += s20 * 654183;
s11 -= s20 * 997805;
s12 += s20 * 136657;
s13 -= s20 * 683901;
s20 = 0;
s7 += s19 * 666643;
s8 += s19 * 470296;
s9 += s19 * 654183;
s10 -= s19 * 997805;
s11 += s19 * 136657;
s12 -= s19 * 683901;
s19 = 0;
s6 += s18 * 666643;
s7 += s18 * 470296;
s8 += s18 * 654183;
s9 -= s18 * 997805;
s10 += s18 * 136657;
s11 -= s18 * 683901;
s18 = 0;
// 汇编第1163行开始
carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21;
carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21;
carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21;
// 汇编第1241行开始
carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21;
carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21;
// 汇编第1306行开始
s5 += s17 * 666643;
s6 += s17 * 470296;
s7 += s17 * 654183;
s8 -= s17 * 997805;
s9 += s17 * 136657;
s10 -= s17 * 683901;
s17 = 0;
s4 += s16 * 666643;
s5 += s16 * 470296;
s6 += s16 * 654183;
s7 -= s16 * 997805;
s8 += s16 * 136657;
s9 -= s16 * 683901;
s16 = 0;
s3 += s15 * 666643;
s4 += s15 * 470296;
s5 += s15 * 654183;
s6 -= s15 * 997805;
s7 += s15 * 136657;
s8 -= s15 * 683901;
s15 = 0;
s2 += s14 * 666643;
s3 += s14 * 470296;
s4 += s14 * 654183;
s5 -= s14 * 997805;
s6 += s14 * 136657;
s7 -= s14 * 683901;
s14 = 0;
s1 += s13 * 666643;
s2 += s13 * 470296;
s3 += s13 * 654183;
s4 -= s13 * 997805;
s5 += s13 * 136657;
s6 -= s13 * 683901;
s13 = 0;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
// 汇编第1546行开始
carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
// 汇编第1624行开始
carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
// 这里s0-s23的24字节就是main中检验的数组,如果s0-s23小端序转换后为1那么这里的结果s也为1
// s[0] = s0 >> 0;
// s[1] = s0 >> 8;
// s[2] = (s0 >> 16) | (s1 << 5);
// s[3] = s1 >> 3;
// s[4] = s1 >> 11;
// s[5] = (s1 >> 19) | (s2 << 2);
// s[6] = s2 >> 6;
// s[7] = (s2 >> 14) | (s3 << 7);
// s[8] = s3 >> 1;
// s[9] = s3 >> 9;
// s[10] = (s3 >> 17) | (s4 << 4);
// s[11] = s4 >> 4;
// s[12] = s4 >> 12;
// s[13] = (s4 >> 20) | (s5 << 1);
// s[14] = s5 >> 7;
// s[15] = (s5 >> 15) | (s6 << 6);
// s[16] = s6 >> 2;
// s[17] = s6 >> 10;
// s[18] = (s6 >> 18) | (s7 << 3);
// s[19] = s7 >> 5;
// s[20] = s7 >> 13;
// s[21] = s8 >> 0;
// s[22] = s8 >> 8;
// s[23] = (s8 >> 16) | (s9 << 5);
// s[24] = s9 >> 3;
// s[25] = s9 >> 11;
// s[26] = (s9 >> 19) | (s10 << 2);
// s[27] = s10 >> 6;
// s[28] = (s10 >> 14) | (s11 << 7);
// s[29] = s11 >> 1;
// s[30] = s11 >> 9;
// s[31] = s11 >> 17;
return;
}
反推出乘数b即可。
l = 2^252 + 27742317777372353535851937790883648493
tmp = [1491575, 1863417, 1725080, 1009708, 39773]
a = 0
for i in range(len(tmp)):
a += tmp[i] << (i * 21) # a0-a11实际上是从a依次取21位
b = a.inverse_mod(l)
assert (a * b) % l == 1
print(int(b).to_bytes(32, 'little').hex())
# 307e2dfb95b36f6389785f7713868f98367980d12b14a2e3f9021d957c39670b
flag:e7b9353489756e87931d473222539bbe
原文始发于微信公众号(山石网科安全技术研究院):RE新瓶装旧酒之printf虚拟机