Driver load/unload fails if WinDbg attached with breakpoint - driver

I just started with driver development. For some experiments with loading, unloading and debugging I have written the following simple driver:
#include <ntddk.h>
void DriverUnload(PDRIVER_OBJECT pDriverObject)
{
UNREFERENCED_PARAMETER(pDriverObject);
DbgPrint("Driver unloading\n");
}
NTSTATUS DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
{
UNREFERENCED_PARAMETER(DriverObject);
UNREFERENCED_PARAMETER(RegistryPath);
DriverObject->DriverUnload = DriverUnload;
DbgPrint("Hello, World\n");
return STATUS_SUCCESS;
}
I compiled the driver for my target system, Windows 7 64bit, with debug symbols, copied it to target system and loaded and run it with OSR Driver Loader.
Everything works fine and I can unload and load the driver:
I can connect with WinDbg using a serial connection and can successfully break and run the target system. However, the problem occurs when I try to set a breakpoint.
I initially tried setting the breakpoint like this:
kd> bp MyDriver1!DriverEntry
but the problem was, if I reloaded the driver and checked the breakpoints:
kd> bl
0 e fffff880`03572010 0001 (0001) < Unloaded_MyDriver1.sys >+0x1010
For me as beginner, it didn't look good (unloaded?) and no breaks occurred when loading.
So, I found out that its possible to set a breakpoint when a module is loaded:
kd> bu MyDriver1
0 e fffff880`03578000 0001 (0001) MyDriver1!DriverEntry < PERF > (MyDriver1+0x0)
When I continue system execution after the above command and load the driver (net start MyDriver1) the system crashes:
Break instruction exception - code 80000003 (first chance)
*
You are seeing this message because you pressed either *
CTRL+C (if you run console kernel debugger) or, *
CTRL+BREAK (if you run GUI kernel debugger), *
on your debugger machine's keyboard. *
*
THIS IS NOT A BUG OR A SYSTEM CRASH *
*
If you did not intend to break into the debugger, press the "g" key, then *
press the "Enter" key now. This message might immediately reappear. If it *
does, press "g" and "Enter" again. *
*
nt!RtlpBreakWithStatusInstruction: fffff800028ca490 cc int 3
kd > bu MyDriver1 kd> bl 0 e fffff88003572010 0001
(0001) MyDriver1!DriverEntry < PERF > (MyDriver1+0x0)
kd > bc 0 kd> bl 1 e fffff880`03578000 0001 (0001)
MyDriver1!DriverEntry (MyDriver1+0x0)
kd> g Access violation - code c0000005 (!!! second chance !!!)
nt!IopUnloadDriver+0x327: fffff800`02cb8b29 0fb74844 movzx
ecx,word ptr [rax+44h]
Finally, if I continue the execution now, I get a BSOD ...
Whats wrong here? Is my code wrong or am I setting the breakpoints not correctly?

The command you are looking for is
sxe ld:MyDriver1
This will break when the driver is mapped into memory but before calling MyDriver1!DriverEntry and will allow you to put breakpoints at DriverEntry.
The command bu MyDriver1 puts a breakpoint in the first byte of the PE header of the driver image.
Also, clean up breakpoints after you unload the driver otherwise you cause the debugger to modify memory that could be allocated for something else.

Related

Success callback function called on failure. Possible bug?

I'm working on a little project, using an ESP8266 with NodeMCU and Lua. I suspect I've found a bug, but since I'm new to Lua (and the other two too!), I'm hoping for some help in confirming if I'm right, or if I've missed something (more likely!).
The NodeMCU firmware contains a built-in SNTP client module which updates the synchronised time to a system clock (rtctime module). The success callback function seems to get called when (or possibly before) the NTP sync fails. This happens for example if the wifi is not connected, or sometimes on the first sync attempt after boot (with wifi connected). According to the doco, rtctime.get() returns zero if current time is not available; this is the result I get, further showing that the NTP sync hasn't been successful. I can't work out why the success function is being called at this point, in advance of, or instead of the failure function (as I would have expected).
The sntp module I'm referring to is here - unfortunately, the C source code was a bit over my head: https://nodemcu.readthedocs.io/en/master/en/modules/sntp/
My (minimal) code:
-- Define callback function for ntp sync success
function ntpSyncSuccess (sec, usec, server, info)
print('SNTP time sync successful!')
print("rtctime.get() returns: ", rtctime.get())
end
-- Configure and start NTP time sync with auto repeat enabled
sntp.sync("0.au.pool.ntp.org",
ntpSyncSuccess(sec, usec, server, info), --success callback
function() -- error callback
print('SNTP time sync failed!')
end,
1 -- enable autorepeat (SNTP sync every 1000 seconds (~17 min))
)
Serial output result when I boot the device and run the code (Note the 2nd and 3rd last lines):
NodeMCU custom build by frightanic.com
branch: master
commit: 11592951b90707cdcb6d751876170bf4da82850d
SSL: false
modules: cron,file,gpio,i2c,net,node,rotary,rtctime,sntp,struct,tmr,uart,wifi
build created on 2019-01-16 03:11
powered by Lua 5.1.4 on SDK 2.2.1(6ab97e9)
lua: cannot open init.lua
> print(uart.setup(0, 115200, 8, 0, 1, 1 ))
115200
> dofile("ntpTest.lua")
SNTP time sync successful!
rtctime.get() returns: 0 0 0
> SNTP time sync failed!
Just so that we can "close" this Q here (once you accept the answer). It has to be a function reference rather than a function invocation.
sntp.sync("0.au.pool.ntp.org",
ntpSyncSuccess, -- no (), no parameters
function() -- error callback

ESP8266 Fatal exception (0) using NodeMCU

When i boot ESP8266 i'm getting on my arduino MEGA serial monitor.
Fatal exception (0): e2= 0d00l(xp00v0xao1,00e0c pe80c00d0x:2= 0d00l(xp00v0xao1,00e0c pe80c00d0x:2= 0d00l(xp00v0xao1,00e0c e 0xp0= 0e)02,0d00a 0e00c00Fic00= 0p0e 0xp0= 0e)02
If i do a hard reset than it prints
Jan 8 2013,rst cause:4, boot mode:(3,6) wdt reset load 0x40100000, len 28740, room 16 tail 4 chksum 0xcd load 0x3ffe8000, len 2888, room 4 tail 4 0xeotail 0 chks
I used NodeMcu flasher nodemcu_integer_0.9.5_20150318.bin and NodeMCU 0.9.5 build 20150318 powered by Lua 5.1.4. I'm using arduino UART (serial monitor) to talk to ESP8266. BAUD RATE : 115200 FLASH SIZE : 4MB FLASH SPEED : 40MHz SPI : DIO Module is powered with apt power (separate power supply)
Here's my connections:
//////////////////////////////////////////////////////////////////////////////
/////// CONNECTIONS ////////
/////////////////////////////////////////////////////////////////////////////
/*
ESP8266 VCC -> BeagleBone 3.3
ESP8266 GND -> Common GND (Arduino & BeagleBone)
ESP8266 CH_PD -> 3K resistor -> VCC
ESP8266 RST -> VCC or pin 13(arduino)
GPIO CAB BE LEFT OPEN OR TIED HIGH
ESP8266 Tx -> pin2 (Arduino software serial Rx)
ESP8266 Rx <- Voltage Divider <- pin3 (Arduino software serial Tx)
*/
Here's my code
#define esp8266 Serial2
#define CH_PD Vcc // but needs a narrow low pulse
#define speed8266 9600 // This is the speed that worked with my ESP8266
void setup()
{
esp8266.begin (speed8266);
Serial.begin(9600);
reset8266(); // Pin CH_PD need a reset before start communication
}
void loop()
{
while(esp8266.available())
{ Serial.write(esp8266.read()); }
while(Serial.available())
{ esp8266.write(Serial.read()); }
}
/*************************************************/
// Reset funtion to accept communication
void reset8266 ()
{
pinMode(CH_PD, OUTPUT);
digitalWrite(CH_PD, LOW);
delay(300);
digitalWrite(CH_PD, HIGH);
}
Here are some snaps of the configuration i did in NodeMCU ( i had already tried with different baud rates)
Advanced Configuration
Configuration
If you are getting fatal error exception like this:
Exception (3):
epc1=0x401003e9 epc2=0x00000000 epc3=0x00000000 excvaddr=0x4000cbd9 depc=0x00000000
In infinite loop in your serial monitor of arduino IDE .
then goto this link download the software and follow the procedure and erase the flash memory to solve the error.
This does not solve fatal error that occurs due to your program but in case your device goes in such condition that it can’t be able to access program memory then it will work and try atleast one time to solve the problem.
This is the procedure to hard reset the nodemcu
( https://www.youtube.com/watch?v=MHrm7axsImI&t=146s )
Step :
Install latest python version in you pc.(https://www.python.org/downloads )
Open cmd prompt as administrator .
Go to c/program files or program files (x86)->python (your version)->Script. For this type (cd c/program files (x86)/python(your version)/Script) then press enter .
Now type (pip install esptool).
Now download ESPlorer ( https://esp8266.ru/esplorer/ ) version(Download ESPlorer.zip (v 0.2.0-rc6)) and extract the file and open executable jar file .
Now goto nodemcu firmware site (https://github.com/nodemcu/nodemcu-firmware/releases ) and from download file (nodemcu_float_0.9.6-dev_20150704.bin ) and copy this file into the c/program files (x86)/python(your version)/Script folder .
Now in cmd prompt just type.
esptool.py --port COM(your port no.) --baud 115200 erase_flash
And press enter.
Note : you can see your port no. into the device manager .
For NODEMCU users who face this issue
This needs to be done only once (first time you connect nodemcu to PC)
Download and run the 32 or 64 bit flasher*:
32 bit: https://github.com/nodemcu/nodemcu-flasher/blob/master/Win32/Release/ESP8266Flasher.exe
64 bit: https://github.com/nodemcu/nodemcu-flasher/blob/master/Win64/Release/ESP8266Flasher.exe
Select the download button on github and open file once downloaded.
Select the chip port from the previous step (Com 6 for me), and then select flash (this should only have to be done once) close flash program once completed. Process is completed when you get the green checkmark in the bottom left hand corner.
PS: make sure you disconnect and re-connect the nodemcu once done
REFERENCE: https://www.instructables.com/NodeMcu-ESP8266-First-Time-Setup-With-Arduino-IDE/

NodeMCU Custom Firmware Problems

After flashing an ESP8266 with a custom NodeMCU build ist doesn't work as with the version before. For the custom build I've used the cloud service at http://nodemcu-build.com, the prior version was nodemcu_float_0.9.6-dev_20150704.bin from github.
The problem now is that communication over serial port now is quirky, sometimes it seems to work, sometime not.
Example:
When I list files:
> for k,v in pairs(file.list()) do l = string.format("%-15s",k)
print(l.." >..v.." bytes") end
stdin:1: ')' expected near 'bytes'
>
>
Or when I execute node.chipid()
þ®ÈJÀHƒÌHÜÞ{½ÝÕ½{ommw¯­íë= node.chipid()
> = node.cèipid()
stdin:1: '<eof>' expected near 'è'
> = node.,+¥‘¡)
stdin:1: '<name>' expected near ','
> = node.,+¥‘¡)
stdin:1: '<name>' expected near ','
> = node.chipid()
13840686
> = node.chipid()
13840686
> = node.chipid()
13840686
>
In the above exapmle I've executed node.chipid() six or seven times, the latter two times it worked. Errors of this kind happen over and over again, uploading lua files doesn't work, although success was stated.
I've tried it with LuaLoader and LuaUploader, it is reproducable. When flashing the older firmware, everything works as expected, but it doesn't provided some modules I want to use. For flashing I've used ESP8266Flasher.exe.
What is going wrong? What did I do wrong? Changing baud rates did make some differences, but the problems persist.
I think the default baud changed with the latest version, try setting the reading side's baud rate to 115200.
Alternatively, try setting the baud rate of the ESP lower (9600) using lua code in the init file, mayby 115200 is too fast for your serial chip.
If you're using ESPlorer to send Lua code/files try turning on 'turbo' mode in the settings. I vaguely remember issues like that.

How to continously load data in Riak with erlang file

I want to run a programme that loads a data into riak database, but the process is stopping suddenly when i gave range about 10. if i gave 5-8 it is taking and loading the data, when i give range more than 10 it was hanging up. what was happening.
test(X,Y) ->
if X < Y ->
{ok,Pid} = riakc_pb_socket:start_link("127.0.0.1",10017),
Val = X,
io:format("~p",[Pid]),
Object = riakc_obj:new(<<"test_age">>,undefined,Val),
riakc_pb_socket:put(Pid,Object),
test(X+1,Y);
true -> []
end.
The function will take a range of numbers and just insert into the riak database with adding the numbers to the old number.
when i run this programme from the erlang shell it is stopping after taking the range about 10:
erlriak:test(1,5)
<0.50.0><0.51.0><0.52.0><0.53.0><0.54.0>[]
erlriak:test(5,15)
<0.62.0><0.63.0><0.64.0><0.65.0><0.66.0><0.67.0><0.68.0><0.69.0><0.70.0>|
It was hanging after the <0.70.0> for minutes and nothing is returning.I am getting the following:
=ERROR REPORT==== 19-May-2014::17:29:54 ===
** Generic server <0.104.0> terminating
** Last message in was {req_timeout,#Ref<0.0.0.423>}
** When Server state == {state,"127.0.0.1",10017,false,false,undefined,false,
gen_tcp,undefined,
{[],[]},
1,[],infinity,undefined,undefined,undefined,
undefined,[],100}
** Reason for termination ==
** disconnected
** exception exit: disconnected
I suspect you are exceeding the limit for simultaneous connections to Riak's PB port. Possible solutions:
call riakc_pb_socket:stop(Pid) to close the connection before recursing
move the call to start_link outside the test function so all requests share the same socket
increase pb_backlog in your app.config so you can have more simultaneous connections

Move execution point in Xcode/lldb

Is there a way to set the execution point while debugging Xcode/lldb? To be more specific, after hitting a breakpoint, moving the execution point manually to another line of code?
If you're looking at moving it up or down with in a method you can click and drag the green arrow to a specific point. so if you want to back up a line before the breakpoint. click on the green arrow that is produced and drag it up. If you hit run you'll hit your breakpoint again
In Xcode 6, you can use j lineNumber - see documentation below:
(lldb) help j
Sets the program counter to a new address. This command takes 'raw' input
(no need to quote stuff).
Syntax: _regexp-jump [<line>]
_regexp-jump [<+-lineoffset>]
_regexp-jump [<file>:<line>]
_regexp-jump [*<addr>]
'j' is an abbreviation for '_regexp-jump'
One of the great things about lldb is that it's easy to extend it with a little bit of python scripting. For instance, I threw together a new jump command without much trouble:
import lldb
def jump(debugger, command, result, dict):
"""Usage: jump LINE-NUMBER
Jump to a specific source line of the current frame.
Finds the first code address for a given source line, sets the pc to that value.
Jumping across any allocation/deallocation boundaries (may not be obvious with ARC!), or with optimized code, quickly leads to undefined/crashy behavior. """
if lldb.frame and len(command) >= 1:
line_num = int(command)
context = lldb.frame.GetSymbolContext (lldb.eSymbolContextEverything)
if context and context.GetCompileUnit():
compile_unit = context.GetCompileUnit()
line_index = compile_unit.FindLineEntryIndex (0, line_num, compile_unit.GetFileSpec(), False)
target_line = compile_unit.GetLineEntryAtIndex (line_index)
if target_line and target_line.GetStartAddress().IsValid():
addr = target_line.GetStartAddress().GetLoadAddress (lldb.target)
if addr != lldb.LLDB_INVALID_ADDRESS:
if lldb.frame.SetPC (addr):
print "PC has been set to 0x%x for %s:%d" % (addr, target_line.GetFileSpec().GetFilename(), target_line.GetLine())
def __lldb_init_module (debugger, dict):
debugger.HandleCommand('command script add -f %s.jump jump' % __name__)
I put this in a directory where I keep Python commands for lldb, ~/lldb/, and I load it in my ~/.lldbinit file with
command script import ~/lldb/jump.py
and now I have a command jump (j works) which will jump to a given line number. e.g.
(lldb) j 5
PC has been set to 0x100000f0f for a.c:5
(lldb)
This new jump command will be available both in command-line lldb and in Xcode if you load it in your ~/.lldbinit file -- you'll need to use the debugger console pane in Xcode to move the pc instead of moving the indicator in the editor window.
You can move the program counter (pc) in lldb using the lldb command register write pc. But it's instruction based.
There's an excellent lldb/gdb comparison here that is useful as an lldb overview.

Resources