or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-access.mddebug.mdhashing.mdimport-export.mdindex.mdmemory.mdordinal-lookups.mdpacker-detection.mdpe-parsing.mdresources.mdsections.md

ordinal-lookups.mddocs/

0

# Ordinal Lookups

1

2

Database of ordinal to symbol name mappings for common Windows DLLs. The ordlookup package provides resolution of function names from ordinal numbers when symbolic information is not available.

3

4

## Capabilities

5

6

### Ordinal Resolution

7

8

Look up function names from ordinal numbers for supported DLLs.

9

10

```python { .api }

11

def ordLookup(libname, ord_val, make_name=False):

12

"""

13

Look up symbol name for given ordinal in specified library.

14

15

Args:

16

libname (bytes): DLL name (case-insensitive)

17

ord_val (int): Ordinal number to look up

18

make_name (bool): If True, generate formatted name when lookup fails

19

20

Returns:

21

bytes: Function name if found, formatted ordinal if make_name=True,

22

or None if not found and make_name=False

23

"""

24

25

def formatOrdString(ord_val):

26

"""

27

Format ordinal number as standardized string.

28

29

Args:

30

ord_val (int): Ordinal number

31

32

Returns:

33

bytes: Formatted ordinal string (e.g., b"ord123")

34

"""

35

```

36

37

### Supported Libraries

38

39

The ordlookup package includes mappings for these common Windows DLLs:

40

41

- **oleaut32.dll**: OLE Automation functions

42

- **ws2_32.dll**: Winsock 2 networking functions

43

- **wsock32.dll**: Legacy Winsock networking functions

44

45

## Usage Examples

46

47

### Basic Ordinal Lookup

48

49

```python

50

import ordlookup

51

52

# Look up function names by ordinal

53

dll_name = b"oleaut32.dll"

54

ordinal = 2

55

56

function_name = ordlookup.ordLookup(dll_name, ordinal)

57

if function_name:

58

print(f"Ordinal {ordinal} in {dll_name.decode()}: {function_name.decode()}")

59

else:

60

print(f"Ordinal {ordinal} not found in {dll_name.decode()}")

61

62

# Generate formatted name if lookup fails

63

formatted_name = ordlookup.ordLookup(dll_name, 9999, make_name=True)

64

print(f"Unknown ordinal formatted: {formatted_name.decode()}")

65

```

66

67

### Integration with PE Import Analysis

68

69

```python

70

import pefile

71

import ordlookup

72

73

def resolve_import_ordinals(pe):

74

"""Resolve ordinal imports using ordlookup database."""

75

if not hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):

76

return

77

78

print("Import Analysis with Ordinal Resolution:")

79

print("-" * 50)

80

81

for entry in pe.DIRECTORY_ENTRY_IMPORT:

82

dll_name = entry.dll

83

print(f"\nDLL: {dll_name.decode('utf-8')}")

84

85

for imp in entry.imports:

86

if imp.import_by_ordinal:

87

# Try to resolve ordinal to function name

88

resolved_name = ordlookup.ordLookup(dll_name, imp.ordinal)

89

90

if resolved_name:

91

print(f" Ordinal {imp.ordinal}: {resolved_name.decode('utf-8')}")

92

else:

93

print(f" Ordinal {imp.ordinal}: <unknown>")

94

else:

95

# Regular named import

96

if imp.name:

97

print(f" Function: {imp.name.decode('utf-8')}")

98

99

# Usage

100

with pefile.PE('executable.exe') as pe:

101

resolve_import_ordinals(pe)

102

```

103

104

### Ordinal Database Exploration

105

106

```python

107

import ordlookup

108

109

def explore_ordinal_database():

110

"""Explore available ordinal mappings."""

111

print("Available Ordinal Databases:")

112

print("=" * 40)

113

114

for dll_name, ord_dict in ordlookup.ords.items():

115

dll_str = dll_name.decode('utf-8')

116

print(f"\n{dll_str}:")

117

print(f" Functions: {len(ord_dict)}")

118

119

# Show ordinal range

120

if ord_dict:

121

min_ord = min(ord_dict.keys())

122

max_ord = max(ord_dict.keys())

123

print(f" Ordinal range: {min_ord} - {max_ord}")

124

125

# Show first few functions

126

print(" Sample functions:")

127

for ord_num in sorted(ord_dict.keys())[:5]:

128

func_name = ord_dict[ord_num].decode('utf-8')

129

print(f" {ord_num}: {func_name}")

130

131

if len(ord_dict) > 5:

132

print(f" ... and {len(ord_dict) - 5} more")

133

134

# Usage

135

explore_ordinal_database()

136

```

137

138

### Custom Ordinal Resolution

139

140

```python

141

import ordlookup

142

143

def resolve_with_fallback(dll_name, ordinal):

144

"""Resolve ordinal with multiple fallback strategies."""

145

# Try direct lookup

146

result = ordlookup.ordLookup(dll_name, ordinal)

147

if result:

148

return result.decode('utf-8'), 'database'

149

150

# Check case variations of DLL name

151

dll_variations = [

152

dll_name.lower(),

153

dll_name.upper(),

154

dll_name.lower().replace(b'.dll', b'') + b'.dll'

155

]

156

157

for dll_var in dll_variations:

158

result = ordlookup.ordLookup(dll_var, ordinal)

159

if result:

160

return result.decode('utf-8'), 'case_variant'

161

162

# Generate formatted ordinal as fallback

163

formatted = ordlookup.formatOrdString(ordinal)

164

return formatted.decode('utf-8'), 'generated'

165

166

# Usage example

167

test_cases = [

168

(b"oleaut32.dll", 2), # Known mapping

169

(b"OLEAUT32.DLL", 2), # Case variation

170

(b"kernel32.dll", 1), # Unknown DLL

171

(b"ws2_32.dll", 999) # Unknown ordinal

172

]

173

174

print("Ordinal Resolution with Fallback:")

175

print("-" * 40)

176

177

for dll, ordinal in test_cases:

178

result, method = resolve_with_fallback(dll, ordinal)

179

print(f"{dll.decode():<15} ord {ordinal:<3}: {result:<20} ({method})")

180

```

181

182

### PE File Analysis with Complete Ordinal Resolution

183

184

```python

185

import pefile

186

import ordlookup

187

188

def complete_import_analysis(pe_file):

189

"""Complete import analysis with ordinal resolution."""

190

print(f"Complete Import Analysis: {pe_file}")

191

print("=" * 60)

192

193

with pefile.PE(pe_file) as pe:

194

if not hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):

195

print("No imports found")

196

return

197

198

total_imports = 0

199

resolved_ordinals = 0

200

201

for entry in pe.DIRECTORY_ENTRY_IMPORT:

202

dll_name = entry.dll

203

dll_str = dll_name.decode('utf-8')

204

205

print(f"\n{dll_str}:")

206

print("-" * len(dll_str))

207

208

dll_imports = 0

209

dll_resolved = 0

210

211

for imp in entry.imports:

212

dll_imports += 1

213

total_imports += 1

214

215

if imp.import_by_ordinal:

216

# Try to resolve ordinal

217

resolved_name = ordlookup.ordLookup(dll_name, imp.ordinal)

218

219

if resolved_name:

220

function_name = resolved_name.decode('utf-8')

221

resolved_ordinals += 1

222

dll_resolved += 1

223

status = "✓"

224

else:

225

function_name = f"<unknown ordinal {imp.ordinal}>"

226

status = "✗"

227

228

print(f" {status} Ordinal {imp.ordinal:3d}: {function_name}")

229

else:

230

# Named import

231

if imp.name:

232

function_name = imp.name.decode('utf-8')

233

print(f" ○ Function: {function_name}")

234

else:

235

print(f" ? Import at 0x{imp.address:08x}")

236

237

print(f" Summary: {dll_imports} imports, {dll_resolved} ordinals resolved")

238

239

# Overall statistics

240

print(f"\nOverall Statistics:")

241

print("-" * 20)

242

print(f"Total imports: {total_imports}")

243

print(f"Resolved ordinals: {resolved_ordinals}")

244

245

if total_imports > 0:

246

resolution_rate = (resolved_ordinals / total_imports) * 100

247

print(f"Resolution rate: {resolution_rate:.1f}%")

248

249

# Usage

250

complete_import_analysis('executable.exe')

251

```

252

253

### Extending the Ordinal Database

254

255

```python

256

import ordlookup

257

258

# Example of how to extend the database (conceptual)

259

def add_custom_ordinals():

260

"""Example of extending ordinal database with custom mappings."""

261

262

# This shows how you could add custom ordinal mappings

263

# Note: This modifies the runtime database, not persistent storage

264

265

custom_dll = b"custom.dll"

266

custom_mappings = {

267

1: b"CustomFunction1",

268

2: b"CustomFunction2",

269

100: b"SpecialExport"

270

}

271

272

# Add to ordlookup database

273

ordlookup.ords[custom_dll] = custom_mappings

274

275

print("Added custom ordinal mappings")

276

277

# Test the new mappings

278

for ordinal, expected_name in custom_mappings.items():

279

resolved = ordlookup.ordLookup(custom_dll, ordinal)

280

if resolved == expected_name:

281

print(f"✓ Custom ordinal {ordinal}: {resolved.decode()}")

282

else:

283

print(f"✗ Failed to resolve custom ordinal {ordinal}")

284

285

# Note: This is for demonstration - actual extension would require

286

# modifying the ordlookup package files or creating a custom lookup system

287

```