示例#1
0
        public void Should_Check_Insert()
        {
            //arrange
            string          str1      = "Hello";
            string          str2      = "hello";
            string          resultStr = "Hehellollo";
            MyStringBuilder builder   = new MyStringBuilder(str1);

            //act
            var result = builder.Insert(2, str2);

            //assert
            result.ToString().ShouldBeEquivalentTo(resultStr);
        }
示例#2
0
        private static string cleandisasm(string[] lines)
        {
            var sb = new MyStringBuilder();

            string[] instr = new string[14];
            int      instrc;
            int      instrs             = 0;
            int      real_data_accesses = 0;
            int      real_base_accesses = 0;

            DATA.lvars.Clear();
            DATA.cache.Clear();
            SortedDictionary <int, A> stuff           = new SortedDictionary <int, A>();
            List <BASEADDRPATCH>      baseaddrpatches = new List <BASEADDRPATCH>();

            sb.Append(":ENTRY").AppendLine();
            sb.Append("hex").AppendLine();
            int _ = 0;

            if (lines[_].Trim().Replace("\r", "").Length == 0)
            {
                do
                {
                    _++;
                } while (!lines[_ - 1].StartsWith("00000000 <_main>"));
            }
            for (; _ < lines.Length; _++)
            {
                string _line = lines[_];
                try {
                    string line = _line.Trim().Replace("\r", "");
                    if (line.Length == 0)
                    {
                        continue;
                    }
                    if (line.EndsWith(":"))
                    {
                        if (comments)
                        {
                            sb.Append("// ").Append(line.Trim()).AppendLine();
                        }
                        continue;
                    }
                    instrc = 0;
                    int c = 1;
                    while (line[c - 1] != ':')
                    {
                        c++;
                    }
                    while (line[c] == ' ' || line[c] == '\t')
                    {
                        c++;
                    }
                    do
                    {
                        instr[instrc++] = new string(new char[] { line[c], line[c + 1] } );
                        c += 3;
                    } while (line[c] != ' ' && line [c] != '\t');
                    while (line[c] == ' ' || line[c] == '\t')
                    {
                        c++;
                    }
                    string comment = line.Substring(c);

                    // >>>>>>> nextline
                    // try to include next line if necessary
                    // for example:
                    //   test   DWORD PTR [esp+0x11223344],0x44332211
                    // results in:
                    // 0:  f7 84 24 44 33 22 11    test   DWORD PTR [esp+0x11223344],0x44332211
                    // 7:  11 22 33 44

tryparsenextline:
                    if (_ + 1 >= lines.Length)
                    {
                        goto skipnextline;
                    }

                    string nextline = lines[_ + 1].Replace("\r", "").Trim();
                    nextline = new Regex("^[0-9a-fA-F]+:\\s+").Replace(nextline, "");
                    string[] opcodes = nextline.Split(' ');
                    foreach (string oc in opcodes)
                    {
                        if (oc.Length != 2)
                        {
                            goto skipnextline;
                        }
                        try {
                            int.Parse(oc, NumberStyles.HexNumber);
                        } catch (Exception) {
                            goto skipnextline;
                        }
                    }

                    foreach (string oc in opcodes)
                    {
                        instr[instrc++] = new string(new char[] { oc[0], oc[1] } );
                    }

                    _++;
                    goto tryparsenextline;

skipnextline:
                    // <<<<<<< nextline

                    int si = 0;
                    if (instrc == 5 &&
                        (comment.StartsWith("call") || comment.StartsWith("jmp") || comment.StartsWith("je ") || comment.StartsWith("jne ")) &&
                        instraddr(instr) > 0x40000)
                    {
                        si = 1;
                        sb.Append(instr[0]).AppendLine();
                        instrs++;
                        stuff.Add(instrs, new JMPCALL());
                        int idx = comment.IndexOf(' ') + 1;
                        comment = comment.Substring(0, idx) + "0x" + realaddr(instr);
                        if (correctoffsets)
                        {
                            patchinstr(instr, 2 * instrs + 4);
                        }
                        else
                        {
                            patchinstr(instr, instrs);
                        }
                    }
                    for (int i = 1; i <= instrc - 4; i++)
                    {
                        int       type      = 0;
                        const int TYPE_DATA = 1;
                        const int TYPE_BASE = 2;
                        if (instr[i] == "ee" && instr[i + 1] == "ff" && instr[i + 3] == "ee")
                        {
                            type = TYPE_DATA;
                        }
                        else if (instr[i] == "ff" && instr[i + 1] == "ee" && instr[i + 2] == "ef" && instr[i + 3] == "ee")
                        {
                            type = TYPE_BASE;
                        }
                        else
                        {
                            continue;
                        }
                        for (; si < i; si++)
                        {
                            sb.Append(instr[si]).Append(' ');
                            instrs++;
                        }
                        switch (type)
                        {
                        case TYPE_DATA:
                            //stuff.Add(instrs, new DATA(instr[i + 2], (int.Parse(instr[i + 1], NumberStyles.HexNumber) << 8) | int.Parse(instr[i], NumberStyles.HexNumber)));
                            stuff.Add(instrs, new DATA(instr[i + 2], 0));
                            sb.AppendLine();
                            sb.Append("00 00 00 00 // DATA").Append(instr[i + 2]);
                            real_data_accesses++;
                            break;

                        case TYPE_BASE:
                            baseaddrpatches.Add(new BASEADDRPATCH(instrs));
                            sb.AppendLine();
                            sb.Append("00 00 00 00 // __BASEADDR");
                            real_base_accesses++;
                            break;
                        }
                        instrs += 4;
                        i      += 3;
                        si     += 4;
                        if (si < instrc)
                        {
                            sb.AppendLine();
                        }
                    }
                    for (; si < instrc; si++)
                    {
                        sb.Append(instr[si]).Append(' ');
                        instrs++;
                    }
                    sb.AppendLine();
                    if (comments)
                    {
                        sb.Append("// ").Append(comment.Trim()).AppendLine();
                    }
                } catch (Exception er) {
                    string result = er.ToString() + "\r\n" + _line;
                    MessageBox.Show(result);
                    return(result);
                }
            }
            sb.Append("end").AppendLine();
            var sb2 = new MyStringBuilder();

            sb2.Append("// this file is generated by asmtool").AppendLine();
            sb2.Append("// https://github.com/yugecin/scmcleoscripts/tree/master/tools/asm").AppendLine();
            sb2.AppendLine();
            sb2.Append(":HOOKER").AppendLine();
            sb2.Append("0AC6: 0@ = label @ENTRY offset").AppendLine();
            sb2.AppendLine();
            sb2.Append("0085: 1@ = 0@ // (int)").AppendLine();
            string[] hookadrs = new string[] {
                "",
                hookaddr.Substring(6, 2),
                hookaddr.Substring(4, 2),
                hookaddr.Substring(2, 2),
                hookaddr.Substring(0, 2),
            };
            sb2.Append("000E: 1@ -= 0x").Append(realaddr(hookadrs)).AppendLine();
            sb2.Append("0A8C: write_memory 0x").Append(i2hs(int.Parse(hookaddr, NumberStyles.HexNumber) - 1)).Append(" size 1 value 0xE9 vp 0").AppendLine();
            sb2.Append("0A8C: write_memory 0x").Append(hookaddr).Append(" size 4 value 1@ vp 0").AppendLine();
            sb2.AppendLine();
            sb2.Append("0AC6: 1@ = label @ENTRY offset").AppendLine();
            sb2.AppendLine();
            if (baseaddrpatches.Count > 0)
            {
                sb2.Append("0085: 2@ = 1@").AppendLine();
                foreach (BASEADDRPATCH p in baseaddrpatches)
                {
                    p.dostuff(sb2);
                }
                sb2.AppendLine();
            }
            int offset = 0;

            foreach (KeyValuePair <int, A> s in stuff)
            {
                int diff = s.Key - offset;
                sb2.Append("000A: 1@ += ").Append(diff).AppendLine();
                offset += diff;
                s.Value.dostuff(sb2);
            }
            sb2.AppendLine();
            sb2.Append("0002: jump @NOMOREHOOKER").AppendLine().AppendLine();
            sb.Insert(0, sb2.ToString());

            check(check_data_accesses, real_data_accesses, "data accesses");
            check(check_base_accesses, real_base_accesses, "base addr accesses");

            return(sb.ToString());
        }