串行时字符串溢出

时间:2012-03-22 18:59:45

标签: c#

我正在尝试创建一个程序打包程序,但我总是失败,因为当我连接三个字符串(一个包含源的前缀,一个包含可执行内容,其他包含源的后缀)内容溢出到后缀。代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.IO;
using System.IO.Compression;

namespace ProgramPacker
{
    public partial class Form1 : Form
    {
        static string prefix = @"using System;
using System.Collections.Generic;
using System.Text; 
using System.IO; 

namespace ProgramPacker 
{ 
    class Program 
    { 
        static string inside = @" + "\"";
        static string suffix = "\";\n" + @"static void Main(string[] args) 
        { 
            string temp = Path.GetRandomFileName() +" + "\"" + @".exe" + "\"" + @";
            BinaryWriter sw = new BinaryWriter(new FileStream(temp, FileMode.Create));
            sw.Write(inside);
            sw.Flush();
            sw.Close();
            System.Diagnostics.Process.Start(temp); 
        } 
    } 
}";
    public string code = "";
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        openFileDialog1.ShowDialog();
        BinaryReader br = new BinaryReader(new FileStream(openFileDialog1.FileName, FileMode.Open));
        byte[] data = new byte[br.BaseStream.Length];
        br.Read(data, 0, (int)br.BaseStream.Length);
        br.Close();
        string inside = Encoding.UTF7.GetString(data);
        code = string.Concat(prefix, string.Concat(inside, suffix));
    }

    private void button2_Click(object sender, EventArgs e)
    {
        Console.Write(code);
        CSharpCodeProvider cs = new CSharpCodeProvider();
        ICodeCompiler compile = cs.CreateCompiler();
        CompilerParameters param = new CompilerParameters();
        param.GenerateInMemory = false;
        param.ReferencedAssemblies.Add("mscorlib.dll");
        param.ReferencedAssemblies.Add("System.dll");
        param.ReferencedAssemblies.Add("System.Core.dll");
        param.GenerateExecutable = true;
        param.OutputAssembly = Environment.CurrentDirectory + "/a.exe";
        param.WarningLevel = 4;
        CompilerResults comp = compile.CompileAssemblyFromSource(param, code);
        foreach (CompilerError error in comp.Errors)
        {
            MessageBox.Show(error.Line + " " + error.Column + " "  + error.ErrorText);
        }
        MessageBox.Show(comp.PathToAssembly);
        MessageBox.Show("Finish!");
    }
}

}

输出:

using System;
using System.Collections.Generic;
using System.Text; 
using System.IO; 

namespace ProgramPacker
{ 
    class Program 
    { 
        static string inside = @"?ãÎoüoy±ôãøÿ?ÿQÔh¦Rt!?^ÿyóë=G:Fÿ»??¿Ç/}òKÿ?úõßû3õMù?c·?Äûòëoª?À_Û>LÖïá^öÿ·õ©üüòcÊ?ª??÷Ô?î:^ȯÏäG¶?ù ?ñË?oñëy:ôã7??ò@ÚyN?w¿=?ëÆ÷ëÛßTëºÓ»yßüø]áå{ö/àïªêL©Oÿ;ú5rù% ä¸?1)Ï?¥?y®ÿ]0QL8û×ÖGòów±?øÿèü[?ª~éá¿ÿó£üüJ~ܹ
Êw¡h??/?úçeñÈ_?¿?ü½L^ywü7?,ùÅû¿ß£ó÷w?É~Ç????ê?ÿQÌyç¿??¹Cö×vZ__>?? ûïx?_ü"õ!ì; ;ùõåÇ?ú3*­¿   @ÿV?èÿ¿Ë??/½P¶y?â¡??ùñÿÑæä/A¶_ò?v??ÿ?ÿQtÄx÷w?O'N?u$ÿk÷U«yÆò?£.Y?ùw(?ßÔ6ÿ]2ÿeUÆò¿?ضö·ßO~ü#*y£Jæ·Ä w yóYëï´
õ}y¡ä¨ù÷YPdú?Z©Óé¼R?æg?ÀSyà쬽Éÿ­ûÁ?ym>ut?ÿA??>?¿[ôçF ê´)9ß9xÿ£¿?
åùïyí ÁTlù
-ùñ?Òÿ·!·
E?£üO5÷]çºy?7Áè¿?Zô?(å§
#ü¥úõ®?o«âû]0Èßä7¿à??¿õ?d?ѵ;Jü_K?úAMìT>Àü1mR0sâ¿ê¨õ{äö×ó??¿.úÿõ½Eä?ÔïÿÎÿ±³v'ÿûìw ?»oÃø1±WtB
É¡wì&øuå£Îÿ?Éw?|úWÿ=ö÷_ÿ·?y®YWöwû¿ßß?Öe'û?%?yß/×Àî-yÿ.?8åóù?ûÇÚ6ÿÂßøï?Áàï?{8Zy?¿Å5yø    ÇpÏ9=ó»üÑ>Õ?Èÿ?Y¿,?ëÿ?Êçÿì_}E?÷Ûú|î$ò÷ø}Jÿ^Êtò¿?@á|ò{Ø`<ªÿQ?QLæ½õo)¿ü&¿áÂÿ¼ó¿_÷7yMå8)¿Ùo'¿õ±üü=~#LÚ¿ó§¢Ë÷üO?Æ?å÷WJÍ$¾¸øW?A?Òÿ(09Áÿà³_ëÿù3l?SWYµßô÷¤~?ÀG¿ñ
??Às%ÍyÑ;Ò¸!ÿ?_Iÿ¼¼í/Ôrö
?T´ôÑùyǹßE~üV?ñ¿C~VßùuÿG   X8|._¼Å_:Æü-?îü:?øì?|W  ¤ÃÓW01?$å×?Û#ùIÿû·1:4û½ü._y^òÙNó?º1?ßIÍ?ÿ¿ß_~|ÖùX?@?në_B?¡µ~_×ãÿhãèïØÏßì¡yïôk_y;HÿÛyÿàâ/sÀ??? $ìw0Jüßü«@?ûo?¿îËX
´úÏ?Æ?Y>øçÿFpyÅÿèËöyK¡²Ì`}ù½Ò¿íÿÀñn"?Í?ëOëi»ò¹Î~çÿ?_òüîÿh£ôáêDøÏÿ¶?ç·fy ÄúçÿÖÿ?yÿ?¿?ã0ÿ¿Ë÷åå?ÿQ|ü/ü9¿?÷×Hè×ÉÏ#õ??æ?ÿâ?x?ß?5µ}~Øy¾ß^øè{¿
y{íü;Òÿ¿óú7¤¡î?»    yû?ÀÓøiP?ÿÀ_ôK?Gëªíá@??ú%íwS×ñ¿¨#Û¦ÿÿÛªy\]¼÷Z~yR~ü¶ÿ£hû???ÇãÿQVèÿ©?÷{O?Gë¬ ??¡ø\«L` æcëí¿ ½?»?ü?oë¼Ätÿ>ò÷£­_¯ÖiÄ?¯ÿÓ¿÷Ï?(c¦äàéûèó?ü£´çÕè4üy_
r?qÆ¿ø'?KÿÀ_ó×xùkÔ¿FõkÌ~õ¯1y5Ú_ã'??n~âר~å¯ñkü»¿Æø×رÿÿ5~?_ã7ø5~Í_ã?Z4ÔrñkL~ò׸?5Òßûÿ??ñïñnQ¦?yYÕò³vÇ;¥ùrZÍ?åÅg}õæÙöÁGiÓfËYVVËü³®óæ£ßãè7NgM?/&åuJrustInfo>
</assembly>
; 
        } 
    } 
}

任何帮助?

编辑:为什么每个人都投票?我刚问了一个问题。

4 个答案:

答案 0 :(得分:4)

请勿使用裸UTF7或UTF8字符串,而是使用Base64编码。

// given: byte[] data = new byte[...]
string inside = System.Convert.ToBase64String(data);
code = string.Concat(prefix, string.Concat(inside, suffix));    

// in your target code
sw.Write(System.Convert.FromBase64String(inside));

答案 1 :(得分:1)

最好使用CodeCompileUnit从C#程序生成C#代码: http://msdn.microsoft.com/en-us/library/system.codedom.codecompileunit.aspx

您也可以使用它将生成的ATS编译成汇编。

或者从文件中解析模板部分。这将使代码更具可读性。

答案 2 :(得分:1)

您不能将可执行二进制代码表示为C#字符串而不必转义它。至少你需要用两个双引号字符的序列替换任何出现的双引号字符('"')。如果那是你遇到的唯一问题,我会非常惊讶。

请注意,字符串可能包含控制字符,导致屏幕以乱码方式显示字符串,但这不一定会导致包含该字符串的代码编译不正确。例如,如果你有一个包含退格的逐字字符串(例如"stac{backspace}koverflow"),退格后面的字符会覆盖退格前的字符,因此在屏幕上查看字符串会导致其内容的表示不准确("stakoverflow")。编译器可能会看到包含退格的完整14个字符的字符串。

答案 3 :(得分:1)

你遇到了一个代表问题,你可能无法按原样修复代码问题。

但是,你可以选择只采用类似的方法进行微小的修改(实际上根本不会压缩你的程序)。

  1. 从字符串@的定义中删除inside。这是导致问题的原因之一。
  2. 您不能只在字符串中插入BELL字符或NUL字符,而是写出他们的unicode转义序列:

    string inside = String.Concat(
        data.Select(b => String.Format(@"\u{0:X4}", b)));
    
  3. 现在,在您的suffix代码中,将您的inside字符串重新解释为您转换为字节的字符:

    sw.Write(inside.Select(c => (byte)c).ToArray()); // hardly efficient
    
  4. 我能够使用这些修改并成功“打包”并执行以下操作:

    C:\temp>type hello.cs 
    using System;
    class M {
    static void Main(string[] args) {
    System.IO.File.Create("hello.world");
    }
    }
    
    C:\temp>csc hello.cs 
    Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
    Copyright (C) Microsoft Corporation. All rights reserved.
    
    
    C:\temp>pack.exe hello.exe 
    3584 bytes
    
    C:\temp>a.exe
    
    C:\temp>dir *.world 
     Volume in drive C is OSDisk
     Volume Serial Number is AABD-D663
    
     Directory of C:\temp
    
     03/22/2012  16:36                 0 hello.world
                   1 File(s)              0 bytes
                   0 Dir(s)  279,351,762,944 bytes free