about deleting methods from assembly

545 views
Skip to first unread message

david khan

unread,
Jun 18, 2010, 9:19:29 AM6/18/10
to mono-cecil
Hello,

Sorry i don't know exactly where to post and sending to your mail.
I have an assembly "test.exe" and structure is like that , there are
some treeview example like reflexil , netdasm , but i already know
which type and method i have to delete and i got list of methods and
types to delete .

test.exe
Form1
Dispose
InitializeComponent
aa
dd
button1_Click
Form2
Dispose
InitializeComponent
aa
xx
button1_Click
Resources
Settings
get_Default
Program
Main


I am trying to delete Types and methods, to delete types i use
like that

TypeDefinition type =
assembly.MainModule.Types["test.Form1"];
assembly.MainModule.Types.Remove(type);

and it is ok ,but how do i delete method "test.Form1.aa" , i use this
way but no success



foreach (TypeDefinition type in assembly.MainModule.Types)
{
if (type.Name == "Form1")
{

foreach (MethodDefinition method in type.Methods)
{
if (method.Name == "bb")
{
type.Methods.Remove(method);

}
}

}
}


So can anybody advice how to delete methods and is there simple way to
delete like if i want to delete method "aa" of type "Form1" , just
give url of assembly like that
type.Methods.Remove("test.Form1.aa");



Many thanks

Jb Evain

unread,
Jun 18, 2010, 9:28:00 AM6/18/10
to mono-...@googlegroups.com
Hey,

On Fri, Jun 18, 2010 at 3:19 PM, david khan <nain...@gmail.com> wrote:
>            TypeDefinition type =
> assembly.MainModule.Types["test.Form1"];
>            assembly.MainModule.Types.Remove(type);

Please upgrade to Cecil 0.9.3.

http://github.com/jbevain/cecil

> So can anybody advice how to delete methods and is there simple way to
> delete like if i want to delete method "aa" of type "Form1" , just
> give url of assembly like that
>          type.Methods.Remove("test.Form1.aa");
>

You can solve that very easily with an extension method:

public static void RemoveMethod (this TypeDefinition self, string methodName)
{
var method = self.Methods.FirstOrDefault (m => m.Name == methodName);
if (method == null)
return;

self.Methods.Remove (method);
}

Note that this will delete the first method with the specified name,
and it's common to find methods with the same names.

--
Jb Evain <j...@nurv.fr>

david khan

unread,
Jun 18, 2010, 10:01:11 AM6/18/10
to mono-cecil
Many thanks for reply, Sorry can you explain about
"FirstOrDefault" , i got error monocecil does not contain a definition
for "FirstOrDefault" , i use library from "http://anonsvn.mono-
project.com/source/trunk/mcs/class/Mono.Cecil/" or is there any
different build.


Thanks

On Jun 18, 2:28 pm, Jb Evain <j...@nurv.fr> wrote:
> Hey,
>

Jb Evain

unread,
Jun 18, 2010, 10:03:50 AM6/18/10
to mono-...@googlegroups.com
On Fri, Jun 18, 2010 at 4:01 PM, david khan <nain...@gmail.com> wrote:
>          Many thanks for reply, Sorry can you explain about
> "FirstOrDefault" , i got error monocecil does not contain a definition
> for "FirstOrDefault" ,  i use library from "http://anonsvn.mono-
> project.com/source/trunk/mcs/class/Mono.Cecil/" or is there any
> different build.

I just gave you a link to the repository for Cecil 0.9:

http://github.com/jbevain/cecil

As for FirstOrDefault, it's a LINQ method:

http://msdn.microsoft.com/en-us/library/system.linq.enumerable.firstordefault.aspx

It requires .net 3.5 though.

--
Jb Evain <j...@nurv.fr>

david khan

unread,
Jun 18, 2010, 10:55:47 AM6/18/10
to mono-cecil
Thank for you reply , i build the version from http://github.com/jbevain/cecil
, but there is no assemblyfactory definition so i can't load
AssemblyDefinition assembly =
Mono.Cecil.AssemblyFactory.GetAssembly("test.exe");

Any solution for that?

Thanks

On Jun 18, 3:03 pm, Jb Evain <j...@nurv.fr> wrote:
> On Fri, Jun 18, 2010 at 4:01 PM, david khan <naing...@gmail.com> wrote:
> >          Many thanks for reply, Sorry can you explain about
> > "FirstOrDefault" , i got error monocecil does not contain a definition
> > for "FirstOrDefault" ,  i use library from "http://anonsvn.mono-
> > project.com/source/trunk/mcs/class/Mono.Cecil/" or is there any
> > different build.
>
> I just gave you a link to the repository for Cecil 0.9:
>
> http://github.com/jbevain/cecil
>
> As for FirstOrDefault, it's a LINQ method:
>
> http://msdn.microsoft.com/en-us/library/system.linq.enumerable.firsto...

Jb Evain

unread,
Jun 18, 2010, 11:23:41 AM6/18/10
to mono-...@googlegroups.com
On Fri, Jun 18, 2010 at 4:55 PM, david khan <nain...@gmail.com> wrote:
> Any solution for that?

http://wiki.github.com/jbevain/cecil/migration

--
Jb Evain <j...@nurv.fr>

david khan

unread,
Jun 18, 2010, 11:45:03 AM6/18/10
to mono-cecil
Ok, finall done with this style coding

public static class Class1
{

public static void RemoveMethod(this TypeDefinition self,
string methodName)
{
var method = self.Methods.FirstOrDefault(m => m.Name ==
methodName);
if (method == null)
return;

self.Methods.Remove(method);

}
}

private void button1_Click(object sender, EventArgs e)
{
var asm =AssemblyDefinition.ReadAssembly("test.exe");
TypeDefinition type = asm.MainModule.Types[1];
Class1.RemoveMethod(type, "aa");
asm.Write(".exe");
}


But the problem i got is "asm.MainModule.Types[1];" , before cecil
library i could use "asm.MainModule.Types["Form1"]; , i mean i could
use string "Form1" , but now i have to find out first which one is
Types [1] or [0] or [2]. Please advise anyway i could use string like
before, as i have about 100 methods to delete.


Many thanks


On Jun 18, 4:23 pm, Jb Evain <j...@nurv.fr> wrote:

Jb Evain

unread,
Jun 18, 2010, 11:54:27 AM6/18/10
to mono-...@googlegroups.com
On Fri, Jun 18, 2010 at 5:45 PM, david khan <nain...@gmail.com> wrote:
> Please advise anyway i could use string like
> before, as i have about 100 methods to delete.

You would have read the migration guide you would know. Use
ModuleDefinition.GetType(string).

--
Jb Evain <j...@nurv.fr>

david khan

unread,
Jun 18, 2010, 12:03:49 PM6/18/10
to mono-cecil
Many thanks for your patient Evain , finally i sort it out, i will
read the migration guide and try other functions as well, if there is
out of my knowledge, i will start new thread.


Many thanks again

On Jun 18, 4:54 pm, Jb Evain <j...@nurv.fr> wrote:

david khan

unread,
Jun 18, 2010, 3:52:44 PM6/18/10
to mono-cecil
Hello Evain,

Sorry i got one simple question about one thing i have notice , from
the above assembly , by using this code

private void button2_Click(object sender, EventArgs e)
{
var asm = AssemblyDefinition.ReadAssembly("test.exe");

TypeDefinition type =
asm.MainModule.GetType("test.Form1");
asm.MainModule.Types.Remove(type);
asm.Write("ccc.exe");

}


I can delete type test.Form2, test.Program etc but why i cannot delete
Form1 , there is exception thrown nullreference when
asm.Write("ccc.exe"); , basically program is when button press form2
show. Similarly if there is

test
Form1
Form2
Form3
Form4 I cannot delete Form1/form2/form3 and only form4 i can
delete, Any idea?

Many thanks






On Jun 18, 4:54 pm, Jb Evain <j...@nurv.fr> wrote:

Jb Evain

unread,
Jun 18, 2010, 5:36:08 PM6/18/10
to mono-...@googlegroups.com
On Fri, Jun 18, 2010 at 9:52 PM, david khan <nain...@gmail.com> wrote:
> Hello Evain,

Hello Khan,

> I can delete type test.Form2, test.Program etc but why i cannot delete
> Form1 , there is exception thrown nullreference when
> asm.Write("ccc.exe");

Two things here.

First, Cecil should not throw a NullReferenceException, could you
paste the full stacktrace?
Second, it probably means that you're removing something blindly that
is used elsewhere.

--
Jb Evain <j...@nurv.fr>

david khan

unread,
Jun 19, 2010, 6:41:45 AM6/19/10
to mono-cecil
Hello Evain,
Thanks for your info, today i have test about 7 EXE , they all the
same, and notice that we cannot delete these classes, so if you test
on any EXE with the code above , the result should be the same.


Here is the stack trace

++++++++++++++++++++++++++++

Mono.Cecil.dll!
Mono.Cecil.MetadataBuilder.LookupToken(Mono.Cecil.IMetadataTokenProvider
provider = null) + 0x75 bytes
Mono.Cecil.dll!
Mono.Cecil.Cil.CodeReader.PatchRawCode(Mono.Cecil.PE.ByteBuffer buffer
= {Mono.Cecil.PE.ByteBuffer}, int code_size = 15,
Mono.Cecil.Cil.CodeWriter writer = {Mono.Cecil.Cil.CodeWriter}) +
0x3b7 bytes
Mono.Cecil.dll!
Mono.Cecil.Cil.CodeReader.PatchRawFatMethod(Mono.Cecil.PE.ByteBuffer
buffer = {Mono.Cecil.PE.ByteBuffer}, Mono.Cecil.Cil.MethodSymbols
symbols = {Mono.Cecil.Cil.MethodSymbols}, Mono.Cecil.Cil.CodeWriter
writer = {Mono.Cecil.Cil.CodeWriter}, out Mono.Cecil.MetadataToken
local_var_token = {[Signature:0x0002]}) + 0x1c1 bytes
Mono.Cecil.dll!
Mono.Cecil.Cil.CodeReader.PatchRawMethodBody(Mono.Cecil.MethodDefinition
method = {System.Void
test.Form1::button2_Click(System.Object,System.EventArgs)},
Mono.Cecil.Cil.CodeWriter writer = {Mono.Cecil.Cil.CodeWriter}, out
Mono.Cecil.Cil.MethodSymbols symbols = {Mono.Cecil.Cil.MethodSymbols})
+ 0x16f bytes
Mono.Cecil.dll!
Mono.Cecil.Cil.CodeWriter.WriteUnresolvedMethodBody(Mono.Cecil.MethodDefinition
method = {System.Void
test.Form1::button2_Click(System.Object,System.EventArgs)}) + 0xe3
bytes
Mono.Cecil.dll!
Mono.Cecil.Cil.CodeWriter.WriteMethodBody(Mono.Cecil.MethodDefinition
method = {System.Void
test.Form1::button2_Click(System.Object,System.EventArgs)}) + 0x9d
bytes
Mono.Cecil.dll!
Mono.Cecil.MetadataBuilder.AddMethod(Mono.Cecil.MethodDefinition
method = {System.Void
test.Form1::button2_Click(System.Object,System.EventArgs)}) + 0x82
bytes
Mono.Cecil.dll!
Mono.Cecil.MetadataBuilder.AddMethods(Mono.Cecil.TypeDefinition type =
{test.Form1}) + 0x80 bytes
Mono.Cecil.dll!
Mono.Cecil.MetadataBuilder.AddType(Mono.Cecil.TypeDefinition type =
{test.Form1}) + 0x22e bytes
Mono.Cecil.dll!Mono.Cecil.MetadataBuilder.AddTypeDefs() + 0x80
bytes
Mono.Cecil.dll!Mono.Cecil.MetadataBuilder.BuildTypes() + 0x68 bytes
Mono.Cecil.dll!Mono.Cecil.MetadataBuilder.BuildModule() + 0x179
bytes
Mono.Cecil.dll!Mono.Cecil.MetadataBuilder.BuildMetadata() + 0x2d
bytes
Mono.Cecil.dll!
Mono.Cecil.ModuleWriter.BuildMetadata.AnonymousMethod(Mono.Cecil.MetadataBuilder
builder = {Mono.Cecil.MetadataBuilder}, Mono.Cecil.MetadataReader _ =
{Mono.Cecil.MetadataReader}) + 0x42 bytes
Mono.Cecil.dll!
Mono.Cecil.ModuleDefinition.Read<Mono.Cecil.MetadataBuilder,Mono.Cecil.MetadataBuilder>(Mono.Cecil.MetadataBuilder
item = {Mono.Cecil.MetadataBuilder},
Mono.Func<Mono.Cecil.MetadataBuilder,Mono.Cecil.MetadataReader,Mono.Cecil.MetadataBuilder>
read = {Method = {Mono.Cecil.MetadataBuilder
<BuildMetadata>b__0(Mono.Cecil.MetadataBuilder,
Mono.Cecil.MetadataReader)}}) + 0x79 bytes
Mono.Cecil.dll!
Mono.Cecil.ModuleWriter.BuildMetadata(Mono.Cecil.ModuleDefinition
module = {test.exe}, Mono.Cecil.MetadataBuilder metadata =
{Mono.Cecil.MetadataBuilder}) + 0xda bytes
Mono.Cecil.dll!
Mono.Cecil.ModuleWriter.WriteModuleTo(Mono.Cecil.ModuleDefinition
module = {test.exe}, System.IO.Stream stream = {System.IO.FileStream},
Mono.Cecil.WriterParameters parameters =
{Mono.Cecil.WriterParameters}) + 0x2db bytes
Mono.Cecil.dll!Mono.Cecil.ModuleDefinition.Write(System.IO.Stream
stream = {System.IO.FileStream}, Mono.Cecil.WriterParameters
parameters = {Mono.Cecil.WriterParameters}) + 0xaf bytes
Mono.Cecil.dll!Mono.Cecil.ModuleDefinition.Write(string fileName =
"ccc.exe", Mono.Cecil.WriterParameters parameters =
{Mono.Cecil.WriterParameters}) + 0x68 bytes
Mono.Cecil.dll!Mono.Cecil.ModuleDefinition.Write(string fileName =
"ccc.exe") + 0x4b bytes
cecil.exe!cecil.Form1.button3_Click(object sender = {Text =
"button3"}, System.EventArgs e = {X = 49 Y = 13 Button = Left}) Line
112 + 0x10 bytes C#
System.Windows.Forms.dll!
System.Windows.Forms.Control.OnClick(System.EventArgs e) Line 8414 C#
System.Windows.Forms.dll!
System.Windows.Forms.Button.OnClick(System.EventArgs e) Line 279 C#
System.Windows.Forms.dll!
System.Windows.Forms.Button.OnMouseUp(System.Windows.Forms.MouseEventArgs
mevent = {X = 49 Y = 13 Button = Left}) Line 308 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseUp(ref
System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons
button, int clicks) Line 13042 + 0x2a5 bytes C#
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref
System.Windows.Forms.Message m) Line 13772 C#
System.Windows.Forms.dll!System.Windows.Forms.ButtonBase.WndProc(ref
System.Windows.Forms.Message m) Line 1306 + 0x9 bytes C#
> System.Windows.Forms.dll!System.Windows.Forms.Button.WndProc(ref System.Windows.Forms.Message m) Line 400 C#
System.Windows.Forms.dll!
System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref
System.Windows.Forms.Message m) Line 14059 C#
System.Windows.Forms.dll!
System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref
System.Windows.Forms.Message m) Line 14114 C#
System.Windows.Forms.dll!
System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr
hWnd, int msg = 514, System.IntPtr wparam, System.IntPtr lparam) Line
777 + 0xa bytes C#
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!
System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int
dwComponentID, int reason = -1, int pvLoopData = 0) Line 2106 + 0x8
bytes C#
System.Windows.Forms.dll!
System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int
reason = -1, System.Windows.Forms.ApplicationContext context =
{System.Windows.Forms.ApplicationContext}) Line 3377 + 0x1b bytes C#
System.Windows.Forms.dll!
System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int
reason, System.Windows.Forms.ApplicationContext context) Line 3261 +
0xc bytes C#
System.Windows.Forms.dll!
System.Windows.Forms.Application.Run(System.Windows.Forms.Form
mainForm) Line 1466 C#
cecil.exe!cecil.Program.Main() Line 18 + 0x1e bytes C#
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile,
System.Security.Policy.Evidence assemblySecurity, string[] args) Line
931 + 0x1f bytes C#
Microsoft.VisualStudio.HostingProcess.Utilities.dll!
Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() +
0x2b bytes
mscorlib.dll!
System.Threading.ThreadHelper.ThreadStart_Context(object state) Line
55 + 0x29 bytes C#
mscorlib.dll!
System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext
executionContext, System.Threading.ContextCallback callback, object
state) Line 355 + 0xd bytes C#
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() Line 82 +
0x21 bytes C#
++++++++++++++++++++++++++++++++++++++



and EXCEPTION

+++++++++++++++++++++++++++++++++++++

************** Exception Text **************
System.ArgumentNullException: Value cannot be null.
at Mono.Cecil.MetadataBuilder.LookupToken(IMetadataTokenProvider
provider)
at Mono.Cecil.Cil.CodeReader.PatchRawCode(ByteBuffer buffer, Int32
code_size, CodeWriter writer)
at Mono.Cecil.Cil.CodeReader.PatchRawFatMethod(ByteBuffer buffer,
MethodSymbols symbols, CodeWriter writer, MetadataToken&
local_var_token)
at Mono.Cecil.Cil.CodeReader.PatchRawMethodBody(MethodDefinition
method, CodeWriter writer, MethodSymbols& symbols)
at
Mono.Cecil.Cil.CodeWriter.WriteUnresolvedMethodBody(MethodDefinition
method)
at Mono.Cecil.Cil.CodeWriter.WriteMethodBody(MethodDefinition
method)
at Mono.Cecil.MetadataBuilder.AddMethod(MethodDefinition method)
at Mono.Cecil.MetadataBuilder.AddMethods(TypeDefinition type)
at Mono.Cecil.MetadataBuilder.AddType(TypeDefinition type)
at Mono.Cecil.MetadataBuilder.AddTypeDefs()
at Mono.Cecil.MetadataBuilder.BuildTypes()
at Mono.Cecil.MetadataBuilder.BuildModule()
at Mono.Cecil.MetadataBuilder.BuildMetadata()
at Mono.Cecil.ModuleWriter.<BuildMetadata>b__0(MetadataBuilder
builder, MetadataReader _)
at Mono.Cecil.ModuleDefinition.Read[TItem,TRet](TItem item, Func`3
read)
at Mono.Cecil.ModuleWriter.BuildMetadata(ModuleDefinition module,
MetadataBuilder metadata)
at Mono.Cecil.ModuleWriter.WriteModuleTo(ModuleDefinition module,
Stream stream, WriterParameters parameters)
at Mono.Cecil.ModuleDefinition.Write(Stream stream,
WriterParameters parameters)
at Mono.Cecil.ModuleDefinition.Write(String fileName,
WriterParameters parameters)
at Mono.Cecil.ModuleDefinition.Write(String fileName)
at cecil.Form1.button3_Click(Object sender, EventArgs e) in C:\Users
\Visual Studio 2008\Projects\ceciltest\ceciltest\Form1.cs:line 112
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons
button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at
System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at
System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32
msg, IntPtr wparam, IntPtr lparam)

+++++++++++++++++++++++++++++++++++++++++






Many Thanks






On Jun 18, 10:36 pm, Jb Evain <j...@nurv.fr> wrote:

david khan

unread,
Jun 19, 2010, 6:53:16 AM6/19/10
to mono-cecil
Sorry i want to be more clarify, as i said all about "i cannot delete"
means "i cannot save after delete these items using
"asm.Write("ccc.exe");"

Thanks
> ...
>
> read more »

Jb Evain

unread,
Jun 19, 2010, 6:57:47 AM6/19/10
to mono-...@googlegroups.com
On Sat, Jun 19, 2010 at 12:53 PM, david khan <nain...@gmail.com> wrote:
> Sorry i want to be more clarify, as i said all about "i cannot delete"
> means "i cannot save after delete these items using
> "asm.Write("ccc.exe");"

As I said, it's because you blindly remove a type while it's still
referenced somewhere in the assembly.

--
Jb Evain <j...@nurv.fr>

david khan

unread,
Jun 19, 2010, 7:06:32 AM6/19/10
to mono-cecil
Thanks for your info , so could you tell me how to save it?

Thanks

On Jun 19, 11:57 am, Jb Evain <j...@nurv.fr> wrote:

david khan

unread,
Jun 19, 2010, 8:27:14 AM6/19/10
to mono-cecil
Hello Evan,
I have create new application , and in my application there is only
one button and only this code below , test on many assembly , so i
don't think it is still reference somewhere.

private void button1_Click(object sender, EventArgs e)
{
var asm = AssemblyDefinition.ReadAssembly("test.exe");
TypeDefinition type =
asm.MainModule.GetType("test.Form1");
asm.MainModule.Types.Remove(type);
asm.Write("ccc.exe");
}


Thanks



On Jun 19, 11:57 am, Jb Evain <j...@nurv.fr> wrote:
Reply all
Reply to author
Forward
0 new messages