Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find a byte offset in a .NET Assembly

Tags:

.net

I'm trying to debug an error that the client has reported to us. The stacktrace only has byte offsets, not line numbers.

e.g.

[NullReferenceException: Object reference not set to an instance of an object.]
Foo.Bar(FooFoo p) +32
Foo.BarBar() +191
Foo.BarBarBar() +15

How can I reverse engineer these byte offsets into lines of code / method calls etc?

How can I find where the NullReferenceException is being thrown?

like image 453
Greg B Avatar asked Feb 03 '11 12:02

Greg B


3 Answers

Here is a solution that might work (or may be not :) ). The problem is that the mapping between offset and line numbers is contained in pdb (aka the debug symbols)

  1. Take exactly (important) same build configuration as the one that was used to ship binaries to client. Then go to project properties, tab "Build", click button "Advanced" on the bottom of the page. Then find "Debug Info" and select "pdb-only"
  2. Build the project and go to output folder.
  3. Pick ildasm, either add it to PATH or copy it somewhere.
  4. In your build folder do ildasm /LINENUM /SOURCE YourFile.exe. It will output IL with offset and source line mapping.

The only problem that I see that you will not be able to produce exactly same binaries and mapping might fluctate.

like image 128
Andrey Avatar answered Oct 01 '22 22:10

Andrey


The only tool I can remember off the top of my head would be the .NET Reflector. Open the exactly same binary as your client has in it, and change the language in the Options dialog into IL, and it should show (AFAIK) the same byte offsets as labels on each line.

You'll have to read IL instead of C# or anything though, but it's better than nothing.

like image 38
Matti Virkkunen Avatar answered Oct 01 '22 23:10

Matti Virkkunen


  1. Open your project in visual studio
  2. Put breakpoint on Foo.Bar(FooFoo p)
  3. Compile and start debugging. Do action that will invoke Foo.Bar(FooFoo p). Note that you need to use configuration that was used to produce client assembly (because of optimization) and of course same source code
  4. Open Call Stack window, right click and enable "Show byte offsets" and disable "Show line numbers"
  5. Step through function until you hit something like "MyAssembly.dll!MyProject.Something.Foo.Bar(FooFoo p) + 0x32 bytes" (or "+ 0x20 bytes" if your offset decimal number)
  6. Win

Edit: Andreys solution is probably better tho :)

like image 43
Lukáš Novotný Avatar answered Oct 01 '22 23:10

Lukáš Novotný