Hi Evain,

I am facing another issue and since I am new to Cecil, I cannot find
what solution would be.

Now I am injecting a method in an assembly (currently it just returns
the string value passed to it as it is) which can be found in
following text.
Than I go through assembly and patch all "ldstr" so that the original
strings are passed to the injected methods and then the rturned value
is used by original ldstr. I got this technique from ncloak.

Now have a look at the following Search method which I have extracted
from my application. I have also posted the decompiled version of the
same method (using reflector). Also I have posted the decompiled
version of the "patched" Search method. Now it all looks ok to me BUT
I am getting following exception
    System.InvalidProgramException: Common Language Runtime detected
an invalid program.
      at WindowsFormsApplication1.Form1.Search(String criteria)
      at WindowsFormsApplication1.Form1.button1_Click(Object sender,
EventArgs e)

This code is being run from a winform application using just a button
whose event handler is
        private void button1_Click(object sender, EventArgs e)
        {
            Search("blah");
        }


And it happens only which I have complex (i mean more than just 2-3)
string concatinations which leads to creation of IL comprising of an
array of strings which gets concatenated at the end.


Hope I have explained my issue properly.

Thanks
Vijay


Original Search method

 public static void Search(string criteria)
        {
            var parameters = new ArrayList();
            var isNumeric = true;

            var query = "from "
                + "blah1  " + " src"
                + " where ("
                + " src." + "blah2" + " like ?"
                + (isNumeric ? " or src." + "blah3" + " = ?" :
string.Empty)
                + ((parameters != null && parameters.Count != 0) ? "
or src." + "blah4" + " in (" + "?" + ")" : string.Empty)
                + ")";

            query = query.ToLower();

            query += "from "
                + "blah1  " + " src"
                + " where ("
                + " src." + "blah2" + " like ?"
                + (isNumeric ? " or src." + "blah3" + " = ?" :
string.Empty)
                + ((parameters != null && parameters.Count != 0) ? "
or src." + "blah4" + " in (" + "?" + ")" : string.Empty)
                + ")";

            foreach (var c in query)
            {
                Console.WriteLine(c.ToString());
            }
        }


Original Search method decompiled (C#) (reflector):
public static void Search(string criteria)
{
    ArrayList parameters = new ArrayList();
    bool isNumeric = true;
    string CS$0$0000 = ("from blah1   src where ( src.blah2 like ?" +
(isNumeric ? " or src.blah3 = ?" : string.Empty) + (((parameters !=
null) && (parameters.Count != 0)) ? " or src.blah4 in (?)" :
string.Empty) + ")").ToLower();
    string[] CS$0$0001 = new string[] { CS$0$0000, "from blah1   src
where ( src.blah2 like ?", isNumeric ? " or src.blah3 = ?" :
string.Empty, ((parameters != null) && (parameters.Count != 0)) ? " or
src.blah4 in (?)" : string.Empty, ")" };
    string query = string.Concat(CS$0$0001);
    foreach (char c in query)
    {
        Console.WriteLine(c.ToString());
    }
}

Original Search method decompiled (IL) (reflector):
.method public hidebysig static void Search(string criteria) cil
managed
{
    .maxstack 4
    .locals init (
        [0] class [mscorlib]System.Collections.ArrayList parameters,
        [1] bool isNumeric,
        [2] string query,
        [3] char c,
        [4] string CS$0$0000,
        [5] string[] CS$0$0001,
        [6] string CS$6$0002,
        [7] int32 CS$7$0003,
        [8] bool CS$4$0004)
    L_0000: nop
    L_0001: newobj instance void
[mscorlib]System.Collections.ArrayList::.ctor()
    L_0006: stloc.0
    L_0007: ldc.i4.1
    L_0008: stloc.1
    L_0009: ldstr "from blah1   src where ( src.blah2 like ?"
    L_000e: ldloc.1
    L_000f: brtrue.s L_0018
    L_0011: ldsfld string [mscorlib]System.String::Empty
    L_0016: br.s L_001d
    L_0018: ldstr " or src.blah3 = ?"
    L_001d: ldloc.0
    L_001e: brfalse.s L_0028
    L_0020: ldloc.0
    L_0021: callvirt instance int32
[mscorlib]System.Collections.ArrayList::get_Count()
    L_0026: brtrue.s L_002f
    L_0028: ldsfld string [mscorlib]System.String::Empty
    L_002d: br.s L_0034
    L_002f: ldstr " or src.blah4 in (?)"
    L_0034: ldstr ")"
    L_0039: call string [mscorlib]System.String::Concat(string,
string, string, string)
    L_003e: stloc.2
    L_003f: ldloc.2
    L_0040: callvirt instance string
[mscorlib]System.String::ToLower()
    L_0045: stloc.2
    L_0046: ldloc.2
    L_0047: stloc.s CS$0$0000
    L_0049: ldc.i4.5
    L_004a: newarr string
    L_004f: stloc.s CS$0$0001
    L_0051: ldloc.s CS$0$0001
    L_0053: ldc.i4.0
    L_0054: ldloc.s CS$0$0000
    L_0056: stelem.ref
    L_0057: ldloc.s CS$0$0001
    L_0059: ldc.i4.1
    L_005a: ldstr "from blah1   src where ( src.blah2 like ?"
    L_005f: stelem.ref
    L_0060: ldloc.s CS$0$0001
    L_0062: ldc.i4.2
    L_0063: ldloc.1
    L_0064: brtrue.s L_006d
    L_0066: ldsfld string [mscorlib]System.String::Empty
    L_006b: br.s L_0072
    L_006d: ldstr " or src.blah3 = ?"
    L_0072: stelem.ref
    L_0073: ldloc.s CS$0$0001
    L_0075: ldc.i4.3
    L_0076: ldloc.0
    L_0077: brfalse.s L_0081
    L_0079: ldloc.0
    L_007a: callvirt instance int32
[mscorlib]System.Collections.ArrayList::get_Count()
    L_007f: brtrue.s L_0088
    L_0081: ldsfld string [mscorlib]System.String::Empty
    L_0086: br.s L_008d
    L_0088: ldstr " or src.blah4 in (?)"
    L_008d: stelem.ref
    L_008e: ldloc.s CS$0$0001
    L_0090: ldc.i4.4
    L_0091: ldstr ")"
    L_0096: stelem.ref
    L_0097: ldloc.s CS$0$0001
    L_0099: call string [mscorlib]System.String::Concat(string[])
    L_009e: stloc.2
    L_009f: nop
    L_00a0: ldloc.2
    L_00a1: stloc.s CS$6$0002
    L_00a3: ldc.i4.0
    L_00a4: stloc.s CS$7$0003
    L_00a6: br.s L_00c7
    L_00a8: ldloc.s CS$6$0002
    L_00aa: ldloc.s CS$7$0003
    L_00ac: callvirt instance char
[mscorlib]System.String::get_Chars(int32)
    L_00b1: stloc.3
    L_00b2: nop
    L_00b3: ldloca.s c
    L_00b5: call instance string [mscorlib]System.Char::ToString()
    L_00ba: call void [mscorlib]System.Console::WriteLine(string)
    L_00bf: nop
    L_00c0: nop
    L_00c1: ldloc.s CS$7$0003
    L_00c3: ldc.i4.1
    L_00c4: add
    L_00c5: stloc.s CS$7$0003
    L_00c7: ldloc.s CS$7$0003
    L_00c9: ldloc.s CS$6$0002
    L_00cb: callvirt instance int32
[mscorlib]System.String::get_Length()
    L_00d0: clt
    L_00d2: stloc.s CS$4$0004
    L_00d4: ldloc.s CS$4$0004
    L_00d6: brtrue.s L_00a8
    L_00d8: ret
}


Injected method (C#) (Added to <Module>)
public static string ExtractString(string v, int s)
{
    return v;
}


Injected method (IL) (Added to <Module>)
.method public hidebysig static string ExtractString(string v, int32
s) cil managed
{
    .maxstack 1
    .locals init (
        [0] string str)
    L_0000: nop
    L_0001: ldarg.0
    L_0002: stloc.0
    L_0003: br.s L_0005
    L_0005: ldloc.0
    L_0006: ret
}


Decompiled new method (C#)
public static void Search(string criteria)
{
    ArrayList list = new ArrayList();
    bool flag = true;
    string str2 = (ExtractString("from blah1   src where ( src.blah2
like ?", 0x170e) + (flag ? ExtractString(" or src.blah3 = ?",
0x1f76) : string.Empty) + (((list != null) && (list.Count != 0)) ?
ExtractString(" or src.blah4 in (?)", 0x1791) : string.Empty) +
ExtractString(")", 0x1801)).ToLower();
    string[] strArray = new string[] { str2, ExtractString("from
blah1   src where ( src.blah2 like ?", 0x269a), flag ? ExtractString("
or src.blah3 = ?", 0x1c2e) : string.Empty, ((list != null) &&
(list.Count != 0)) ? ExtractString(" or src.blah4 in (?)", 0x216e) :
string.Empty, ExtractString(")", 0x1acb) };
    string str = string.Concat(strArray);
    foreach (char ch in str)
    {
        Console.WriteLine(ch.ToString());
    }
}


Decompiled new method (IL)
.method public hidebysig static void Search(string criteria) cil
managed
{
    .maxstack 3
    .locals init (
        [0] class [mscorlib]System.Collections.ArrayList list,
        [1] bool flag,
        [2] string str,
        [3] char ch,
        [4] string str2,
        [5] string[] strArray,
        [6] string str3,
        [7] int32 num,
        [8] bool flag2)
    L_0000: nop
    L_0001: newobj instance void
[mscorlib]System.Collections.ArrayList::.ctor()
    L_0006: stloc.0
    L_0007: ldc.i4.1
    L_0008: stloc.1
    L_0009: ldstr "from blah1   src where ( src.blah2 like ?"
    L_000e: ldc.i4 0x170e
    L_0013: call string <Module>::ExtractString(string, int32)
    L_0018: ldloc.1
    L_0019: brtrue.s L_0022
    L_001b: ldsfld string [mscorlib]System.String::Empty
    L_0020: br.s L_0031
    L_0022: ldstr " or src.blah3 = ?"
    L_0027: ldc.i4 0x1f76
    L_002c: call string <Module>::ExtractString(string, int32)
    L_0031: ldloc.0
    L_0032: brfalse.s L_003c
    L_0034: ldloc.0
    L_0035: callvirt instance int32
[mscorlib]System.Collections.ArrayList::get_Count()
    L_003a: brtrue.s L_0043
    L_003c: ldsfld string [mscorlib]System.String::Empty
    L_0041: br.s L_0052
    L_0043: ldstr " or src.blah4 in (?)"
    L_0048: ldc.i4 0x1791
    L_004d: call string <Module>::ExtractString(string, int32)
    L_0052: ldstr ")"
    L_0057: ldc.i4 0x1801
    L_005c: call string <Module>::ExtractString(string, int32)
    L_0061: call string [mscorlib]System.String::Concat(string,
string, string, string)
    L_0066: stloc.2
    L_0067: ldloc.2
    L_0068: callvirt instance string
[mscorlib]System.String::ToLower()
    L_006d: stloc.2
    L_006e: ldloc.2
    L_006f: stloc.s str2
    L_0071: ldc.i4.5
    L_0072: newarr string
    L_0077: stloc.s strArray
    L_0079: ldloc.s strArray
    L_007b: ldc.i4.0
    L_007c: ldloc.s str2
    L_007e: stelem.ref
    L_007f: ldloc.s strArray
    L_0081: ldc.i4.1
    L_0082: ldstr "from blah1   src where ( src.blah2 like ?"
    L_0087: ldc.i4 0x269a
    L_008c: call string <Module>::ExtractString(string, int32)
    L_0091: stelem.ref
    L_0092: ldloc.s strArray
    L_0094: ldc.i4.2
    L_0095: ldloc.1
    L_0096: brtrue.s L_009f
    L_0098: ldsfld string [mscorlib]System.String::Empty
    L_009d: br.s L_00ae
    L_009f: ldstr " or src.blah3 = ?"
    L_00a4: ldc.i4 0x1c2e
    L_00a9: call string <Module>::ExtractString(string, int32)
    L_00ae: stelem.ref
    L_00af: ldloc.s strArray
    L_00b1: ldc.i4.3
    L_00b2: ldloc.0
    L_00b3: brfalse.s L_00bd
    L_00b5: ldloc.0
    L_00b6: callvirt instance int32
[mscorlib]System.Collections.ArrayList::get_Count()
    L_00bb: brtrue.s L_00c4
    L_00bd: ldsfld string [mscorlib]System.String::Empty
    L_00c2: br.s L_00d3
    L_00c4: ldstr " or src.blah4 in (?)"
    L_00c9: ldc.i4 0x216e
    L_00ce: call string <Module>::ExtractString(string, int32)
    L_00d3: stelem.ref
    L_00d4: ldloc.s strArray
    L_00d6: ldc.i4.4
    L_00d7: ldstr ")"
    L_00dc: ldc.i4 0x1acb
    L_00e1: call string <Module>::ExtractString(string, int32)
    L_00e6: stelem.ref
    L_00e7: ldloc.s strArray
    L_00e9: call string [mscorlib]System.String::Concat(string[])
    L_00ee: stloc.2
    L_00ef: nop
    L_00f0: ldloc.2
    L_00f1: stloc.s str3
    L_00f3: ldc.i4.0
    L_00f4: stloc.s num
    L_00f6: br.s L_0117
    L_00f8: ldloc.s str3
    L_00fa: ldloc.s num
    L_00fc: callvirt instance char
[mscorlib]System.String::get_Chars(int32)
    L_0101: stloc.3
    L_0102: nop
    L_0103: ldloca.s ch
    L_0105: call instance string [mscorlib]System.Char::ToString()
    L_010a: call void [mscorlib]System.Console::WriteLine(string)
    L_010f: nop
    L_0110: nop
    L_0111: ldloc.s num
    L_0113: ldc.i4.1
    L_0114: add
    L_0115: stloc.s num
    L_0117: ldloc.s num
    L_0119: ldloc.s str3
    L_011b: callvirt instance int32
[mscorlib]System.String::get_Length()
    L_0120: clt
    L_0122: stloc.s flag2
    L_0124: ldloc.s flag2
    L_0126: brtrue.s L_00f8
    L_0128: ret
}




-- 
--
mono-cecil

Reply via email to