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

Prolog sanity check failed - multiple inheritance offsets #275

Open
Detectronic-PB opened this issue Nov 26, 2024 · 15 comments
Open

Prolog sanity check failed - multiple inheritance offsets #275

Detectronic-PB opened this issue Nov 26, 2024 · 15 comments
Assignees

Comments

@Detectronic-PB
Copy link

I'm getting this error trying to run OOProlog on a Kensington firmware update utility:

Consistency checks failed.
Class 0x587970 inherits from 0x569a4c at offsets 0 and 0x244
Initial sanity check failed, indicating the OO rules are incorrect.

There are several warnings/errors at the OOAnalyzer stage which may be related.


Container Version: seipharos/pharos:latest (sha256:fe09ad8e492115b7a1cfe0899995fa37057089d695d73332aa633b7f696f33bd)

Input file: KensingtonUpdate.exe

API database JSON files: ApiJson.zip

Logs: Logs.zip

Partition command:

partition
    --serialize=kensington/kensington-sem.ser
    --maximum-memory=10240
    kensington/KensingtonUpdate.exe

Analyzer command:

ooanalyzer
    --serialize=kensington/kensington-sem.ser
    --new-method=0x4116a6
    --new-method=0x4116d8
    --new-method=0x42f692
    --delete-method=0x42f6ae
    --delete-method=0x53b4c0
    --maximum-memory 18000
    --per-function-maximum-memory=0
    --prolog-facts=kensington/kensington-facts.pl
    --threads=1
    --per-function-timeout=600
    --apidb=/usr/local/share/pharos/contrib/winspool.json
    --apidb=kensington/hid.xml.json
    --apidb=kensington/gdiplus.xml.json
    --apidb=kensington/SetupAPI.xml.json
    --apidb=kensington/UxTheme.xml.json
    --apidb=kensington/Imm32.xml.json
    --apidb=kensington/Msimg32.xml.json
    --apidb=kensington/Oleacc.xml.json
    --apidb=kensington/User32.xml.json
    --apidb=kensington/OleDlg.xml.json
    kensington/KensingtonUpdate.exe

Note: --threads=1 is to avoid a multithread issue that I'll submit/add to another issue for.

Prolog command:

ooprolog
    --facts kensington/kensington-facts.pl
    --results kensington/kensington-results.pl
    --log-level=6
@Detectronic-PB
Copy link
Author

Forgot the facts:
Facts.zip

@sei-eschwartz
Copy link
Collaborator

Thanks, I will take a look at this. The threading problem is probably #267.

@sei-eschwartz
Copy link
Collaborator

Working backwards...

Consistency checks failed.
Class 0x587970 inherits from 0x569a4c at offsets 0 and 0x244
Merging class 0x50b8db into 0x587970 ...
reasonMergeVFTables_A(constructor, 0x587970, 0x50b8db, 0x587970, 0, factVFTableWrite(0x50b8f8, 0x50b8db, 0, 0x587970)).

@sei-eschwartz
Copy link
Collaborator

[eschwartz@pd4 ooanalyzer-tests]$ /home/mwd/git/plogtrace/plogtrace.py ./code/testcases/kensington/kensington.exe.results.log 'factObjectInObject(0x587970, 0x569a4c, 0x244)'
1487178: Retracting factObjectInObject(0x50b8db, 0x569a4c, 0x244) and asserting factObjectInObject(0x587970, 0x569a4c, 0x244) ...
1487060: Merging class 0x50b8db into 0x587970 ...
895020: Retracting factObjectInObject(0x50b8db, 0x426738, 0x244) and asserting factObjectInObject(0x50b8db, 0x569a4c, 0x244) ...
894951: Merging class 0x426738 into 0x569a4c ...
152343: Concluding factObjectInObject(0x50b8db, 0x426738, 0x244).
reasonObjectInObject_D(0x50b8db, 0x426738, 0x244, validMethodCallAtOffset(0x50b92d, 0x50b8db, 0x426738, 0x244)).
% This rule is a special case of the reasonObjectInObject_E, that relies on the fact that it
% does not matter whether the InnerClass and OuterClass are provably different or whether
% they're just currently not assigned to the same class.  The key observation is that the
% distinction only matters when offset is non-zero, because that fact alone rules out the
% possibility that the two classes are in fact the same class.

@sei-eschwartz
Copy link
Collaborator

0x587970 is the vftable for .?AVCMFCPropertyGridCtrl@@
and 0x569a4c is the vftable for .?AVCWnd@@

@sei-eschwartz
Copy link
Collaborator

According to this:

class CMFCPropertyGridCtrl : public CWnd

So what is going on with the offset at 0x244?

@Detectronic-PB
Copy link
Author

Just to add some more information in case it's relevant.

I identified 3 new operators and 2 delete operators, in a potentially strange configuration:

  • 0x004116a6 is the main new operator
  • 0x0053b4c0 is the main delete operator
  • 0x004116d8 is a wrapper around the main new operator
  • 0x0042f692 is CNoTrackObject::operator_new
  • 0x0042f6ae is CNoTrackObject::operator_delete

Having double checked these just now I've found a wrapper for the main delete operator as well, I will try running again with that one defined.

@sei-eschwartz
Copy link
Collaborator

At 0x50b92d of 0x50b8db (probably MFCPropertyGridCtrl's constructor), we call 0x426738 at offset 0x244.

@sei-eschwartz
Copy link
Collaborator

sub_426738 proc near
push    esi
mov     esi, ecx
call    sub_42305A
xor     eax, eax
mov     dword ptr [esi], offset ??_7CWnd@@6B@ ; const CWnd::`vftable'
mov     dword ptr [esi+30h], offset ??_7XAccessible@CWnd@@6B@ ; const CWnd::XAccessible::`vftable'
mov     dword ptr [esi+34h], offset ??_7XAccessibleServer@CWnd@@6B@ ; const CWnd::XAccessibleServer::`vftable'
mov     [esi+3Ch], eax
mov     [esi+40h], eax
or      dword ptr [esi+3Ch], 0FFFFFFFFh
or      dword ptr [esi+40h], 0FFFFFFFFh
mov     [esi+20h], eax
mov     [esi+24h], al
mov     [esi+38h], eax
mov     [esi+2Ch], eax
mov     [esi+28h], eax
mov     [esi+54h], eax
mov     [esi+58h], eax
mov     [esi+5Ch], eax
mov     [esi+60h], eax
mov     [esi+64h], eax
mov     [esi+68h], eax
mov     [esi+6Ch], eax
mov     [esi+70h], eax
mov     [esi+44h], eax
mov     [esi+48h], eax
mov     [esi+4Ch], eax
mov     [esi+50h], eax
mov     eax, esi
pop     esi
retn
sub_426738 endp

@sei-eschwartz
Copy link
Collaborator

According to OOAnalyzer, 0x426738 is CWnd::CWnd.

@sei-eschwartz
Copy link
Collaborator

I think the MFC classes in this program are triggered a rare-but-not-unknown problem in a sanity rule, insanityInheritTwice. Comment out this line and try to run again.

@Detectronic-PB
Copy link
Author

Initial results are promising, it's on to the guess phase.

As an aside, are any of the errors in the analysis log concerning? I'm assuming it will just result in slightly less information extracted than otherwise.

@sei-eschwartz
Copy link
Collaborator

Nothing too concerning, especially for a program of that size

@Detectronic-PB
Copy link
Author

Detectronic-PB commented Nov 29, 2024

After a few adjustments to memory and swap on the container I'm now getting:

reasoningLoop: post-reason sanityChecks
failed.
Consistency checks failed.
Contradictory information about constructor: factConstructor(0x426738) but reasonNOTConstructor(0x426738)
Constraint checks failed, retracting guess!
....
Fail-Retracting factNOTConstructor(0x4f7de3)...
setting numGroup to 0x2 failed so setting to 1
Fail-Retracting guessedNOTConstructor(0x52b9d4)...
Fail-Retracting factNOTConstructor(0x52b9d4)...
tryBinarySearch completely failed on [0x52b9d4] and will now backtrack to fix an upstream problem.
guess: We have back-tracked to the call of tryBinarySearch(tryConstructor, tryNOTConstructor, [0x52b9d4, 0x4c96e7, 0x424cde, 0x415931, 0x536cb0, 0x5357ff, 0x52d483, 0x52d050, 0x52867f, 0x52856d, 0x527ea9, 0x527ae7, 0x521244, 0x5142c3, 0x50813f, 0x502989, 0x4f8465, 0x4dcf68, 0x4d193e, 0x4cfe49, 0x4ccd22, 0x4ca61a, 0x4bfb3e, 0x4aa46f, 0x4a9fc1, 0x4a7719, 0x4a0e6c, 0x499ec9, 0x471a5b, 0x45786b, 0x43cf62, 0x43a0a2, 0x4302d3, 0x425e15, 0x425d6d, 0x4153f0, 0x41467c, 0x4133ec, 0x4133c5])
Refusing to backtrack into reasoningLoop to fix an upstream problem because backtrackForUpstream/0 is not set.

Full log: prolog.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants