示例#1
0
def f_dwepdread_epd_safe(targetplayer):
    ret, retepd = c.EUDVariable(), c.EUDVariable()

    # Common comparison rawtrigger
    c.PushTriggerScope()
    cmpc = c.Forward()
    cmp_player = cmpc + 4
    cmp_number = cmpc + 8
    cmpact = c.Forward()

    cmptrigger = c.Forward()
    cmptrigger << c.RawTrigger(
        conditions=[cmpc << c.Memory(0, c.AtMost, 0)],
        actions=[cmpact << c.SetMemory(cmptrigger + 4, c.SetTo, 0)])
    cmpact_ontrueaddr = cmpact + 20
    c.PopTriggerScope()

    # static_for
    chain1 = [c.Forward() for _ in range(32)]
    chain2 = [c.Forward() for _ in range(32)]

    # Main logic start
    c.SeqCompute([(ut.EPD(cmp_player), c.SetTo, targetplayer),
                  (ut.EPD(cmp_number), c.SetTo, 0xFFFFFFFF),
                  (ret, c.SetTo, 0xFFFFFFFF),
                  (retepd, c.SetTo, ut.EPD(0) + 0x3FFFFFFF)])

    readend = c.Forward()

    for i in range(31, -1, -1):
        nextchain = chain1[i - 1] if i > 0 else readend
        if i >= 2:
            epdsubact = [retepd.AddNumber(-2**(i - 2))]
            epdaddact = [retepd.AddNumber(2**(i - 2))]
        else:
            epdsubact = []
            epdaddact = []

        chain1[i] << c.RawTrigger(
            nextptr=cmptrigger,
            actions=[
                c.SetMemory(cmp_number, c.Subtract, 2**i),
                c.SetNextPtr(cmptrigger, chain2[i]),
                c.SetMemory(cmpact_ontrueaddr, c.SetTo, nextchain),
                ret.SubtractNumber(2**i),
            ] + epdsubact)

        chain2[i] << c.RawTrigger(actions=[
            c.SetMemory(cmp_number, c.Add, 2**i),
            ret.AddNumber(2**i),
        ] + epdaddact)

    readend << c.NextTrigger()

    return ret, retepd
示例#2
0
def EUDJump(nextptr):
    if isinstance(nextptr, c.EUDVariable):
        t = c.Forward()
        c.SeqCompute([(ut.EPD(t + 4), c.SetTo, nextptr)])
        t << c.RawTrigger()
    else:
        c.RawTrigger(nextptr=nextptr)
示例#3
0
def _f_mul(a, b):
    ret, y0 = ev.EUDCreateVariables(2)

    # Init
    ev.SeqCompute([(ret, rt.SetTo, 0), (y0, rt.SetTo, b)])

    chain = [ac.Forward() for _ in range(32)]
    chain_y0 = [ac.Forward() for _ in range(32)]

    # Calculate chain_y0
    for i in range(32):
        ev.SeqCompute(((ut.EPD(chain_y0[i]), rt.SetTo, y0), (y0, rt.Add, y0)))
        if i <= 30:
            p1, p2, p3 = ac.Forward(), ac.Forward(), ac.Forward()
            p1 << rt.RawTrigger(nextptr=p2,
                                conditions=a.AtMost(2**(i + 1) - 1),
                                actions=rt.SetNextPtr(p1, p3))
            p3 << rt.RawTrigger(nextptr=chain[i],
                                actions=rt.SetNextPtr(p1, p2))
            p2 << rt.NextTrigger()

    # Run multiplication chain
    for i in range(31, -1, -1):
        cy0 = ac.Forward()

        chain[i] << rt.RawTrigger(
            conditions=[a.AtLeast(2**i)],
            actions=[a.SubtractNumber(2**i), cy0 << ret.AddNumber(0)])

        chain_y0[i] << cy0 + 20

    return ret
示例#4
0
def _f_div(a, b):
    ret, x = ev.EUDCreateVariables(2)

    # Init
    ev.SeqCompute([
        (ret, rt.SetTo, 0),
        (x, rt.SetTo, b),
    ])

    # Chain ac.Forward decl
    chain_x0 = [ac.Forward() for _ in range(32)]
    chain_x1 = [ac.Forward() for _ in range(32)]
    chain = [ac.Forward() for _ in range(32)]

    # Fill in chain
    for i in range(32):
        ev.SeqCompute([
            (ut.EPD(chain_x0[i]), rt.SetTo, x),
            (ut.EPD(chain_x1[i]), rt.SetTo, x),
        ])

        # Skip if over 0x80000000
        p1, p2, p3 = ac.Forward(), ac.Forward(), ac.Forward()
        p1 << rt.RawTrigger(nextptr=p2,
                            conditions=x.AtLeast(0x80000000),
                            actions=rt.SetNextPtr(p1, p3))
        p3 << rt.RawTrigger(nextptr=chain[i], actions=rt.SetNextPtr(p1, p2))
        p2 << rt.NextTrigger()

        ev.SeqCompute([
            (x, rt.Add, x),
        ])

    # Run division chain
    for i in range(31, -1, -1):
        cx0, cx1 = ac.Forward(), ac.Forward()
        chain[i] << rt.RawTrigger(
            conditions=[cx0 << a.AtLeast(0)],
            actions=[cx1 << a.SubtractNumber(0),
                     ret.AddNumber(2**i)])

        chain_x0[i] << cx0 + 8
        chain_x1[i] << cx1 + 20

    return ret, a  # a : remainder
示例#5
0
def CreatePayloadRelocator(payload):
    # We first build code injector.
    prtdb = c.Db(b''.join([ut.i2b4(x // 4) for x in payload.prttable]))
    prtn = c.EUDVariable()

    ortdb = c.Db(b''.join([ut.i2b4(x // 4) for x in payload.orttable]))
    ortn = c.EUDVariable()

    orig_payload = c.Db(payload.data)

    if c.PushTriggerScope():
        root = c.NextTrigger()

        # Verify payload
        # Note : this is very, very basic protection method. Intended attackers
        # should be able to penetrate through this very easily

        # init prt
        prtn << len(payload.prttable)
        if payload.prttable:
            if cs.EUDWhile()(prtn >= 1):
                cs.DoActions(prtn.SubtractNumber(1))
                sf.f_dwadd_epd(
                    ut.EPD(orig_payload) +
                    sf.f_dwread_epd(prtn + ut.EPD(prtdb)), orig_payload // 4)
            cs.EUDEndWhile()

        # init ort
        ortn << len(payload.orttable)
        if payload.orttable:
            if cs.EUDWhile()(ortn >= 1):
                cs.DoActions(ortn.SubtractNumber(1))
                sf.f_dwadd_epd(
                    ut.EPD(orig_payload) +
                    sf.f_dwread_epd(ortn + ut.EPD(ortdb)), orig_payload)
            cs.EUDEndWhile()

        # Jump
        cs.EUDJump(orig_payload)

    c.PopTriggerScope()

    return c.CreatePayload(root)
示例#6
0
def f_dwepdCUnitread_epd(targetplayer):
    origcp = f_getcurpl()
    ptr, epd = c.EUDVariable(), c.EUDVariable()
    cs.DoActions([
        ptr.SetNumber(0x59CCA8),
        epd.SetNumber(ut.EPD(0x59CCA8)),
        c.SetCurrentPlayer(targetplayer)
    ])

    for i in range(10, -1, -1):
        c.RawTrigger(conditions=[
            c.Deaths(c.CurrentPlayer, c.AtLeast, 0x59CCA8 + 336 * 2**i, 0)
        ],
                     actions=[
                         c.SetDeaths(c.CurrentPlayer, c.Subtract, 336 * 2**i,
                                     0),
                         ptr.AddNumber(336 * 2**i),
                         epd.AddNumber(84 * 2**i)
                     ])

    cs.DoActions(c.SetDeaths(c.CurrentPlayer, c.SetTo, ptr, 0))
    f_setcurpl(origcp)

    return ptr, epd
示例#7
0
def CreateVectorRelocator(chkt, payload):
    global trglist

    # Append 'Require EUD enabler' to string table
    str_section = chkt.getsection('STR')
    strtb = c.TBL(str_section)
    eude_needed = strtb.GetStringIndex('This map requires EUD Enabler to run')
    str_section = strtb.SaveTBL()

    '''
    Algorithm credit to [email protected]

    Overall algorithm : STR <-> MRGN cycle

    MRGN:
      SetMemory(payload, Add, payload_offset // 4)

    MRGN <-> STR0  =  Trigger(actions=[
             STR1        [SetMemory(
                            mrgn.action[i].player,
                            Add,
                            prttable[j+packn] - prttable[j]
                          ) for i in range(packn)],
             STR2        SetNextPtr(mrgn, STR[k+1])
             ...      )
    '''

    mrgn = 0x58DC60
    packn = 15

    #############
    # STR SECTION
    #############
    str_sled = []
    sledheader_prt = b'\0\0\0\0' + ut.i2b4(mrgn)
    sledheader_ort = b'\0\0\0\0' + ut.i2b4(mrgn + 2408)

    # apply prt
    prttrg_start = 2408 * len(str_sled)  # = 0
    # mrgn.action[i].player = EPD(payload_offset) + prevoffset[i]
    prevoffset = [-1] * packn
    for i in range(0, len(payload.prttable), packn):
        prts = list(map(lambda x: x // 4, payload.prttable[i: i + packn]))
        prts = prts + [-1] * (packn - len(prts))  # -1 : dummy space
        pch = [prts[j] - prevoffset[j] for j in range(packn)]
        str_sled.append(sledheader_prt + tt.Trigger(
            players=[tt.AllPlayers],
            actions=[
                [tt.SetMemory(mrgn + 328 + 32 * j + 16, tt.Add, pch[j])
                 for j in range(packn)],
            ]
        ))

        prevoffset = prts

    # apply ort
    orttrg_start = 2408 * len(str_sled)  # = 0
    # mrgn.action[i].player = EPD(payload_offset) + prevoffset[i]
    prevoffset = [-1] * packn
    for i in range(0, len(payload.orttable), packn):
        orts = list(map(lambda x: x // 4, payload.orttable[i: i + packn]))
        orts = orts + [-1] * (packn - len(orts))  # -1 : dummy space
        pch = [orts[j] - prevoffset[j] for j in range(packn)]
        str_sled.append(sledheader_ort + tt.Trigger(
            players=[tt.AllPlayers],
            actions=[
                [tt.SetMemory(mrgn + 2408 + 328 + 32 * j + 16, tt.Add, pch[j])
                 for j in range(packn)],
            ]
        ))

        prevoffset = orts

    # jump to ort
    str_sled.append(sledheader_ort + tt.Trigger(
        players=[tt.AllPlayers],
        actions=[
            [tt.SetMemory(mrgn + 2408 + 328 + 32 * j + 16, tt.Add,
                          0xFFFFFFFF - prevoffset[j]) for j in range(packn)],
            tt.SetMemory(mrgn + 2408 + 4, tt.Add, 4)  # skip garbage area
        ]
    ))

    # sled completed
    str_sled = b''.join(str_sled)

    str_padding_length = -len(str_section) & 3
    strsled_offset = len(str_section) + str_padding_length
    payload_offset = strsled_offset + len(str_sled) + 4
    str_section = str_section + \
        bytes(str_padding_length) + str_sled + b'\0\0\0\0' + payload.data
    chkt.setsection('STR', str_section)

    ##############
    # MRGN SECTION
    ##############
    mrgn_trigger = []
    mrgn_trigger.append(
        bytes(4) + ut.i2b4(prttrg_start + strsled_offset) +
        tt.Trigger(
            players=[tt.AllPlayers],
            actions=[
                # SetDeaths actions in MRGN initially points to EPD(payload -
                # 4)
                [tt.SetMemory(payload_offset - 4, tt.Add, payload_offset // 4)
                 for _ in range(packn)],
                tt.SetMemory(mrgn + 4, tt.Add, 2408)
            ]
        )
    )

    mrgn_trigger.append(
        bytes(4) + ut.i2b4(orttrg_start + strsled_offset) +
        tt.Trigger(
            players=[tt.AllPlayers],
            actions=[
                [tt.SetMemory(payload_offset - 4, tt.Add, payload_offset)
                 for _ in range(packn)],
                tt.SetMemory(mrgn + 2408 + 4, tt.Add, 2408)
            ]
        )
    )

    mrgn_section = b''.join(mrgn_trigger) + bytes(5100 - 2408 * 2)
    chkt.setsection('MRGN', mrgn_section)

    ##############
    # TRIG SECTION
    ##############
    trglist.clear()

    # Check if epd is supported
    Trigger(
        actions=[
        tt.SetDeaths(-12, tt.SetTo, 1, 1)
    ])

    Trigger(
        conditions=[
            tt.Deaths(0, tt.Exactly, 0, 0)
        ],
        actions=[
            tt.DisplayText(eude_needed),
            tt.Draw()
        ]
    )

    # End trigger execution if EUDA is not supported
    #  - using condition #115 twice.
    Trigger(
        conditions=[
            tt.Deaths(0, tt.Exactly, 0, 0),
            tt.Condition(0, 0, 0, 0, 0, 115, 0, 0),
            tt.Condition(0, 0, 0, 0, 0, 115, 0, 0),
        ]
    )

    Trigger(actions=[
        tt.SetDeaths(-12, tt.SetTo, 0, 1)
    ])

    # -------

    # Init mrgn rawtrigger
    strs = 0x5993D4
    for e in range(31, 1, -1):
        # prt table
        # player
        Trigger(
            conditions=tt.Memory(strs, tt.AtLeast, 2 ** e),
            actions=[
                [tt.SetMemory(mrgn + 328 + 32 * i + 16, tt.Add, 2 ** (e - 2))
                 for i in range(packn)],
                tt.SetDeaths(11, tt.Add, 2 ** e, 0),
                [tt.SetMemory(mrgn + 328 + 32 * i + 20, tt.Add, 2 ** (e - 2))
                 for i in range(packn)],
                tt.SetMemory(mrgn + 4, tt.Add, 2 ** e),
                [tt.SetMemory(
                    mrgn + 2408 + 328 + 32 * i + 16, tt.Add, 2 ** (e - 2))
                 for i in range(packn)],
                tt.SetMemory(mrgn + 2408 + 4, tt.Add, 2 ** e),
                [tt.SetMemory(mrgn + 2408 + 328 + 32 * i + 20, tt.Add, 2 ** e)
                 for i in range(packn)],
                tt.SetMemory(strs, tt.Subtract, 2 ** e),
            ]
        )

    for e in range(31, 1, -1):
        Trigger(
            conditions=tt.Deaths(11, tt.AtLeast, 2 ** e, 0),
            actions=[
                tt.SetDeaths(11, tt.Subtract, 2 ** e, 0),
                tt.SetMemory(strs, tt.Add, 2 ** e)
            ]
        )

    # Payload update
    curpl = 0x6509B0

    # -------

    # pts[player].lasttrigger->next = value(strs) + strsled_offset

    pts = 0x51A280

    for player in range(8):
        triggerend = ~(0x51A284 + player * 12)

        Trigger(
            players=[player],
            actions=[
                tt.SetMemory(curpl, tt.SetTo, ut.EPD(pts + 12 * player + 4)),
                tt.SetDeaths(9, tt.SetTo, triggerend, 0)  # Used in stage 2
            ]
        )

    # read pts[player].lasttrigger
    for e in range(31, 1, -1):
        Trigger(
            conditions=tt.Deaths(tt.CurrentPlayer, tt.AtLeast, 2 ** e, 0),
            actions=[
                tt.SetDeaths(tt.CurrentPlayer, tt.Subtract, 2 ** e, 0),
                tt.SetDeaths(10, tt.Add, 2 ** e, 0),
                tt.SetDeaths(11, tt.Add, 2 ** e, 0),
            ]
        )

    for e in range(31, 1, -1):
        Trigger(
            conditions=tt.Deaths(10, tt.AtLeast, 2 ** e, 0),
            actions=[
                tt.SetDeaths(10, tt.Subtract, 2 ** e, 0),
                tt.SetDeaths(tt.CurrentPlayer, tt.Add, 2 ** e, 0)
            ]
        )

    # apply to curpl
    Trigger(actions=[
        tt.SetDeaths(10, tt.SetTo, ut.EPD(4), 0),
        tt.SetMemory(curpl, tt.SetTo, ut.EPD(4))
    ])
    for e in range(31, 1, -1):
        Trigger(
            conditions=tt.Deaths(11, tt.AtLeast, 2 ** e, 0),
            actions=[
                tt.SetDeaths(11, tt.Subtract, 2 ** e, 0),
                # used for nextptr recovery in stage 3
                tt.SetDeaths(10, tt.Add, 2 ** (e - 2), 0),
                tt.SetMemory(curpl, tt.Add, 2 ** (e - 2))
            ]
        )

    # now curpl = EPD(value(ptsprev) + 4)
    # value(EPD(value(ptsprev) + 4)) = strs + payload_offset
    CopyDeaths(tt.EPD(strs), tt.CurrentPlayer, False, strsled_offset)

    # Done!
    trigdata = b''.join(trglist)

    # Stage 1 created

    # -------

    # Previous rawtrigger datas

    oldtrigraw = chkt.getsection('TRIG')
    oldtrigs = [oldtrigraw[i:i + 2400]
                for i in range(0, len(oldtrigraw), 2400)]
    proc_trigs = []

    # Collect only enabled triggers
    for trig in oldtrigs:
        trig = bytearray(trig)
        flag = ut.b2i4(trig, 320 + 2048)
        if flag & 8:  # Trigger already disabled
            pass

        flag ^= 8  # Disable it temporarilly. It will be re-enabled at stage 3
        trig[320 + 2048: 320 + 2048 + 4] = ut.i2b4(flag)
        proc_trigs.append(bytes(trig))

    oldtrigraw_processed = b''.join(proc_trigs)
    chkt.setsection('TRIG', trigdata + oldtrigraw_processed)