Open EpicLPer opened 1 year ago
@guino yep, long before i put the waiting into the bg which seems to trigger a watchdog. there is no chance to wait for so long.
For a test i put iirc 8 * nop
instruction at the start of void ht_log_init(void)
the first sub in main().
It worked without killing the log function, but we could live without the logging...
My problem is the ldr
part. i don't understand how to load the statusMQTT variable into r3
in assembler code.
i "copied" the code block from tuya_main()
while (statusMQTT != 1) {
sleep(1);
}
0009c498 01 00 a0 e3 mov r0,#0x1
0009c49c 18 de fe eb bl <EXTERNAL>::sleep
0009c4a0 a0 30 9f e5 ldr r3,[PTR_DAT_0009c548]
0009c4a4 03 30 8f e0 add r3,pc,r3
0009c4a8 00 30 93 e5 ldr r3,[r3,#0x0]=>statusMQTT
0009c4ac 01 00 53 e3 cmp r3,#0x1
0009c4b0 f8 ff ff 1a bne LAB_0009c498
into the free part of void ht_log_init(void)
but i didn't get ldr to point to the statusMQTT.
@jonesMeUp here's what I'd try (this will SET the statusMQTT and at the same time skip the loop):
0009c4a0 a0 00 9f e5 ldr r0,[0x9c548]
0009c4a4 01 30 a0 e3 mov r3,#0x1
0009c4a8 00 30 00 e5 str r3,[r0,#0x0]
0009c4ac 01 00 53 e3 cmp r3,#0x1
0009c4b0 f8 ff ff 1a bne LAB_0009c498
YOU MUST ALSO modify the bytes on address 0x9c548 to be: 1c 4d 43 00
If that's not what you want to do you may give me some more detail... in any case, if you want to load the contents of statusMqtt (0x434dc1) into r3 the instruction should be:
ldr r3,[0x9c548]
along with modifying the bytes in 0x9c548 to be 1c 4d 43 00
(as I did with r0 above).
If you wanted to just set the variable from an outside script I assume that trick with echo+dd would work (as you previously confirmed):
echo -en '\x01\x00\x00\x00' | dd of=/proc/$PID/mem bs=1 count=4 seek=$((0x434d1c))
@jonesMeUp some other piece of information which can help.. apparently this can prevent the watchdog from resetting the device:
(while true; do sleep 5; echo -n 1 > /dev/watchdog; done ) < /dev/null >& /dev/null &
(basically sending 1
to /dev/watchdog every 5 seconds)
I kept my device running for a few minutes without a reboot and without anyka_ipc running that way -- however: the biggest problem is that anyka_ipc is what configures/connects the wifi on the device (so you can sync the time) so you'd have to start and configure the wifi by hand in order to get the time before running anyka_ipc. Still could be an option if all else fails.
@guino thx for your support!
You misunderstood me. I used your hint to set statusMQTT in hack.sh
as soon as ntpd has done its job.
What i want ito do:
while (statusMQTT != 1) {
sleep(1);
}
Place this loop at 0x00065bc8 in void ht_log_init(void)
thats in main()
NOT in tuya_main()
There is enough "empty" space for this loop and i want to test it for sideeffects.
If this will work, i want to overwrite the loop in tuya_main() with a call to ht_log_init(void)
(The original caller function to ht_log_init(void) will be NOP out for the testing, later it can be "repaired")
At this position the wlan should be working and the time sync shouldn't be started.
This should work on both versions: your online and mine offline version.
while (statusMQTT != 1) {
sleep(1);
}
But i don't get the ldr to work. I now it holds a reference to an address, but i don't have a clue how to calculate the offset. I asked the Duck, but got only topics where you must know already assembler to understand it.
I thought 2.10.36 is available again, but looks like it's just the hack makes it believe it's running 2.10.36.
@jonesMeUp there's not a lot to it:
READ data from any address (into r3):
ldr r0,[0xPOINTER_ADDRESS]
ldr r3,[r0,#0x0]
WRITE data to any address (from r3):
ldr r0,[0xPOINTER_ADDRESS]
str r3,[r0,#0x0]
In both cases POINTER_ADDRESS will be an address containing the address to read/write, so if you wanted to read/write to 0x434d1c you would have to place the bytes 1c 4d 43 00
somewhere (near the code) and call that 'somewhere' POINTER_ADDRESS. You could even take out part of a string to write those bytes. In my example above https://github.com/guino/Merkury1080P/issues/42#issuecomment-1360832460 I used 0x9c548 because it was already storing some address used by code I overwrote. There's no 'offset calculation' required for this method, just requires the 8 bytes (for the 2 instructions) + 4 bytes to store the absolute address to read/write (but has to be near the code).
So you'll need to copy all the bytes from the loop code to 0x065bc8 (assuming you have space) then you'll need some other 4 bytes (near that code) to put the address bytes 1c 4d 43 00
. It could look like this:
LOOP: 01 00 a0 e3 mov r0,#0x1
18 de fe eb bl <EXTERNAL>::sleep
a0 30 9f e5 ldr r3,[POINTER_ADDRESS]
00 30 93 e5 ldr r3,[r3,#0x0]
01 00 53 e3 cmp r3,#0x1
f8 ff ff 1a bne LOOP
?? ?? ?? ea b EXIT_LOOP
POINTER_ADDRESS:
1c 4d 43 00
EXIT_LOOP:
<existing code>
(notice the 'missing' add instruction since I'm using absolute address defined in the POINTER_ADDRESS memory location)
You also have the option to use a few more instructions to build the address directly:
LOOP: 01 00 a0 e3 mov r0,#0x1
18 de fe eb bl <EXTERNAL>::sleep
1c 30 a0 e3 mov r3,#0x1c
4d 3c 83 e3 orr r3,r3,#0x4d00
43 38 83 e3 orr r3,r3,#0x430000
00 30 13 e5 ldr r3,[r3,#0x0]
01 00 53 e3 cmp r3,#0x1
f9 ff ff 1a bne LOOP
Either one should work as long as you have enough space -- chances are whatever code you're overwriting/deleting (to put your code in place) already uses some address nearby that you can use for a pointer_address making it simpler to write without adding jumps or multiple instructions (seems like 0x65ca8 is the perfect POINTER_ADDRESS for you).
I thought 2.10.36 is available again, but looks like it's just the hack makes it believe it's running 2.10.36.
Yes, the hack uses a main application 2.10.36 so it reports that version to the server. I never did look into changing that since it works fine, but it could prevent us from knowing when a 2.10.36 is actually available for that device. Chances are it may come out as a different version than 2.10.36 anyway.
@guino i used your build the address directly
version for my testings, worked well. I also added much nop
instructions for you to give us more nice functions ;)
Still no success on localtime, but added current lumi: x
to the event loop. I want to use the camera to switch on a light when its dark on movement event. Currently i use a _Sun_RiseSetTimer calculation for this, but its not very accurate.
I hope to find more time for my testings, now that the holidays are nearly over.
date
and hwclock
now shows the correct date/time, so no more 1970 as root of the streaming folder.
But the video-stream still differs 1h. I will spend some more time on it, but if it tooks to much time - i will give up and live with it.
I will post my actual hack.sh and the patch file as soon as the 1h problem is fixed (or if i get lost in the fix).
@jonesMeUp Nice to hear you've made progress. I recommend you try a normal boot (i.e. no SD card) to verify the video time is correct -- if it's off by 1h without the SD card then the issue isn't related to your changes (likely just some other setting).
@guino of course the problem is related to the offline patch. There are many functions that are only called when the device is online.
To get the date fixed for the streaming folder i had to rewrite the IPC_APP_Sync_Utc_Time()
funtion (which didn't make any sense in the offline version).
The timestamp was coming from tuya server as a json string, now dd
writes the timestamp into the new funtion after the time was synced.
I have already seen a possible location for the 1h problem:
[01-10 04:55:36-- TUYA Debug][gw_intf.c:4405] timezone:+01:00
The lines of the logfile are crying in my head, so i have to spend some time there.
@guino after searching for endless hours in the code, without any success, i think they are cheating.
Can you please check if date
and hwclock
differ, on your online cam, also to the vlc time display?
@jonesMeUp sorry it's been a busy few days here.
This is my doorbell (2.9.6 fw):
~ # date
Tue Jan 17 14:24:31 CST 2023
~ # hwclock
-sh: hwclock: not found
~ # /mnt/mmc01/busybox hwclock
hwclock: can't open '/dev/misc/rtc': No such file or directory
~ # ls -la /etc/TZ
-rwxr-xr-x 1 wagner root 12 Jan 17 02:07 /etc/TZ
~ # cat /etc/TZ
CST05:00:00
This is my indoor dumb camera (2.7.6 fw):
~ # date
Tue Jan 17 14:26:38 CST 2023
~ # hwclock
-sh: hwclock: not found
~ # /mnt/mmc01/busybox hwclock
hwclock: can't open '/dev/misc/rtc': No such file or directory
~ # ls -la /etc/TZ
-rwxr-xr-x 1 wagner root 12 Jan 17 01:04 /etc/TZ
~ # cat /etc/TZ
CST05:00:00
This is my rotating camera (2.10.36):
~ # date
Tue Jan 17 09:29:56 GMT 2023
~ # hwclock
Tue Jan 17 09:29:57 2023 0.000000 seconds
~ # ls -la /etc/TZ
lrwxrwxrwx 1 1000 1000 7 Aug 24 2021 /etc/TZ -> /tmp/TZ
~ # ls -la /tmp/TZ
-rw-rw-rw- 1 root root 10 Jan 17 09:27 /tmp/TZ
~ # cat /tmp/TZ
GMT+05:00
My local time was 14:24-29 when testing the above -- please notice I am on Eastern US timezone (despite it showing CST), but all my devices show the correct time on the video.
@guino so i searched many hours in my patches, but the gmt/date/hwclock
"glitch" was in the original app already.
After you confirmed my suspicion, i updated my post to my actual version, showing the correct time only in OSD (like the original version). https://github.com/guino/Merkury1080P/issues/42#issuecomment-1353850449
Cyberduck ftp Server (192.168.xxx.xx) port 21 user: root pass:telnet
Heya!
Bought a LSC Smart Outdoor (IP) Camera yesterday and tried this hack, but sadly it didn't seem to work. I added the camera to Tuya and had to update it before being able to use it (which probably was a mistake in hindsight).
The Firmware version on it right now is 2.10.36, and the only open ports I see are 53 and 6668.
If you need anything, I'm willing to open the camera up and do have soldering skills, I've also helped to dump the Sonoff cam a few years back and then figuring some things out :)
Thanks already for your help!