Mehrere JPG-Bilder in ein PDF konvertieren

By dose | November 5, 2019
Under: Uncategorized
Comments: No Comments »

Es kommt immer einmal wieder gerne vor, dass man – um sich die teuren Kopiergebühren zumindest temporär zu ersparen – Akten abfotografiert.
Hierbei kommen dann ein Haufen JPG Bilder zusammen in meistens unterschiedlichen Ausrichtungen: Mal kopfüber, mal richtig, mal quer, je nachdem, wie es das Tablet/Handy gerade für gut befindet.
Um die Bilder in die richtige Ausrichtung zu bringen und in ein PDF zu wandeln, habe ich mir eine kleine Batchdatei geschrieben, die dies erledigt.
Hierfür werden das kostenlose OCR-Programm Tesseract und das ebenfalls freie Tool jpegtran (für Seitenerkennung und Ausrichtung) genutzt.
jpegtran muss sich im Suchpfad befinden, dann kann man einfach ein Verzeichnis mit .jpg Dateien auf die .bat Datei ziehen und diese wird konvertiert:

@echo off
setlocal enableextensions
set PATH=%PATH%;C:\Program Files (x86)\Tesseract-OCR\
echo Drehe Seiten...
for %%I in ("%~1\*.jpg") do (
  for /F "tokens=2"  %%F in ('tesseract.exe --psm 0 "%%I" stdout ^| find "Rotate:"') do (
    echo %%I um %%F Grad
    if not "%%F"=="0" jpegtran -rotate %%F "%%I" "%%I"
  )
)
echo Erstelle OCR-PDF...
dir /s /b "%~1\*.jpg" | tesseract - "%~1\combined" -l deu pdf
endlocal

MS SQL Server 2017 upstart script

By dose | October 30, 2019
Under: Uncategorized
Comments: No Comments »

I recently had to install a MS SQL Server 2017 on Linux. Unfortunately, the supplied scripts only support the stupid systemd, not upstart, so for Devuan or Debian Jessie without systemd, the script may be benificial:

!/bin/sh
### BEGIN INIT INFO
# Provides: mssql-server
# Required-Start:       $syslog $local_fs $network.
# Required-Stop:        $syslog $local_fs $network.
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description: Microsoft SQL Server Database Engine
### END INIT INFO
 
DESC="Microsoft SQL Server Database Engine"
NAME=mssql-server
PIDFILE=/var/run/$NAME.pid
DAEMON="/opt/mssql/bin/sqlservr"
SCRIPTNAME=/etc/init.d/mssql-server
USER=mssql
 
. /lib/lsb/init-functions
 
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
 
case "$1" in
        start)
                log_daemon_msg "Starting $DESC" "$NAME"
                start-stop-daemon --start --quiet --oknodo --chdir /var/opt/mssql --background --make-pidfile --pidfile $PIDFILE --chuid $USER \
                        --exec $DAEMON -- $DAEMON_ARGS
                log_end_msg $?
                ;;
        stop)
                log_daemon_msg "Stopping $DESC" "$NAME"
                start-stop-daemon --stop --retry=TERM/15/KILL/5 --remove-pidfile --pidfile $PIDFILE
                status=$?
                rm -f $PIDFILE
                log_end_msg $?
                ;;
        status)
                pidofproc -p $PIDFILE $DAEMON >/dev/null
                status=$?
 
                if [ $status -eq 0 ]; then
                        log_success_msg "$DESC is running"
                else
                        log_failure_msg "$DESC is not running"
                fi
                exit $status
                ;;
        reload|force-reload)
                log_daemon_msg "Reloading $DESC configuration..."
                start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
                log_end_msg $?
                ;;
        restart)
                $0 stop
                sleep 1
                $0 start
                ;;
        *)
                echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload|status}"
                exit 1
                ;;
esac

Unformtunately, MS SQL Server 2017 on Debian Jessie is a real pain to install. Newer versions tend to crash (coredump) very often and without a recent openssl-version from jessie-backports (which can only be installed with a little trick nowadays), it just drops every TCP connection to the server on client side with:

Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : TCP Provider: Error code 0x2746.
Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : Client unable to establish connection.

and on server side respectively with error 0x80090304

So we need a suitable version of MS SQL Server and the correct version of openssl to get it working.
Here is what seems to work here (currently stress testing with HammerDB before productive use):

apt-get install curl apt-transport-https
echo "deb http://archive.debian.org/debian/ jessie-backports main contrib non-free" >>/etc/apt/sources.list
echo 'Acquire::Check-Valid-Until no;' > /etc/apt/apt.conf.d/99no-check-valid-until
apt-get update
apt-get install -t jessie-backports openssl
curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
curl https://packages.microsoft.com/config/ubuntu/16.04/mssql-server-2017.list | sudo tee /etc/apt/sources.list.d/mssql-server.list
apt-get install mssql-server=14.0.1000.169-2
/opt/mssql/bin/sqlservr-setup

Paragon GPT loader #3

By dose | September 28, 2019
Under: Uncategorized
Comments: 2 Comments »

Recently, I bought a 3rd harddisk which is over 2TB in space and added it to my Desktop machine. As mentioned previously,I had to fix the gpt_loader.sys driver in order to not crash.

My patch worked quite well for a few years, but after adding the new drive, it always crashed with 0xc000001d. So I first thought about another bug in the driver, but then I saw, that the ExceptionCode means c000001d Illegal instruction. Then checking with the debugger, I found out that it crashed at a location that I patched. As the instruction in the closeDriver call was bogus,I immediately thought about a reloaction table entry that must have been written ot the wrong location and indeed – when moving up the code by 2 bytes to get space for my patch, I overlooked a reloaction entry in place.

As long as the driver wasn’t moved in memory and got loaded at the preferred load address, the bug didn’t surface,but due to the new drive, it seems that the driver was reloacted and so the bug struck me. Of course, it was easy to patch, I just had to adjust the reloaction table entry by 2 bytes as well. I updated the patch so that it patched this too. If you need to install this fix on your machine, the patch created a gpt_loader.bak file in the %SystemRoot%\drivers directory. Just restore the gpt_loader.bak to gpt_loader.sys, then apply the updated patch from here and also don’t forget to apply the second patch.

If you have further questions, feel free to ask.

Windows 7 Professional as RemoteApp Server

By dose | September 27, 2019
Under: Uncategorized
Comments: No Comments »

I found out, that Windows 7 Professional doesn’t support providing RemoteApps to clients per default, only Windows 7 Enterprise, Ultimate or higher provides this functionality.
But fortunately, I found this thread on github.
You need to follow all the instructions in the thread:
The following files can be found in various subdirectories of the %SystemRoot%\WinSXS directory and copied to the appropriate place:

%SystemRoot%\system32\rdpinit.exe
%SystemRoot%\system32\rdpshell.exe
%SystemRoot%\system32\TSErrRedir.dll
%SystemRoot%\system32\tspubwmi.dll
%SystemRoot%\system32\wbem\tsallow.mof
%SystemRoot%\system32\spp\tokens\ppdlic\terminalservices-remoteapplications-clientsku-ppdlic.xrm-ms

Then register the components:

RegSvr32 %SystemRoot\system32\tspubwmi.dll
mofcomp %SystemRoot%\system32\wbem\tsallow.mof

Now patch %SystemRoot%\system32\rdpinit.exe (0x8000404 to 0x00000001)

rdpinit.exe (1.7601.17514) 32bit:

0000568E: 04 01
0000568F: 40 00
00005690: 00 00
00005691: 80 00

rdpinit.exe (1.7601.17514) 64bit:

0000611D: 04 01
0000611E: 40 00
0000611F: 00 00
00006120: 80 00

Finally add registry keys:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\TerminalTypes\eddcc3ce-6e7e-4f4b-8439-3d9ad4c9440f]
"Name"="Remote Applications Terminal"
"SessionSource"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\ConnectionHandler\eddcc3ce-6e7e-4f4b-8439-3d9ad4c9440f]
"CLSID"="2be8bdbb-be09-499d-9a4b-4637e09ae00b"
"Description"="Default Connection Handler"
"Name"="Default Connection Handler"
"fAcceptConnection"=dword:00000001

Now restart Terminal services and use RemoteAppTool to create Remote Applications and .rdp files for the clients.

KB4500331 (fixes CVE-2019-0708) for Windows XP SP2

By dose | May 16, 2019
Under: Uncategorized
Comments: No Comments »

KB4500331 fixes a critical bug in Microsoft Windows RDP protocol in Windows XP and Windows 7.
The patch is available via the Microsoft update site. However it is only available for Windows XP SP3. When looking at the code, I found out that it also works properly with XP SP2, so if you are a user who cannot or doesn’t want to upgrade to XP SP3, here is my patched installer that also allows you to install the update on SP2.

“Word kann den Speichervorgang aufgrund eines Berechtigungsfehlers nicht zu Ende führen” Problem seit 22.2.2019

By dose | February 27, 2019
Under: Uncategorized
Comments: No Comments »

Diese Woche hatte ich gleich mehrere Benutzer, die plötzlich das Problem hatten, dass Microsoft Word keine Dateien mehr speichern konnte und oben genannte Fehlermeldung ausgaben.
Nach längerer Suche stellte sich heraus, dass wohl der Avira Antivirus an dem Problem schuld ist, ich musste das Programm daher entfernen und warte darauf, dass das Problem hoffentlich bald behoben ist. Ob Avira davon Kenntnis hat, weiß ich nicht. Die betroffenen Rechner liefen alle auf Windows 7, das kann aber auch Zufall sein.
Betroffen waren sowohl ältere (Word 2000), als auch neuere Word-Versionen (Word 2007)

Fixing an endless loop bug in the Xerox Unix printing Package 4.50.29 xsf tool

By dose | January 24, 2019
Under: Uncategorized
Comments: No Comments »

I got annoyed today by a Xerox printer that was driven via CUPS, where the queue hung forever from time to time.
So I investigated where it hung. Turns out, it got stuck in this loop:

int __cdecl SendLprCmd(int a1, int a2, int a3, int a4, int fd)
{
  int v5; // ST1C_4@21
  signed int v7; // [sp+10h] [bp-98h]@10
  int v8; // [sp+14h] [bp-94h]@17
  char s; // [sp+20h] [bp-88h]@2
 
  switch ( a1 )
  {
    case 1:
      sprintf(&s, "\x01%s\n", a2);
      break;
    case 2:
      sprintf(&s, "\x02%s\n", a2);
      break;
    case 7:
      sprintf(&s, "\x02%i %s\n", a3, a2);
      break;
    case 8:
      sprintf(&s, "\x03%i %s\n", a3, a2);
      break;
    case 3:
      sprintf(&s, "\x03%s\n", a2);
      break;
    case 4:
      sprintf(&s, "\x04%s\n", a2);
      break;
    case 0:
      s = 0;
      break;
    case 5:
    case 6:
      break;
  }
  RdBufI = 0;
  RdBuf = 0;
  if ( a1 )
    v7 = strlen(&s);
  else
    v7 = 1;
  if ( a1 == 1 )
  {
    write(fd, &s, v7);
  }
  else
  {
    while ( !pPN->byte38 )
    {
      if ( (pPN->byte38 || write(fd, &s, v7) == v7) && (v8 = GetLprResponse(a4, fd), v8 >= 0) && v8 != 1 )
      {
        if ( !v8 )
          return 0;
      }
      else
      {
        ReturnPrinterError(14, fd);
      }
      v5 = rand();
      sleep(v5 % 16 + 5);
    }
  }
  return 0;
}

Let’s have a look at ReturnPrinterError function:

int __cdecl ReturnPrinterError(int errcode, int fd)
{
  int *v2; // eax@2
  char v3; // ST14_1@2
 
  if ( errcode == 16 )
  {
    v2 = __errno_location();
    v3 = (unsigned int)strerror(*v2);
    WrStatus(pPN->fdError, "ERROR: %s\n", v3);
  }
  else
  {
    WrStatus(pPN->fdError, "ERROR: %s\n", (unsigned int)SocketErrorMsg[errcode]);
  }
  if ( fd > 0 )
    close(fd);
  return errcode;
}

So file descriptor gets closed in there and becomes invalid. Therefore write() call can never suceed again ever after, so we got stuck in an endless loop on error.
Upon calls of SendLprCmd, return value gets checked (0=success).
Turns out this function never returns anything different than 0. So conclusion: Routine shall return something != 0 in EAX if error occurs.
ReturnPRinterError always returns error code>0, so EAX gets set fine by this routine.
Let’s have a look at the ASM code of the call then:

.text:08049E9B loc_8049E9B:                            ; CODE XREF: SendLprCmd+17Dj
.text:08049E9B                                         ; SendLprCmd+19Dj ...
.text:08049E9B                 sub     esp, 8
.text:08049E9E                 push    [ebp+fd]        ; fd
.text:08049EA1                 push    0Eh             ; int
.text:08049EA3                 call    ReturnPrinterError
.text:08049EA8                 add     esp, 10h
.text:08049EAB                 jmp     short loc_8049EB8
.text:08049EAD ; ---------------------------------------------------------------------------
.text:08049EAD
.text:08049EAD loc_8049EAD:                            ; CODE XREF: SendLprCmd+1A8j
.text:08049EAD                 cmp     [ebp+var_94], 0
.text:08049EB4                 jnz     short loc_8049EB8
.text:08049EB6                 jmp     short loc_8049F0F
.text:08049EB8 ; ---------------------------------------------------------------------------
.text:08049EB8
.text:08049EB8 loc_8049EB8:                            ; CODE XREF: SendLprCmd+1BAj
.text:08049EB8                                         ; SendLprCmd+1C3j
.text:08049EB8                 sub     esp, 0Ch
.text:08049EBB                 sub     esp, 4
.text:08049EBE                 call    _rand
.text:08049EC3                 add     esp, 4

So instead of jumping back to rand sleep() routine, just let it bail out to 08049F14:

.text:08049F0F loc_8049F0F:                            ; CODE XREF: SendLprCmd+13Bj
.text:08049F0F                                         ; SendLprCmd+14Cj ...
.text:08049F0F                 mov     eax, 0
.text:08049F14                 leave
.text:08049F15                 retn
.text:08049F15 SendLprCmd      endp

JMP to rand() is EB 0B, so change it to new offset EB 67 @08049EAB:

08049E9C  EC 08 FF 75 18 6A 0E E8  D5 FC FF FF 83 C4 10 EB
08049EAC  0B 83 BD 6C FF FF FF 00  75 02 EB 57 83 EC 0C 83
-->
08049E9C  EC 08 FF 75 18 6A 0E E8  D5 FC FF FF 83 C4 10 EB
08049EAC  67 83 BD 6C FF FF FF 00  75 02 EB 57 83 EC 0C 83

So patch 0B @ file offset 1EAB to 67, problem fixed.

At least, bug seems to be fixed now, will have to look if there is an update to this buggy version of the printing system that runs on the target machine, but as it’s a productive machine, I first need a timeslot to test.

Backing up Outlook .pst files while in use

By dose | December 18, 2018
Under: Uncategorized
Comments: No Comments »

Microsoft Outlook is a very popular e-mail client nowadays.
Though cloud based services are becoming more popular, it’s still the case that i.e. e-mail storage at service providers is very limited. Therefore, there are a lot of people out there who are forced to download their e-mail and archive it in their e-mail client, i.e. in Microsoft Outlook .pst files.
Now we all know the problem of ransomware or physical disk damage that can kill the data storage location of the outlook .pst files.
For performance reasons, it’s better to keep the files locally on a possibly fast SSD drive and not to store them on a slow network drive.
Even though when files are stored on a network drive, there still is a problem that files are in an inconsistent state when being backed up from that location.
There are tools like SafePST that address this problem and promise to offer functions to do a background backup of a .pst file while the file is open and in use by the e-mail application.
Even though, they backup works, it is still not working well, as the destination file grows significally without getting compacted, as it seems (i.e. I had 20GB of Outlook .pst files which grw to 1TB in Size at the backup location – ridiculous).
There are plugins for outlook like Personal folder backup from Microsoft, that copy the .pst files on Outlook exit, but this also isn’t a solution for very large files, as it would take far too long and maybe ppl don’t close their Outlook for weeks.

So, why not use a simple backup strategy and do what all these disk imaging applications do:
Make a Volume shadow copy snapshot of the drive that contains the Outlook data files, so that the .pst file is in an at least somewhat consitant state and then copy it to the backup location?
It turns out that this can be accomplished very easily with the tools that are already shipped with Windows 7 or above. Therefore we can create a simple batch file in order to do this job.

First, Outlook profiles of the current user are collected, then volume snapshots are taken for all local drives that contain Outlook data files, next files are copied from the snapshot and finally the snapshot gets released. When copying from the snapshot to the Backup destination, we have to ensure that file is first copied completely before the old file gets overwritten, therefore taking up at least twice the size of the largest .pst file on the backup drive.
From the backup drive, you then can have a backup routine like rsnapshot which pulls off the files from the drive and stores it at a safe location.
Here is my batch file that does exactly that with descriptive comments, I hope you find it as useful as I do:

@echo off
REM
REM Outlook .pst file backup script for Outlook 2007 or above and Windows 7 or above
REM (c) leecher@dose.0wnz.at   12/2018
REM
REM ---------- Configuration
REM
REM Set this to the Microsoft office internal version number you are using
REM Works with Outlook 2007 or above:
REM 
REM Outlook 2007	12.0
REM Outlook 2010	14.0
REM Outlook 2013	15.0
REM Outlook 2016	16.0
REM Outlook 2019	16.0
set OFFICEVER=12.0
 
REM If you want logging to a file, set logfile here, otherwise leave it blank
set LOG=
 
REM Temporary file that records the volume shadow copied created.
REM Needed for removal on next run, if there is no clean exit.
REM Normally, you should keep it as it is
set SHADOWSF=%TEMP%\backup_pst.lst
 
REM Destination directory.. Taken as cmdline arg, modify if needed
set DEST=%1
 
REM
REM ---------- Implementation
REM
setlocal ENABLEDELAYEDEXPANSION
 
if "%DEST%"=="" (
  echo Usage: %0 [Backup Destination directory]
  exit /b
)
 
REM
REM 1) Check for admin rights, we need them to run properly
REM
net session >nul 2>&1
if errorlevel 2 (
  call :tee "ERROR: This script has to be run with administrative rights for VSS copying."
  exit /b 1
)
 
REM
REM 2) Collect .pst files we need to process preserving spaces into PSTS
REM
call :log ".pst file backup started"
set LW=
set PSTS=
for /f "tokens=1 delims=*" %%s in ('reg query HKCU\Software\Microsoft\Office\%OFFICEVER%\Outlook\Catalog /s ^| findstr "REG_BINARY"') do (
  set KEY=%%s
  set KEY=!KEY:REG_BINARY=^|!
  for /F "tokens=1 delims=^|" %%t in ("!KEY!") do (
    set KEY=%%t
    for /L %%a in (1,1,260) do (
        if "!KEY:~-1!"==" " set KEY=!KEY:~0,-1!
        if "!KEY:~0,1!"==" " set KEY=!KEY:~1!
    )
    set PSTS=!PSTS! "!KEY!"
  )
)
 
REM 
REM 3) Collect local drives we need to make a snapshot for
REM
for %%s in (!PSTS!) do (
  set FOUND=
  for %%i in (!LW!) do if "%%i"=="%%~ds" set FOUND=1
  if not !FOUND!==1 (
    for /F "delims=" %%L in ('
        2^>^&1 ^> nul wmic LogicalDisk where ^(DeviceID^="%%~ds" AND DriveType^=3^)
    ') do set FOUND=1
    if not !FOUND!==1 set LW=!LW! %%~ds
  )
)
 
REM
REM 4) If there are already volume shadow copies available, delete them first
REM
if exist %SHADOWSF% (
  for /f "tokens=2 delims= " %%s in (%SHADOWSF%) do (
    call :log "Removing stale volume shadow copy %%s"
    vssadmin delete Shadows /Shadow=%%s /quiet >nul
  )
)
 
REM
REM 5) Create shadow copy of local drives to work with and collect GUIDs
REM
del %SHADOWSF% 2>nul 
for %%s in (%LW%) do (
  for /f "tokens=3" %%i in ('"Wmic shadowcopy call create ClientAccessible,"%%s\""^|Findstr ShadowID') Do (
    call :log "Created volume shadow copy %%i for drive %%s"
    set VSSID=%%i
    echo %%s !VSSID:~1,-2! >>%SHADOWSF%
  )
)
 
REM
REM 6) Backup files from snapshot to backup location
REM
for %%s in (!PSTS!) do (
  set FOUND=
  for /f "tokens=*" %%i in (%SHADOWSF%) do (
    set VSS=%%i
    For /f "tokens=2 delims=:" %%j in ('"vssadmin list shadows /Shadow=!VSS:~3!"^|FindStr GLOBALROOT') Do Set VSSVOL=%%j
    if "!VSS:~0,2!"=="%%~ds" (
      call :tee "Saving %%~ns%%~xs"
      copy /y !VSSVOL!%%~ps%%~ns%%~xs %DEST%\%%~ns.xxx
      if errorlevel 0 move /y %DEST%\%%~ns.xxx %DEST%\%%~ns%%~xs >nul
      set FOUND=1
    )
  )
  if "%%~ds"=="\\" set FOUND=1
  if not !FOUND! == 1 (
    call :tee "echo Saving %%~ns%%~xs"
    copy /y %%s %DEST%\%%~ns.xxx
    if errorlevel 0 move /y %DEST%\%%~ns.xxx %DEST%\%%~ns%%~xs >nul
  )
)
 
REM
REM 7) Delete shadow copies again, no longer needed
REM
for /f "tokens=2 delims= " %%s in (%SHADOWSF%) do (
  vssadmin delete Shadows /Shadow=%%s /quiet >nul
  call :log "Removed shadow copy %%s"
)
del %SHADOWSF% 
 
call :log ".pst file Backup finished"
EXIT /B 0
 
:log
IF NOT "%LOG%"=="" ECHO !DATE! !TIME! %* >>!LOG!
EXIT /B 0
 
:tee
ECHO %*
CALL :log %*
EXIT /B 0

Protocol of a Wavecom 2C2 GSM module

By dose | December 6, 2018
Under: Uncategorized
Comments: No Comments »

As I recently wrote, I had a Wavecom FastTrak M1306B compatible GSM-Modem from China (branded as Ostent Q2303A modem) where I flashed a new firmware from Wavecom to it, as it didn’t receive any SMS, which finally broke it.
I found a good amount of documentation for the modem and mirrored it here for archival, in case the chinese sites serving the documentation go offline.

From what I have read in the documentation, there is a BOOT pin that you have to pull down to GND with a resistor in order to place the defunct modem in a Firmware upload Boot-mode.
After doing so, it really gets into download mode, but due to the fact that I have a board with an Prolific PL2303 USB->Serial converter on it and the RTS/CTS signals were not connected to the Wavecom 2C2 module, the downloader mode doesn’t work as expected.
Normally, the firmware upgrade should be done with the DwlWin application, which one can obtain from the Sierrawireless site, because they bought Wavecom.
I unfortunately was never able to flash the module with it, because the module always NACKed the initial Bootstrap command 0x28. Not sure if it has something to do with the unconnected RTS/CTS lines, because documentation states that these lines are necessary, but I finally gave up on it, it’s not worth the effort.
Nevertheless during my research, I found out a bit about the Downloader-protocol which I want to share with you.
As the DwlWin application is C++ with a lot of classes, it is a pain to reverse-engineer. Fortunately the company M-Star also mad a DwlWin-application for their chips, which seems to be loosely based on the WaveCom DwlWin, but with very verbose debug output and seemingly C-code, so I first had a look at this to find the general principle of the Recovery-procedure. Note that this is not related to the wavecom chip:

Procedure:
Download Bootstrap to chip:
1) Open port with 2400 baud.
2) GetChipID
3) Send SendAndRecvStartFrame
4) Send PacketLengthSettingFrame
5) Change to requested baudrate
6) Send DataFrame until Bootloader is transmitted
7) Send ExitFrame

Then run Bootstrapper:
1) Set Baudrate to 2400 baud
2) Send BootstrapStartFrame
3) Change to requested baudrate

Next is to send Downloader to Bootstrap, which is a seperate protocol spoken
by bootstrapper.

M-Star command frames
Here are the corresponding commands used by M-Star (I don’t explain them any further, i.e. how to calc CRC, because it’s not relevant for Wavecom chips anyway):

#define ACK 0x06
#define NACK 0x15

Frame data is organized as {Command, [Data...], CKSHi CKSLo}
So it has a 16bit frame checksum and specific commands:

PacketLengthSettingFrame = {0x01, LenHi, LenLo, 0x00, 0x00, CKSHi, CKSLo}
Max. 28 bytes
SendAndRecvStartFrame = {0x02, Baudrate, 0x00, 0x00, 0x00, CKSHi, CKSLo}
Baudrate:
1 - 2400
2 - 4800
3 - 9600
4 - 19200
5 - 38400
6 - 57600
7 - 115200
8 - 230400
9 - 460800
10 - 921600
-> ACK
DataFrame = {0x16, ....Framedata..., CKSHi, CKSLo}
-> ACK (0x06)
ExitFrame = {0x04, CRC4, CRC3, CRC2, CRC1, CKSHi, CKSLo}
-> ACK
GetChipID = {0x07, 0x04, 0x00, 0x00, 0x00, CKSHi, CKSLo}
-> ACK (0x06), 4 Bytes chip ID
BootstrapStartFrame = {0x28, 0x02, 0x53, Baudrate, CKSHi, CKSLo}
-> ACK

CKS..Frame Checksum
CRC..CRC over sent application

The Wismo 2C2 protocol

Now the WISMO 2C speak a different protocol. You can use the same baudrate table as above with the M-Star protocol.
CKS (Frame checksum) is always an XORed sum over the previous bytes of the frame, so very easy to calc.

Every data frame is organized as {Len, [Data…], CKS}
Therefore:

SendAndRecvStartFrame = {0x04, 0x53, Baudrate, 0x43, 0x01, CKS}
-> ACK
DataFrame = {Len, [Data...], CKS}
ExitFrame = {0x00, 0x00}
-> ACK
SetBaudrate = {0x02, 0x53, Baudrate, CKS}

0x53 = 'S' = Baudrate
0x50 = 'P' = Parity (0...None)
0x54 = 'T' = Stopbits (1..1 Stopbit)

Introduce downloader:
= {0x09, Ver_Maj, Ver_min, Ver_release, Ver_build, ?Baudrate?, Unixtime1, Unixtime2, Unixtime3, Unixtime4, CKS}
Ver_*.......Version octets of DWLWin Version
Unixtime*...Current time_t Unixtime timestamp as DWORD

I guess, nobody really has a use for this, but I just wanted to dump the information here in case there is interest in it and to save other ppl the effort of reversing it.

Word 2013 – “Dieses Feature scheint leider defekt zu sein”

By dose | December 6, 2018
Under: Uncategorized
Comments: No Comments »

Heute hatte ich auf einem PC das Problem, dass bei einem bestimmten Benutzer auf einer PC das Word 2013 beim Starten immer vermeldete: “Dieses Feature scheint leider defekt zu sein”
Auch eine Reparaturinstallation brachte nichts. Deaktivieren von Add-Ons führte auch nicht zum Erfolg.
winword /safe funktionierte aber, ebenso war kein Fehler zu sehen, wenn man Word als Administrator startet.

Daher habe ich mich mit dem Process Monitor von Sysinternals auf die Lauer gelegt, einen Filter gesetzt auf winword.exe und beim Ergebnis einen Filter auf “DENIED” gelegt.
Dies ergab dann, dass Word auf einen Registry-Schlüssel im WOW3264Node zugreifen wollte, welcher die .doc Dokumentenklasse als CLSID definiert. Auf diesem System hatte aus irgendeinem Grund der Benutzer “Benutzer” keine Zugriffsrechnte auf den Schlüssel.
Also Registry Editor geöffnet, “Benutzer” Zugriffsrechte auf den Schlüssel erteilt und siehe da – kein Fehler mehr beim Start von Word.