Results 1 to 11 of 11

Thread: Exploring CFG (Control Flow Guard)

  1. #1
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Blog Entries

    Exploring CFG (Control Flow Guard)

    EDIT: Posts moved from another thread into a new topic

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

    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

     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.

  2. #2
    Super Moderator
    Join Date
    Dec 2004
    Blog Entries
    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)

    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
      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
              0000000140001010  _TlgEnableCallback
              0000000140001340  __report_gsfailure
              0000000140001830  wWinMainCRTStartup
              0000000140001850  ?__CxxUnhandledExceptionFilter@@YAJPEAU_EXCEPTION_POINTERS@@@Z (long __cdecl __CxxUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *))
              0000000140001890  __CxxSetUnhandledExceptionFilter
              0000000140001970  _matherr
              0000000140001A80  _guard_check_icall_nop
            1000 .data
            1000 .pdata
            1000 .rdata
            1000 .reloc
            5000 .rsrc
            1000 .text
    if you are going to continue I would suggest split this

  3. #3
    Teach, Not Flame Kayaker's Avatar
    Join Date
    Oct 2000
    Blog Entries
    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.

  4. #4
    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):

    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 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 (

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

  5. #5
    Quote Originally Posted by Elenil View Post
    version 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.
    Last edited by WaxfordSqueers; June 3rd, 2019 at 02:07.

  6. #6
    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 ?:
    and oddly 6.12 or 6.6 doing the job but not on a fresh installed version
    Last edited by Elenil; June 3rd, 2019 at 11:18.

  7. #7
    Super Moderator
    Join Date
    Dec 2004
    Blog Entries
    @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

    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

    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

    0:000> dt ole32!tagMSG
    Symbol ole32!tagMSG not found.
    0:000> dt ole32!_tagMSG
    Symbol ole32!_tagMSG not found.
    0:000> dt *!*tagMSG*
    0:000> dt combase!tagMSG
       +0x000 hwnd             : Ptr64 HWND__
       +0x008 message          : Uint4B
       +0x010 wParam           : Uint8B
       +0x018 lParam           : Int8B
       +0x020 time             : Uint4B
       +0x024 pt               : tagPOINT

    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

    #include <Windows.h>
    #include <dbghelp.h>
    #include <stdio.h>
    #pragma comment (lib , "dbghelp.lib")
    BOOL CALLBACK EnumSymProc(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID 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;
    			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;
    	return 0;

    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
    1800A0900    0 ZwAssociateWaitCompletionPacket
    SymEnum Succeded
    symload.exe (process 12364) exited with code 0.
    Last edited by blabberer; June 4th, 2019 at 08:45.

  8. #8
    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 is doing it for example just the file has to be replaces for example
    oddly the is not doing it but the also do the job

  9. #9
    It's funny how reality interferes with these investigations. In the middle of an unrelated project but "I'll be back".

  10. #10
    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

  11. #11
    Quote Originally Posted by Elenil View Post
    ...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
    Paranoia!!! It's the folks at Firefox playing Big Brother. They think they can hold everyone's hand and protect them from everything on the Net. If Firefox would go back to simply putting out a good browser and letting users look out for themselves, Firefox would once again be a good browser.

    Recently, I had to jump through hoops to turn off Firefox updates on version 68. They no longer allow you to turn them off and you have to know the trade secrets to turn them off. Simple actually, you place a certain file in the distribution folder which essentially says, "turn updates off".

    Reminds me of the the early NET and the BBS system. Whenever you went on a site that had anything to do with reversing, you'd be greeted by heavy metal figures, skulls, and everything evil. I'd wonder what the heck I was getting myself into. Turned out to be nothing, all those sites were fine.

    Anyone who regards Woody's site as evil is paranoid.

    Microsoft started banning evil users from W7 updates if they dared to run W7 on an 8th generation Intel processor/chipset. In other words, if you were not willing to upgrade to W8 or W10 and tried running W7 against their wishes, they stopped allowing you to update W7. Fortunately, I discovered wufuc at github.

Similar Threads

  1. Control Flow Deobfuscation via Abstract Interpretation
    By OpenRCE_RolfRolles in forum Blogs Forum
    Replies: 0
    Last Post: July 9th, 2011, 03:23
  2. Control Flow Integrity: Some interesting papers
    By Piotr Bania Chronicles in forum Blogs Forum
    Replies: 0
    Last Post: May 17th, 2011, 21:18
  3. Control Flow Deobfuscation Part 3
    By fr33ke in forum Blogs Forum
    Replies: 2
    Last Post: July 16th, 2008, 09:44
  4. Control Flow Deobfuscation Part 2
    By fr33ke in forum Blogs Forum
    Replies: 1
    Last Post: April 28th, 2008, 04:21
  5. Control Flow Deobfuscation Part 1
    By fr33ke in forum Blogs Forum
    Replies: 4
    Last Post: January 14th, 2008, 17:13


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts