PDA

View Full Version : Exploring CFG (Control Flow Guard)


Kayaker
May 22nd, 2019, 18:32
EDIT: Posts moved from another thread into a new topic


I've been looking at Control Flow Guard (CFG) lately

https://docs.microsoft.com/en-us/windows/desktop/secbp/control-flow-guard

Code:
What is Control Flow Guard?

Control Flow Guard (CFG) is a highly-optimized platform security feature that was created to combat memory corruption vulnerabilities.
By placing tight restrictions on where an application can execute code from, it makes it much harder for exploits to execute arbitrary code through vulnerabilities such as buffer overflows.
CFG extends previous exploit mitigation technologies such as /GS, DEP, and ASLR.



and this Windbg extension

https://github.com/JKornev/cfgdump

Code:
cfgdump

Windbg extension that allows you analyze Control Flow Guard map

!cfgcover - prints memory map that is covered by CFG map and shows which region are protected by CFG bits
!cfgrange <address> <size> - prints CFG bits for specified address range
!cfgdump - prints all CFG bits for whole address space
!cfgmap - prints available CFG maps



I'm trying to rebuild it from source since it doesn't work as written on my system. I've gotten to the stage where I need to look at memory regions in Windbg to sort out access and locations. So that's why I'm playing with Windbg lately.

This thread should be split at some point if it goes off topic.

blabberer
May 29th, 2019, 08:11
@kayaker
I just glanced the git downloaded and gave it a spin in 2017 community x64 with 10.17763 sdk (vs asked if I upgrade the vcxproj and I said yes)
added the linker ->input->def to cfg.def (for exporting the DECLARE_API() commands)
fixed four warnings (163,165,263 cfgdump.cpp | 37 helper.cpp)
and it compiles and links on both 32 bit as well as 64 bits

but executing the !xxxx it errs with cant find CFGMap on calc.exe (both 32 as well as 64 on w10)

I dump-binned the calc.exe for /loadcfg and it seems it is cfg instrumented

so it is debug time I think (where are you struck with it)

here is a dumpbin output for calc.exe (64 bit w10)


Code:
C:\>dumpbin /loadconfig c:\Windows\System32\calc.exe
Microsoft (R) COFF/PE Dumper Version 14.16.27027.1
Copyright (C) Microsoft Corporation. All rights reserved.


Dump of file c:\Windows\System32\calc.exe

File Type: EXECUTABLE IMAGE

Section contains the following load config:

00000108 size
0 time date stamp
0.00 Version
0 GlobalFlags Clear
0 GlobalFlags Set
0 Critical Section Default Timeout
0 Decommit Free Block Threshold
0 Decommit Total Free Threshold
0000000000000000 Lock Prefix Table
0 Maximum Allocation Size
0 Virtual Memory Threshold
0 Process Heap Flags
0 Process Affinity Mask
0 CSD Version
0000 Dependent Load Flag
0000000000000000 Edit List
0000000140003040 Security Cookie
0000000140002258 Guard CF address of check-function pointer
0000000140002260 Guard CF address of dispatch-function pointer
00000001400022A0 Guard CF function table
9 Guard CF function count
00017500 Guard Flags
CF instrumented
FID table present
Protect delayload IAT
Delayload IAT in its own section
Export suppression info present
Long jump target table present
0000 Code Integrity Flags
0000 Code Integrity Catalog
00000000 Code Integrity Catalog Offset
00000000 Code Integrity Reserved
0000000000000000 Guard CF address taken IAT entry table
0 Guard CF address taken IAT entry count
0000000000000000 Guard CF long jump target table
0 Guard CF long jump target count
0000000000000000 Dynamic value relocation table
0000000000000000 Hybrid metadata pointer
0000000000000000 Guard RF address of failure-function
0000000000000000 Guard RF address of failure-function pointer
00000000 Dynamic value relocation table offset
0000 Dynamic value relocation table section
0000 Reserved2
0000000000000000 Guard RF address of stack pointer verification function pointer
00000000 Hot patching table offset
0000 Reserved3
0000000000000000 Enclave configuration pointer
0000000000000000 Volatile metadata pointer

Guard CF Function Table

Address
--------
0000000140001010 _TlgEnableCallback
0000000140001340 __report_gsfailure
0000000140001490
0000000140001570
0000000140001830 wWinMainCRTStartup
0000000140001850 ?__CxxUnhandledExceptionFilter@@YAJPEAU_EXCEPTION_POINTERS@@@Z (long __cdecl __CxxUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *))
0000000140001890 __CxxSetUnhandledExceptionFilter
0000000140001970 _matherr
0000000140001A80 _guard_check_icall_nop

Summary

1000 .data
1000 .pdata
1000 .rdata
1000 .reloc
5000 .rsrc
1000 .text


if you are going to continue I would suggest split this

Kayaker
May 29th, 2019, 08:41
Hi Blabberer, thanks for taking a look. I got the same thing, compiled but CFGMap doesn't work as written. I didn't get to your Guard CF dump, but started to dfprint output in the loops trying to figure out the logic of the algo. Process Explorer has a CFG column that can be used to find processes that use the feature.

I won't be able to take a look at this again until late next week, so we can get back to it then. Cheers.

Elenil
June 2nd, 2019, 03:53
nice to see all the old guys are still somehow around

i tryed around with ollydbg on some applications that use the the CFG by microsoft, that kayaker was talking about

and ollydbg seems to be chanceless against this

i tryed it with this setup (targets where windows 7 32 bit and 64 bit):
https://github.com/romanzaikin/OllyDbg-v1.10-With-Best-Plugins-And-Immunity-Debugger-theme-


then i gone to some other applications and they also cause high amounts of detections what where not CFG related
maybe i do something wrong here ? or is ollydbg on its limit when it comes to CFG ?

so i think microsoft actually working together with those people its certainly not for the user
its rather for other companys that want more control about the computer their software

i also tryed out my old hidetool it seems microsoft have done something here too

version 6.6.7.5 of symserv function dll does no longer work correctly it doesnt load the sym files from the microsoft server
if it already has the files all is ok


what i did then was download a new version from microsoft symchk.exe(10.0.16), symsrv.dll (10.0.16),dbghelp.dll (10.0.16) and symbolcheck.dll (10.0.16)
and executred symchk with the right command line

then i looked and saw microsoft moved the most functions to the framework components like the functions for strings where for example in ucrtbase.dll and some others

then i started to take a look on syser and syser somehow has their older version working (6.6.7.5)

do someone maybe know how their version is still in function ? i tryed the SymLoadModule64 function for example

WaxfordSqueers
June 3rd, 2019, 02:01
Quote:
[Originally Posted by Elenil;97733]version 6.6.7.5 of symserv function dll does no longer work correctly it doesnt load the sym files from the microsoft server
if it already has the files all is ok

Hey, Elenil, good to hear from you. Are you aware that Microsoft changed the way they deliver symbols? With symserv I remember being able to download individual symbol files but now it seems you have to be connected to Msoft via windbg or equivalent.

I may be wrong.

I have been storing the files in a separate directory that Msoft downloads via windbg. Don't know if they'll work elsewhere.

If you use windbg the symbol downloads work well after you figure out how to set it up.

ps. blabberer commented on this earlier in this thread, about how to set up a local symbol cache on a network.

Elenil
June 3rd, 2019, 04:16
yep it does as long the files are found in the \sym folder
the problem with the load came from microsoft somehow uncertain what it is
thats why i have added some symbol files with files that fit for the sym files

are im right to blabberer´s answer here ?:
http://www.woodmann.com/forum/showthread.php?14709-Can-t-get-symbols-working-with-Olly-1-10
and oddly 6.12 or 6.6 doing the job but not on a fresh installed version

blabberer
June 4th, 2019, 06:05
@elenil I assume you are aware that starting from windows 8
most of the old win32 apis have been moved to an implementation called API_SETS ("https://docs.microsoft.com/en-us/windows/desktop/apiindex/windows-apisets")

it is basically some kind of redirection where the api-set will resolve and forward the called apis to appropriate dlls so that ms can move implementation
to wherever it wants (for example you can see ole32 types have been moved to combase a symbol relevant to this thread is tagMSG )

a reference thread tagMSG in ole32dll ("https://reverseengineering.stackexchange.com/questions/17271/record-all-calls-to-specific-function-olly-x64dbg")


but if you do that in windows 10 you will see and if you look into documentation you may find an lpPrivate member which doesn't
appear in this type

Code:
0:000> dt ole32!tagMSG
Symbol ole32!tagMSG not found.
0:000> dt ole32!_tagMSG
Symbol ole32!_tagMSG not found.
0:000> dt *!*tagMSG*
combase!tagMsgRoutingInfo
combase!tagMSGBOXPARAMSW
combase!tagMSG
combase!tagMSGBOXPARAMSA
combase!tagMSG
0:000>

0:000> dt combase!tagMSG
+0x000 hwnd : Ptr64 HWND__
+0x008 message : Uint4B
+0x010 wParam : Uint8B
+0x018 lParam : Int8B
+0x020 time : Uint4B
+0x024 pt : tagPOINT
0:000>



so unless you have code that is agnostic of bitness , ascii , wideness ,etc you may have problems with old code

I had some old code lying around (corrected the bitness of its arguments and comiled for x64 with vs 2017 community) it seems to work out of box

here it is for reference


Code:
#include <Windows.h>
#include <dbghelp.h>
#include <stdio.h>
#pragma comment (lib , "dbghelp.lib"
BOOL CALLBACK EnumSymProc(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)
{
UNREFERENCED_PARAMETER(UserContext);
printf("%I64X %4u %s\n", pSymInfo->Address, SymbolSize, pSymInfo->Name);
return TRUE;
}

int main(int argc , char *argv[])
{
if (argc != 3) { printf("usage %s fullpath mask\n", argv[0]); return 0; }
HANDLE hProc = GetCurrentProcess();
BOOL res = FALSE;
res = SymInitialize(hProc, NULL, FALSE);
if (res)
{
PCSTR ImgName = argv[1];
DWORD64 mod = SymLoadModuleEx(hProc, NULL, ImgName, NULL, 0, 0, NULL, 0);
if (mod == 0)
{
DWORD failreason = GetLastError();
printf("failed to load module reason = %d\n", failreason);
goto cleanup;
}
else
{
printf("loaded module at %I64x\n lets enumerate symbols\n", mod);
res = SymEnumSymbols(hProc, mod, argv[2], EnumSymProc, NULL);
if (!res) { printf("symenum failed %d\n", GetLastError()); }
printf("SymEnum Succeded\n";
goto cleanup;
}
}
cleanup:
SymCleanup(hProc);
return 0;
}


result

Code:
symload.exe c:\windows\system32\ntdll.dll *ZwA*
loaded module at 180000000
lets enumerate symbols
18009F750 32 ZwAccessCheck
18009F790 0 ZwAcceptConnectPort
18009FA50 0 ZwAllocateVirtualMemory
18009FC70 0 ZwAccessCheckAndAuditAlarm
18009FF70 0 ZwAdjustPrivilegesToken
1800A0030 0 ZwAddAtom
1800A00D0 32 ZwApphelpCacheControl
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1800A0900 0 ZwAssociateWaitCompletionPacket
SymEnum Succeded

symload.exe (process 12364) exited with code 0.

Elenil
June 5th, 2019, 07:37
that list from api_sets is indeed very interesting that is kinda useful to know
that plugin seems to be interesting too

does some one have a idea how to collect or regain older files or a solution for this problem?

i have problems to find versions of files in steps

for example some files are not useable from win7 to win10 or only with certain updates or settings
talking about a test with (symchk.exe) 10.0.18362.1 on windows 7
it comes out with an error on win7 then rather i use a different version (10.0.16299.91) that works on both operating systems
that gives an advantage in compatibility


then looking for a useable version for both is getting a mess
that would also solve the problem to find the latest version
something like "dlldownload" just with more files or even all the files

isnt there something to find all the versions that exits ? (a list or the files, both is perfect)






yep waxfordsqueers the 6.12.2.633 is doing it for example just the file has to be replaces for example
oddly the 6.6.7.5 is not doing it but the 6.6.3.5 also do the job

WaxfordSqueers
June 12th, 2019, 17:44
It's funny how reality interferes with these investigations. In the middle of an unrelated project but "I'll be back".

Elenil
July 11th, 2019, 03:43
i agree this discussion part was moved from the usb driver thread

private messages are offline?

maybe combase.dll can be used instead on windows 10

and being off tropic why recently (rather to be exactly the last year) more and more websides are getting marked with negativ words "unwanted" software "malware" and "malicious"

actually google and firefox actually marked woodmann with a big red warning