

Flag: Tornado!
Hurricane!
|
 |
Topic created on: February 9, 2008 14:03 CST by bmazic  .
Is it possible to spy on API calls using OllyDbg? By that I don't mean manually setting breakpoints on select API calls, but rather saying: I want to run the target from address A to address B and then find out which API calls have been made and with what parameters. Also, it would be nice if I could select what type of API calls I'm interested in (e.g. memory management, file access, etc.)
Boris
|
should be possible with OllyScript .. or in Immunity dbg you can just use python ..
|
Yeah, take a look at Damian and myself's posts on http://forum.immunityinc.com regarding inter-modular calls.
It's quite easy to take each inter-modular call and set a breakpoint on it. Then determine what your starting and ending run addresses are (set breakpoints on the start address) and then single step.
|
After a little bit of research I found out that API spying is called intermodular calls logging in OllyDbg jargon.
There is a way to place a logging breakpoint on all intermodular calls in OllyDbg. At a certain point during debugging, you should do the following:
1. Right click in the CPU window and select 'Search for|All intermodular calls',
2. The References (R) window contains a list of found intermodular calls. Right-click and select 'Set log breakpoint on every command' and in the dialog box select 'Log function arguments'.
This doesn't work for me, though. First of all, the intermodular call list contains some calls I am not interested in and would like them to be removed from the list but have no idea how. Secondly, the OllyDbg doesn't allow me to set 'Log function arguments' option. Even if I try to set a single log breakpoint on a recognised API call (so 'Log function arguments' option is not greyed out), e.g.
Found intermodular calls, item 216
Address=007C8B4E
Disassembly=CALL DWORD PTR DS:[7D973C]
Destination=kernel32.WriteFile
the OK button is greyed out and I cannot finish setting the breakpoint (I set all fields to their default empty values).
Any ideas why is this so?
By the way, what is the difference between Immunity Debugger and OllyDbg v1.10 apart from the Python scripting support?
Boris
|
right click -> search for all intermodular calls --> right click --> set log break point on every command
if log function arguments radio button is greyed out
analyse the exe or dll or module first
after that you will see the log function arguments radio button is enabled
for example ollydbg -> calc.exe -> alt+e comctl32.dll -> right click follow entry point + ctrl+a --> right click -> search for all intermodular calls -> right click set log break point on every command -> log function arguments -->
log window -> right click --> log to file --> f9
result
01012475 Program entry point
Analysing calc
158 heuristical procedures
273 calls to known, 167 calls to guessed functions
91 loops, 22 switches
71950000 Module C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.10.0_x-ww_f7fb5805\comctl32.dll
Analysing comctl32
2338 heuristical procedures
6475 calls to known, 3224 calls to guessed functions
739 loops, 260 switches
5AD70000 Module C:\WINDOWS\System32\uxtheme.dll
7197E147 CALL to GetWindowLongW
hWnd = 001001D8 (class='Edit')
Index = 0.
7197E165 CALL to DefWindowProcW
hWnd = 001001D8 (class='Edit')
Message = WM_GETMINMAXINFO
wParam = 0
pMinMax = 0006F840
7197E147 CALL to GetWindowLongW
hWnd = 001001D8 (class='Edit')
Index = 0.
7197E5AB CALL to GetProcessHeap
7197E5B2 CALL to HeapAlloc
hHeap = 00090000
Flags = HEAP_ZERO_MEMORY
HeapSize = 124 (292.)
7197E5C7 CALL to SetWindowLongW
hWnd = 001001D8 (class='Edit')
Index = 0.
NewValue = 94978
719A9C93 CALL to GetWindowLongW
hWnd = 001001D8 (class='Edit')
Index = -1.
7197C096 CALL to GetVersionExW
pVersionInformation = 0006F58C
719A9D8E CALL to LocalAlloc
Flags = LHND
Size = 40 (64.)
71954296 CALL to LoadLibraryA
FileName = "UxTheme.dll"
719542F7 CALL to GetProcAddress
hModule = 5AD70000 (uxtheme)
ProcNameOrOrdinal = "OpenThemeData"
719A9DD7 CALL to DefWindowProcW
hWnd = 001001D8 (class='Edit')
Message = WM_NCCREATE
wParam = 0
pCreate = 0006F838
7197E147 CALL to GetWindowLongW
hWnd = 001001D8 ('CalcMsgPumpWnd',class='Edit')
Index = 0.
719B7B46 CALL to DefWindowProcW
hWnd = 001001D8 ('CalcMsgPumpWnd',class='Edit')
Message = WM_NCCALCSIZE
CalcFlag = FALSE
Data = 0006F860
7197E147 CALL to GetWindowLongW
hWnd = 001001D8 ('CalcMsgPumpWnd',class='Edit')
Index = 0.
7197CDB1 CALL to GetDC
hWnd = 001001D8 ('CalcMsgPumpWnd',class='Edit')
7197CD03 CALL to CopyRect
pRectDst = 0006F568
pRectSrc = 000949B8 {0.,0.,0.,0.}
7197CD42 CALL to GetClientRect
hWnd = 001001D8 ('CalcMsgPumpWnd',class='Edit')
pRect = 0006F558
7197CD78 CALL to IntersectRect
pRectDst = 0006F558
pRect1 = 0006F558 {0.,0.,762.,498.}
pRect2 = 0006F568 {0.,0.,0.,0.}
7197CD8D CALL to IntersectClipRect
hDC = 34010635
Left = 0
Top = 0
Right = 0
Bottom = 0
719AAB9F CALL to GetTextCharset
hDC = 34010635
7197CDF2 CALL to ReleaseDC
hWnd = 001001D8 ('CalcMsgPumpWnd',class='Edit')
hDC = 34010635
719AABB6 CALL to GetKeyboardLayout
ThreadID = 0
719AAD57 CALL to GetDC
hWnd = 001001D8 ('CalcMsgPumpWnd',class='Edit')
719A9B87 CALL to GetTextFaceW
hDC = 34010635
MaxFaceName = 20 (32.)
pFaceName = 0006F4D8
7197D434 CALL to GetTextCharsetInfo
hDC = 34010635
pSignature = 0006F50C
Flags = 0
stripped off 453 kb of further garbage
|
|
Perfect! The steps are the same for ImmunityDebugger, and see my previous post on how to automate the whole process using Python.
|
right click -> search for all intermodular calls --> right click --> set log break point on every command
These methods do not work in some cases .few I remember are
push AdderOfAPI
ret
other could be
Jmp AdderOfAPI
|
Thank you for your replies. I am trying to analyse a multiply packed application (ASProtect + MoleBox), so I wouldn't want to rely on OllyDbg heuristics to recognise intermodullar calls. Also, I would like to be able to monitor just those calls that I am interested in (e.g. file system calls, process control, memory management, etc.). Is there a way in OllyDbg to place a logging breakpoint on all exported functions from a DLL. For example,
Alt-E (View|Executable modules)
Select kernel32 module
Ctrl-N (Right click|View names)
Set log breakpoint on every name (NON-EXISTENT COMMAND)
I am aware of Pedram Amini's Breakpoint Manager, but it lacks some easy way of creating large breakpoint sets. If I could somehow manage to create log breakpoints for all exported functions from a DLL, then I might use Breakpoint Manager's ability to save the breakpoint list in a text file which I could then edit manually (split, merge, etc). Any ideas how this could be done?
Also, is there any easy way to use OllyDbg plugins in Immunity Debugger?
Boris
|
Expanding on my previous post, here is a solution to creating custom breakpoint sets for OllyDbg.
The procedure is as follows:
A) Using OllyDbg, export a list of names in a DLL. To do that, do the following:
1. Alt-E (View|Executable modules)
2. Select the module you are interested in
3. Ctrl-N (Right click|View names)
4. Right click|Copy to clipboard|Whole table
5. Paste the copied text to a text editor, then add the module's base address to the first line saying, e.g.
Names in kernel32, Base=7C800000
NOTE: Make sure you resize all columns properly (so all text in a column becomes clearly visible) before copying the function names to the clipboard.
B) With the file created, you can now run the provided python script to generate the *.obp file (Pedram Amini's Breakpoint Manager file format), e.g.
python names2obp.py < kernel32.txt > kernel32.obp
C) Modify the provided python script to change the breakpoint type or filter out the exports you want breakpoints on
Tweak the expresion parameter in the source of the python script to change the type of breakpoints generated. The 'Q' means conditional log breakpoint with the following options selected (Pause program: Never, Log value of expression:Never, Log function arguments: Always).
Modify the not_filtered() function to change the way the input list is filtered. The current implementation will filter out all but file management functions from kernel32.dll. Keep that in mind when you run it for the first time.
D) Having made sure you have Pedram Amini's Breakpoint Manager plugin already installed, run the target and load the breakpoint set(s)
Alt-B (View|Breakpoints)
Right-click|Breakpoint Manager|Import Breakpoints
That's it.
Boris
The python script source follows:
%<------%<------%<--CUT_HERE----%<------%<------%<------%<
###
# File: names2obp.py
# Author: Boris Mazic
# Date: 19/02/2008
##
"""
Convert OllyDbg's module name list (a list of exported and forwarded functions)
to Pedram Amini's Breakpoint Manager *.obp file format. You can filter out
the list to include only certain exports by modifying the script below.
To create a list of exported functions do the following in OllyDbg:
1. Alt-E (View|Executable modules)
2. Select the module you are interested in
3. Ctrl-N (Right click|View names)
4. Right click|Copy to clipboard|Whole table
5. Paste the copied text to a text editor, then add the module's base
address to the first line saying, e.g.
Names in kernel32, Base=7C800000
With the file created, you can now run this python script to generate the
*.obp file, e.g.
names2obp.py < kernel32.txt > kernel32.obp
Tweak the expresion parameter in the source below to change the type of
breakpoint generated. The 'Q' means conditional log breakpoint with the
following options selected (Pause program: Never, Log value of expression:
Never, Log function arguments: Always).
NOTE: Make sure you resize all columns properly (so all text in a column
becomes clearly visible) before copying the function names to the clipboard.
"""
import sys, re, string
# Typical input:
"""
Names in kernel32, Base=7C800000
Address Section Type (Known) Name Comment
7C80A634 .text Export ActivateActCtx
7C8231D5 .text Export (Known) WriteProfileStringW
"""
RE_title = re.compile(r'^Names in (\S+), Base=([0-9a-fA-F]+)')
RE_heading = re.compile(r'^Address\s+Section\s+Type\s+\(Known\)\s+Name\s+Comment')
RE_api_info = re.compile(r"""
^([0-9a-fA-F]+) # Address
\s+
(\S+) # Section
\s+
((\S+)(\s+\(Known\))?) # Type
\s+
(\S+) # Name
(\s+(\S+))? # Comment
""", re.VERBOSE | re.MULTILINE)
file_management = 'AreFileApisANSI|CheckNameLegalDOS8Dot3|CloseHandle|CopyFile|CopyFileEx|CreateFile|CreateHardLink|DeleteFile|FindClose|FindFirstFile|FindFirstFileEx|FindFirstStreamW|FindNextFile|FindNextStreamW|GetBinaryType|GetCompressedFileSize|GetFileAttributes|GetFileAttributesEx|GetFileInformationByHandle|GetFileSize|GetFileSizeEx|GetFileTime|GetFileType|GetFullPathName|GetLongPathName|GetShortPathName|GetTempFileName|GetTempPath|MoveFile|MoveFileEx|MoveFileWithProgress|ReOpenFile|ReplaceFile|SearchPath|SetFileApisToANSI|SetFileApisToOEM|SetFileAttributes|SetFileSecurity|SetFileShortName|SetFileTime|SetFileValidData|'
file_io = 'CancelIo|CreateIoCompletionPort|FlushFileBuffers|GetQueuedCompletionStatus|LockFile|LockFileEx|PostQueuedCompletionStatus|ReadFile|ReadFileEx|ReadFileScatter|SetEndOfFile|SetFilePointer|SetFilePointerEx|UnlockFile|UnlockFileEx|WriteFile|WriteFileEx|WriteFileGather|'
file_mapping = 'CreateFileMapping|FlushViewOfFile|MapViewOfFile|MapViewOfFileEx|OpenFileMapping|UnmapViewOfFile|'
memory_management = 'CopyMemory|CreateMemoryResourceNotification|FillMemory|GetLargePageMinimum|GetWriteWatch|GlobalMemoryStatus|GlobalMemoryStatusEx|IsBadCodePtr|IsBadReadPtr|IsBadStringPtr|IsBadWritePtr|MoveMemory|QueryMemoryResourceNotification|ResetWriteWatch|SecureZeroMemory|ZeroMemory|'
memory_global_and_local = 'GlobalAlloc|GlobalDiscard|GlobalFlags|GlobalFree|GlobalHandle|GlobalLock|GlobalReAlloc|GlobalSize|GlobalUnlock|LocalAlloc|LocalDiscard|LocalFlags|LocalFree|LocalHandle|LocalLock|LocalReAlloc|LocalSize|LocalUnlock|'
memory_heap = 'GetProcessHeap|GetProcessHeaps|HeapAlloc|HeapCompact|HeapCreate|HeapDestroy|HeapFree|HeapLock|HeapQueryInformation|HeapReAlloc|HeapSetInformation|HeapSize|HeapUnlock|HeapValidate|HeapWalk|'
memory_virtual = 'VirtualAlloc|VirtualAllocEx|VirtualFree|VirtualFreeEx|VirtualLock|VirtualProtect|VirtualProtectEx|VirtualQuery|VirtualQueryEx|VirtualUnlock|'
dynamic_linking = 'DisableThreadLibraryCalls|DllMain|FreeLibrary|FreeLibraryAndExitThread|GetDllDirectory|GetModuleFileName|GetModuleFileNameEx|GetModuleHandle|GetModuleHandleEx|GetProcAddress|LoadLibrary|LoadLibraryEx|SetDllDirectory|LoadModule|'
process_management = 'CreateProcess|CreateProcessAsUser|CreateProcessWithLogonW|CreateProcessWithTokenW|ExitProcess|FreeEnvironmentStrings|GetCommandLine|GetCurrentProcess|GetCurrentProcessId|GetCurrentProcessorNumber|GetEnvironmentStrings|GetEnvironmentVariable|GetExitCodeProcess|GetGuiResources|GetLogicalProcessorInformation|GetPriorityClass|GetProcessAffinityMask|GetProcessHandleCount|GetProcessId|GetProcessIdOfThread|GetProcessIoCounters|GetProcessPriorityBoost|GetProcessShutdownParameters|GetProcessTimes|GetProcessVersion|GetProcessWorkingSetSize|GetProcessWorkingSetSizeEx|GetStartupInfo|NeedCurrentDirectoryForExePath|OpenProcess|SetEnvironmentVariable|SetPriorityClass|SetProcessAffinityMask|SetProcessPriorityBoost|SetProcessShutdownParameters|SetProcessWorkingSetSize|SetProcessWorkingSetSizeEx|TerminateProcess|WinExec|'
process_enumerate = 'EnumProcesses|Process32First|Process32Next|WTSEnumerateProcesses|'
thread_management = 'AttachThreadInput|CreateRemoteThread|CreateThread|ExitThread|GetCurrentThread|GetCurrentThreadId|GetExitCodeThread|GetThreadId|GetThreadIOPendingFlag|GetThreadPriority|GetThreadPriorityBoost|GetThreadTimes|OpenThread|ResumeThread|SetThreadAffinityMask|SetThreadIdealProcessor|SetThreadPriority|SetThreadPriorityBoost|SetThreadStackGuarantee|Sleep|SleepEx|SuspendThread|SwitchToThread|TerminateThread|ThreadProc|TlsAlloc|TlsFree|TlsGetValue|TlsSetValue|WaitForInputIdle|'
##
# Create a filter for API calls we want to place a breakpoint on
##
filter = '|'
filter += file_management + file_io + file_mapping
#filter += memory_management + memory_global_and_local + memory_heap + memory_virtual
#filter += dynamic_linking
#filter += process_management + process_enumerate + thread_management
def not_filtered(address, section, type, apicall, comment):
if(type != 'Export'):
return 0
f = apicall
if(apicall[-1] in ['A', 'W']):
f = apicall[0:-1]
if(filter.find('|' + f + '|') >= 0):
return 1
return 0
def main():
base_address = 0
expression = 'Q'
f = sys.stdin
line = f.readline() # Names in kernel32
m = RE_title.match(line)
if(not m):
print "ERROR: invalid 1st line\n%s" % line
return 1
module, base_address = m.group(1,2)
base_address = long(base_address, 16)
line = f.readline() # Address Section Type (Known) Name Comment
m = RE_heading.match(line)
if(not m):
print "ERROR: invalid 2nd line\n%s" % line
return 1
while 1:
line = f.readline()
if(not line): break
m = RE_api_info.match(line)
if(not m): break
address, section, type, apicall, comment = m.group(1, 2, 4, 6, 8)
address = long(address, 16)
if(not_filtered(address, section, type, apicall, comment)):
print "%s:%08X:%s:%s" % (module, address-base_address, expression, apicall)
return 0
main()
%<------%<------%<--CUT_HERE----%<------%<------%<------%<
|
Note: Registration is required to post to the forums.
|
|
 |
|
There are 31,328 total registered users.
|
|