Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add debug section to exe #10

Open
Trass3r opened this issue Jan 11, 2020 · 7 comments
Open

add debug section to exe #10

Trass3r opened this issue Jan 11, 2020 · 7 comments
Labels
component/pe help wanted Extra attention is needed type/enhancement New feature or request

Comments

@Trass3r
Copy link
Contributor

Trass3r commented Jan 11, 2020

referencing the newly created pdb.

@Mixaill Mixaill added the type/enhancement New feature or request label Jan 11, 2020
@jfm535
Copy link

jfm535 commented Jul 21, 2021

a possible way todo this would be to store a kind of template debug section for both x86 and x64 targets and configure it as necessary on the fly before writing it to the dll/exe

@jfm535
Copy link

jfm535 commented Jul 21, 2021

typedef struct _IMAGE_DEBUG_DIRECTORY {
  DWORD Characteristics;
  DWORD TimeDateStamp;
  WORD  MajorVersion;
  WORD  MinorVersion;
  DWORD Type;
  DWORD SizeOfData;
  DWORD AddressOfRawData;
  DWORD PointerToRawData;
} IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY;

this seems to be the format for a debug directory entry

struct CV_INFO_PDB70
{
  DWORD  CvSignature;
  GUID Signature;
  DWORD Age;
  BYTE PdbFileName[];
} ;

And this seems to be the format of the inner debug data.
source used: http://beefchunk.com/documentation/sys-programming/os-win32/debug/www.debuginfo.com/articles/debuginfomatch.html

@sunbeam906
Copy link

Adding to this:

Some of the executables I created a fake .pdb for with IDA labels have the Debug Directory stripped. In this case, it would need to artificially be added to the executable. At the same time, if a fake random PDB id is generated, it would have to be patched in the executable as well.

P.S.: If you know any PE Editors that let you add the Debug Directory on the fly, do let me know.

@jfmherokiller
Copy link

jfmherokiller commented Aug 5, 2021

Sadly I dont know of any pe editors that expose that functionality. A possibly simple outcome would be to expand the executable's last section a certain number of bytes or add a new section at the end of the executable.

@sunbeam906
Copy link

sunbeam906 commented Aug 5, 2021

I've sorted it out.

  1. To "create" the Debug Directory, you need to find a spot where to write 0x1C bytes. I recommend using an existing section, at the end of it, rather than creating a new empty section. Why.. because PE Editors, as well as tools that parse the exe will not find the RSDS data (Debug Directory) information if an empty section, last section of the executable, and at the end of the section.

I planted it as I saw in most executables, at the end of .rdata section:

image

image

  1. Then patch the Debug Directory RVA and Size in your PE editor (I use CFF Explorer):

image

Size is always 0x1C bytes.

  1. Then patch in the Debug Directory information:

image

  1. Then patch in the RSDS information (in my case AddressOfRawData points to where this should be; I put it close by so it's continguous -> 000A6200 + 400000 = 4A6200):

image

SizeOfData represents the whole block + null terminator. The RSDS section has to have the first 4 characters as 'RSDS', then GUID as the next 16 bytes, then Age as DWORD (01 00 00 00) and lastly the path to the pdb. I chose to use the pdb name directly, no path given. The GUID is also something random (well, a GUID I borrowed from another pdb).

Once you've done all this, ONLY THEN open the executable in IDA and dump the fake .pdb. WHY? Because if you've done your work right, this will happen:

FakePDB/generate pdb (with function labels):
    * generating JSON: C:\Users\SunBeam\Desktop\debug\lithtech.exe.json
    * generating PDB: C:\Users\SunBeam\Desktop\debug\lithtech.pdb
    * symserv EXE id: b'3AE746D9C7000'
    * symserv PDB id: b'3810F85E542A40B394ABED5EDF1399C31'
    * done

Instead of:

FakePDB/generate pdb (with function labels):
    * generating JSON: F:\Games\NOLF\lithtech.exe.json
    * generating PDB: F:\Games\NOLF\lithtech.pdb
    * symserv EXE id: b'3AE746D9C7000'
    * symserv PDB id: b'00000000000000000000000'
    * done

Notice how, without a Debug Directory, the symserv PDB id is 0. If you patch your executable beforehand, then FakePDB will read that information and use it when generating the PDB ;)

I've opened a ticket here thinking it was an x64dbg issue not being able to load the .pdb. The x64dbg author mentioned in there that you can force the pdb to be loaded by editing the x32dbg/x64dbg .ini to force load the pdb. Might work without all the work I mentioned above.. to just load the .pdb in.. Thought it'd be interesting for you to read up on it :)

BR,
Sun

@Mixaill Mixaill added component/pe help wanted Extra attention is needed labels Aug 26, 2021
@Trass3r
Copy link
Contributor Author

Trass3r commented Aug 30, 2021

P.S.: If you know any PE Editors that let you add the Debug Directory on the fly, do let me know.

There is none but CFF Explorer is scriptable, here's a starting point:

filename = GetOpenFile()
pehandle = OpenFile(filename)

local random = math.random
local function uuid()
    local template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
    return string.gsub(template, '[xy]', function (c)
        local v = (c == 'x') and random(0, 0xf) or random(8, 0xb)
        return string.format('%x', v)
    end)
end
math.randomseed(os.time())
function string.random(length)
	local randomString = ''
	for i = 1, length do
		randomString = randomString .. string.char(math.random(0, 255))
	end
	return randomString
end

data = "RSDS" .. string.random(16) .. string.char(1, 0, 0, 0) .. "executablenamebuffer.pdb"
AddSectionWithData(pehandle, data, ".debug", IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_CNT_INITIALIZED_DATA)

@kweatherman
Copy link

kweatherman commented Jul 19, 2023

As this page points out: https://lordjeb.com/2023/03/10/how-the-hell-things-work-how-windows-debugger-finds-symbols-for-your-code/
The debugger (WindDbg et al) will actually look first for a GUID that is made up of the module timestamp plus the size of the module (which incidentally makes smaller GUID).

So if the module doesn't have a debug section, the debugger will look for the short GUID version,

If you manually add a module pdb to you're symbol store doing:
symstore.exe add /f MyModule.pdb /s C:\ProgramData\Dbg\sym /t AnyName
("C:\ProgramData\Dbg\sym" is the default WinDbg symbol store location, yours might be different.)
It should figure automatically make the shorter GUID version when it sees it doesn't have the other.
Worth a try.

If the tool doesn't. Then you can manually create it using a script.

At any rate do:

!sym noisy
.reload /i /v /f MyModule.dll

It will show the search for the PDB and you'll see the problem if any.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component/pe help wanted Extra attention is needed type/enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants