News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

ResGuard for Framework C

Started by Biterider, August 24, 2023, 06:24:17 AM

Previous topic - Next topic

Biterider

Hi
I just uploaded the updated version of ResGuard to the GitHub repo. Now it can also be compiled for 64 bit, but the frame analysis and forwarding did not work properly, however the 32 bit counterpart works as expected.
Reworking the existing code forced me to think again about all the details and I wrote a lot more comments to understand what I did in the next iteration of the code.  :biggrin:

For the 64-bit version, stackwalking is much more complicated and requires the use of additional information that is not on the stack. There are some APIs that make the task easier, like StackWalk64, but they need to be implemented properly, which will take a little more time.

To find leaks, the 32-bit version must be used for the time being.  :wink2:

Biterider


Biterider

Hi
I tested the debug services for ResGuard and was really impressed with how useful they are, so I thought I should share it.  :cool:

At the moment, leaked resources are detected as before, but the call stack up to the API call that triggered the leak can be reconstructed and visualised in DebugCenter.
The current test environment shows, for example, the API name, the name of the calling procedure and the address where the call was made up to the start of the application.

──────────────────────────────────────────────────────────────────────
 • CreateBitmap « P2(00007FF789F748EEh)
                 « P1(00007FF789F7492Fh)
                  « P0(00007FF789F7494Ah)
                   « start(00007FF789F7517Eh)
 • CreateRectRgn « P2(00007FF789F74904h)
                  « P1(00007FF789F7492Fh)
                   « P0(00007FF789F7494Ah)
                    « start(00007FF789F7517Eh)
 • GlobalAlloc « StrAllocW(00007FF789F7670Bh)
                « StrNewW(00007FF789F754D1h)
                 « P2(00007FF789F74913h)
                  « P1(00007FF789F7492Fh)
                   « P0(00007FF789F7494Ah)
                    « start(00007FF789F7517Eh)
 • BeginPaint « OA_Application_OnPaint(00007FF789F74C1Eh)
               « OA_Window_WndProc(00007FF789F725F0h)
                « CallWindowProcW(00007FFDF4F8E858h)
                 « DispatchMessageW(00007FFDF4F8E3DCh)
                  « SendMessageTimeoutW(00007FFDF4FA0C33h)
                   « KiUserCallbackDispatcher(00007FFDF5D50E94h)
                    « NtUserCallHwndLock(00007FFDF3531464h)
                     « OA_Application_Init(00007FF789F74A2Ah)
                      « start(00007FF789F7518Fh)
──────────────────────────────────────────────────────────────────────

Unfortunately, the 32-bit API counterpart behaves a little differently, so the code path has to be changed.  :sad:

Regards, Biterider

HSE

Hi Biterider,

Quote from: Biterider on August 29, 2023, 05:52:13 AMUnfortunately, the 32-bit API counterpart behaves a little differently, so the code path has to be changed.  :sad:

Old method with today long addresses don't look so good. Beside, with this more informative format, you could search in source code instead of only X64DBG disassemble :thumbsup:

HSE
Equations in Assembly: SmplMath

Biterider

Hi HSE
The "old" hooking method has proven to work perfectly on 32-bit and 64-bit targets, and that's a big deal. 
The stack tracing features provided by the operating system are the new additions that help effectively locate the API call that caused the leak or failed call.

The visualization is also important, but I am far from saying that this is the final version. It should just be a small taste. If there are any suggestions on this, they are very welcome. At the moment nothing is fixed and can be modeled as we like.  :thumbsup:

Biterider

HSE

Hi Biterider,


Quote from: Biterider on August 29, 2023, 05:19:27 PMThe "old" hooking method has proven to work perfectly on 32-bit and 64-bit targets, and that's a big deal.

That work perfectly, pretty easy  :rolleyes:

Last time I "play", resource theoretically is released from linked list and collection, but still is counted like a leak  :biggrin:  :biggrin:

More to play  :thumbsup:

Quote from: Biterider on August 29, 2023, 05:19:27 PMIf there are any suggestions on this, they are very welcome.

:thumbsup:

HSE
Equations in Assembly: SmplMath

Biterider

Hi HSE
This is the new look and feel, which is more in line with the classic design.

Started
Leak Report:
Global Mem-Blocks:  cur. =   1, max. =     2, tot. =     3
 • GlobalAlloc ← StrAllocW(00007FF60B5C670Bh) ← StrNewW(00007FF60B5C54D1h) ← P2(00007FF60B5C4913h) ← P1(00007FF60B5C492Fh) ← P0(00007FF60B5C494Ah) ← start(00007FF60B5C517Eh)
Heap Mem-Blocks:    cur. =   1, max. =     1, tot. =     1
 • HeapAlloc ← P2(00007FF60B5C4719h) ← P1(00007FF60B5C492Fh) ← P0(00007FF60B5C494Ah) ← start(00007FF60B5C517Eh)
GDI Brushes:        cur. =   2, max. =     2, tot. =     2
 • CreateSolidBrush ← P2(00007FF60B5C486Ah) ← P1(00007FF60B5C492Fh) ← P0(00007FF60B5C494Ah) ← start(00007FF60B5C517Eh)
 • CreateSolidBrush ← P2(00007FF60B5C48C9h) ← P1(00007FF60B5C492Fh) ← P0(00007FF60B5C494Ah) ← start(00007FF60B5C517Eh)
GDI Bitmaps:        cur. =   1, max. =     1, tot. =     1
 • CreateBitmap ← P2(00007FF60B5C48EEh) ← P1(00007FF60B5C492Fh) ← P0(00007FF60B5C494Ah) ← start(00007FF60B5C517Eh)
GDI Regions:        cur. =   1, max. =     1, tot. =     1
 • CreateRectRgn ← P2(00007FF60B5C4904h) ← P1(00007FF60B5C492Fh) ← P0(00007FF60B5C494Ah) ← start(00007FF60B5C517Eh)
Failed API calls:   3
 • CreateFileW ← P2(00007FF60B5C4700h) ← P1(00007FF60B5C492Fh) ← P0(00007FF60B5C494Ah) ← start(00007FF60B5C517Eh)
 • CreateFileW ← P2(00007FF60B5C489Eh) ← P1(00007FF60B5C492Fh) ← P0(00007FF60B5C494Ah) ← start(00007FF60B5C517Eh)
 • DeleteObject ← P2(00007FF60B5C48BEh) ← P1(00007FF60B5C492Fh) ← P0(00007FF60B5C494Ah) ← start(00007FF60B5C517Eh)
Stopped

The catch with ResGuard is that it has to be updated with every OS update when new APIs are introduced. Fortunately, the old classic GDI and USER APIs are well covered.

Biterider

HSE

Hi Biterider,

Quote from: Biterider on August 30, 2023, 04:46:19 PMThis is the new look and feel, which is more in line with the classic design.

Fantastic  :thumbsup:


Quote from: Biterider on August 30, 2023, 04:46:19 PMOS update when new APIs are introduced.

Really? I think I'm using same APIs available in Win95  :biggrin:

HSE
Equations in Assembly: SmplMath

Biterider

Hi
I have finished both code paths and will update the repo tonight. 
The code has the character of a beta version.  :cool:

I had to update the "model.inc" file to pass some parameters to the ResGuard system so that the stack would stop running at the boundary of the application and not enter the operating system.

It is important to know that symbolic information from the pdb file is required to display the procedure names. In the vast majority of cases this is not a problem, since the compilation target is always DEBUG when using ResGuard.

Another change is the introduction of a flag called SUFFIX in the SysSetup macro, which adds a "32" or "64" to the end of the generated files. The import lib takes this into account as well.

Biterider

Biterider

Hi
Finally done, both code paths work the same. I have uploaded the complete code (still beta) for testing. The correct selection of the 32/64 bit DLL is done automatically. This means that the handling is identical to previous versions  :cool:

In the testing process I discovered a small bug on DebugCenter, that was also updated (ver 2.2.1).

Biterider

Biterider

Hi
When adding some new APIs, I noticed that the system "named objects" need special handling and that the detour procedure has to pay attention to whether the name is local or global.

Affected are: named Pipes, Mailslots, WaitableTimers, FileMappings etc. 
As long as you do not reuse the names, they all work fine. The problem arises when the objects are reused with the same name.

The next version will take care of that.  :cool:

Biterider

HSE

Hi Biterider,

Quote from: Biterider on September 03, 2023, 09:16:40 PMThe problem arises when the objects are reused with the same name.

You mean same name in different namespace ¿?

HSE
Equations in Assembly: SmplMath

Biterider

Hi HSE
It is easier to explain this with an example: CreateEventExA

QuoteReturn value
If the function succeeds, the return value is a handle to the event object. If the named event object existed before the function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.

In the case that you have called this API more than once with the same name, which is perfectly legal, ResGuard must be aware of this situation. Fortunately, the affected APIs return the same HANDLE for such calls. 
This way, the previous calls (and all associated information) can be discarded, leaving only the last call. 
Whether the names are local or global is less relevant, as I don't want to keep track of them.

Biterider


HSE

Ok. A Windows object, like a window class in return of RegisterClass.  :thumbsup:

Thanks, HSE.
Equations in Assembly: SmplMath

Biterider

Hi
While reviewing the examples and projects from the ObjAsm project with the new ResGuard version, I noticed that there is a borderline case. This occurs when a system object handle is obtained in a non-standard way.

For example, when the WM_CTLCOLORSTATIC message is used with a control and it returns a brush that is deleted by accident. In this case, ResGuard tries internally to remove the call data when deleting the object, but does not find it and thus an error occurs. In the current ResGuard implementation, this case is considered a ResGuard internal error and an error message is issued.

Actually, this situation can be used to detect logic errors in the examined code. I can imagine introducing a new category to the 2 already existing ones: "Leaks", "Fails" and new "Logic errors".

Biterider

HSE

Equations in Assembly: SmplMath