PDA

View Full Version : Question about dwFlags and IDA (or any simple way to translate dwFlags)


bboitano
May 27th, 2015, 03:05
Hi everyone,

This is just a simple questions regarding the hex values passed as dwFlags and translating them to their actual meaning. I found this thread (t-12498.html) which _nearly_ solves the problem but I'm still a little stuck.

As I understand it we should be right clicking and using Standard Symbolic Symbol.

Now this works fine for a single value (for example, the #define INTERNET_FLAG_FORMS_SUBMIT 0x00000040 in the referenced thread). But for multiple OR'd values, it doesn't help (at least the way I'm using it and that well may be wrong!)

Currently I'm looking at a call to HttpOpenRequestA and the dwFlags push is 4003300h. I was wondering if there was a way in IDA (or another utility that I could use) to translate that into it's actual meaning

INTERNET_FLAG_RAW_DATA 0x40000000
INTERNET_FLAG_IGNORE_CERT_DATE_INVALID 0x2000
INTERNET_FLAG_IGNORE_CERT_CN_INVALID 0x1000
INTERNET_FLAG_NO_UI 0x200
INTERNET_FLAG_PRAGMA_NOCACHE 0x100

Sure it is possible to do it manually but I was wondering if there was a way to integrate this functionality into IDA or something else.

Many thanks in advance

Kayaker
May 27th, 2015, 23:21
Hi

I've occasionally wished for the same. The most straightforward way might just be to start creating your own database of enums of dwFlags you come across and want to define. You could use either a header file or an idc script that you can run for each new project. The added defines will then be available from the Symbolic Constant menu.
Naming multiple OR'd flags so they're understandable would be a bit clunky, but...

As an example, the following header file will create a new enum named "HttpOpenRequest" with a mixture of (crudely named) flag combinations from your list. File/Load File/Parse C header file to implement. IDA will correctly calculate the "+" values. You may have to "Add Enum" in the Enums window and select the new entry from the standard list (which should be at the bottom) to get it to show.

Code:

// MyEnums.h

typedef enum HttpOpenRequest {
INTERNET_FLAG_RAW_DATA = 0X40000000,
INTERNET_FLAG_RAW__IGNORE_CERT_DATE_INVALID = 0X40000000 + 0x2000,
INTERNET_FLAG_RAW__IGNORE_CERT_CN_INVALID = 0X40000000 + 0x1000,
INTERNET_FLAG_RAW__NO_UI = 0X40000000 + 0x200,
INTERNET_FLAG_RAW__PRAGMA_NOCACHE = 0X40000000 + 0x100,
INTERNET_FLAG_RAW__IGNORE_CERT_DATE__IGNORE_CERT_CN__NO_UI__PRAGMA_NOCACHE = 0X40000000 + 0x2000 + 0x1000 + 0x200 + 0x100
};


The same thing can be done with an idc script. This is simply ripped from having IDA dump the typeinfo data to an idc file and modifying to suit. A slight benefit of this method is that it seems to immediately update the Enums window with the new entry.

Code:

// MyEnums.idc

#define UNLOADED_FILE 1
#include <idc.idc>

static main(void)
{
Enums(); // enumerations
}

static Enums_0(id) {
id = AddEnum(-1,"HttpOpenRequest",0x1100000);
AddConstEx(id,"INTERNET_FLAG_RAW_DATA", 0X40000000, -1);
AddConstEx(id,"INTERNET_FLAG_RAW__IGNORE_CERT_DATE_INVALID", 0X40000000+0x2000, -1);
AddConstEx(id,"INTERNET_FLAG_RAW__IGNORE_CERT_CN_INVALID", 0X40000000+0x1000, -1);
AddConstEx(id,"INTERNET_FLAG_RAW__NO_UI", 0X40000000+0x200, -1);
AddConstEx(id,"INTERNET_FLAG_RAW__PRAGMA_NOCACHE", 0X40000000+0x100, -1);
AddConstEx(id,"INTERNET_FLAG_RAW__IGNORE_CERT_DATE__IGNORE_CERT_CN__NO_UI__PRAGMA_NOCACHE", 0X40000000+0x2000+0x1000+0x200+0x100, -1);
return id;
}

//------------------------------------------------------------------------
// Information about enum types

static Enums(void) {
auto id;
BeginTypeUpdating(UTP_ENUM);
id = Enums_0(id);
EndTypeUpdating(UTP_ENUM);
}


Result:
Code:

; enum HttpOpenRequest
INTERNET_FLAG_RAW_DATA = 40000000h
INTERNET_FLAG_RAW__PRAGMA_NOCACHE = 40000100h
INTERNET_FLAG_RAW__NO_UI = 40000200h
INTERNET_FLAG_RAW__IGNORE_CERT_CN_INVALID = 40001000h
INTERNET_FLAG_RAW_IGNORE_CERT_DATE_INVALID = 40002000h
INTERNET_FLAG_RAW__IGNORE_CERT_DATE__IGNORE_CERT_CN__NO_UI__PRAGMA_NOCACHE = 40003300h



I suppose you could get more elegant with some fancy scripting and a full database of known API dwFlags (IDAPython/SQLite?), but it's a start.

Cheers,
Kayaker

bboitano
May 28th, 2015, 05:50
Hi Kayaker,

Thank you very much for taking the time to reply and put together some snippets - it is really appreciated.

I can imagine that it will be a huge amount of work to put something together with all of the possible flag combinations - even for a simple call as HttpOpenRequest (17 different flags than can be set - I think that is 2^17 options or over 131000 different possible permutations of flags!)

Putting something like that together for every call in the common APIs would be horrific!

I can but assume that calculating it on a case by case basis would be the only way forward - I wonder why such a tool doesn't exist already? Ho-Hum.

Again, my thanks for your time trying to help me. I will continue to hunt around and if I find anything I will be sure to post back here so everyone can benefit!

Kindest regards

bboitano
June 1st, 2015, 04:24
Hi Kayaker,

I posted here with the same question (http://reverseengineering.stackexchange.com/questions/9012/question-about-dwflags-and-ida-or-any-simple-way-to-translate-dwflags) and received a useful answer :

Quote:
This is very possible in IDA, using bitfield-enums.

1.Assign an enum type to your value. If you use standard symbolic constant, there will be a local copy of the type in your Enumerations subview.


2.Edit the enum type definition, and enable the bitfield checkbox. IDA will convert the bitfield automatically if all the enum values have only 1 bit set. If there are other values like zero, you have to remove them first.


3.The value will now display similar to (INTERNET_FLAG_RAW_DATA or INTERNET_FLAG_IGNORE_CERT_DATE_INVALID or INTERNET_FLAG_IGNORE_CERT_CN_INVALID or INTERNET_FLAG_NO_UI or INTERNET_FLAG_PRAGMA_NOCACHE).


There is also support for more complicated multi-bit flags using masks. Read the Enum docs in IDA for more.


Hope somebody else finds this useful too

bb

Kayaker
June 3rd, 2015, 12:02
That is useful. I noticed that IDA already has a number of enum groupings for some API dwFlags.

For example, CreateProcess type flags are grouped under an enum called MACRO_DEBUG

Code:

00000001 ; enum MACRO_DEBUG (standard) (bitfield)
00000001 DEBUG_PROCESS = 1
00000002 DEBUG_ONLY_THIS_PROCESS = 2
00000004 CREATE_SUSPENDED = 4
00000008 DETACHED_PROCESS = 8
00000010 CREATE_NEW_CONSOLE = 10h
00000020 NORMAL_PRIORITY_CLASS = 20h
00000040 IDLE_PRIORITY_CLASS = 40h
00000080 HIGH_PRIORITY_CLASS = 80h
00000100 REALTIME_PRIORITY_CLASS = 100h
00000200 CREATE_NEW_PROCESS_GROUP = 200h
00000400 CREATE_UNICODE_ENVIRONMENT = 400h
00000800 CREATE_SEPARATE_WOW_VDM = 800h
00001000 CREATE_SHARED_WOW_VDM = 1000h
00002000 CREATE_FORCEDOS = 2000h
00004000 BELOW_NORMAL_PRIORITY_CLASS = 4000h
00008000 ABOVE_NORMAL_PRIORITY_CLASS = 8000h
00010000 INHERIT_PARENT_AFFINITY = 10000h
00020000 INHERIT_CALLER_PRIORITY = 20000h
00040000 CREATE_PROTECTED_PROCESS = 40000h
00080000 EXTENDED_STARTUPINFO_PRESENT = 80000h
00100000 PROCESS_MODE_BACKGROUND_BEGIN = 100000h
00200000 PROCESS_MODE_BACKGROUND_END = 200000h
01000000 CREATE_BREAKAWAY_FROM_JOB = 1000000h
02000000 CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 2000000h
04000000 CREATE_DEFAULT_ERROR_MODE = 4000000h
08000000 CREATE_NO_WINDOW = 8000000h
10000000 PROFILE_USER = 10000000h
20000000 PROFILE_KERNEL = 20000000h
40000000 PROFILE_SERVER = 40000000h
80000000 CREATE_IGNORE_SYSTEM_DEFAULT = 80000000h


Memory protection and memory allocation constants (VirtualAlloc, CreateFileMapping,...) as MACRO_PAGE

Code:

00000001 ; enum MACRO_PAGE (standard) (bitfield)
00000001 PAGE_NOACCESS = 1
00000002 PAGE_READONLY = 2
00000004 PAGE_READWRITE = 4
00000008 PAGE_WRITECOPY = 8
00000010 PAGE_EXECUTE = 10h
00000020 PAGE_EXECUTE_READ = 20h
00000040 PAGE_EXECUTE_READWRITE = 40h
00000080 PAGE_EXECUTE_WRITECOPY = 80h
00000100 PAGE_GUARD = 100h
00000200 PAGE_NOCACHE = 200h
00000400 PAGE_WRITECOMBINE = 400h
00001000 MEM_COMMIT = 1000h
00002000 MEM_RESERVE = 2000h
00004000 MEM_DECOMMIT = 4000h
00008000 MEM_RELEASE = 8000h
00010000 MEM_FREE = 10000h
00020000 MEM_PRIVATE = 20000h
00040000 MEM_MAPPED = 40000h
00080000 MEM_RESET = 80000h
00100000 MEM_TOP_DOWN = 100000h
00200000 MEM_WRITE_WATCH = 200000h
00400000 MEM_PHYSICAL = 400000h
00800000 MEM_ROTATE = 800000h
20000000 MEM_LARGE_PAGES = 20000000h
80000000 MEM_4MB_PAGES = 80000000h


There are File mapping flags (CreateFileMapping, MapViewOfFile,..) under the enum groupings MACRO_FS and MACRO_SEC, and so on.

These enum groupings nicely give the desired OR'd definitions, but of course only when they are loaded. Again scripting could be useful here, say you right click on a function name and the script loads the associated enums.

ZaiRoN
June 3rd, 2015, 17:48
It's everything inside the defined type libraries (.til files inside til\pc folder). To create your personal type libraries (including complex OR's values) you can use tilib.exe utility available for registered users.

Kayaker
June 4th, 2015, 06:12
Thanks Z.

It looks like the FLARE MSDN Annotations plugin deals with this whole issue quite nicely.

https://www.fireeye.com/blog/threat-research/2014/09/flare-ida-pro-script-series-msdn-annotations-ida-pro-for-malware-analysis.html

ZaiRoN
June 5th, 2015, 10:03
Thanks K. for the nice link.