After reboot, on resumption of uncompression, inflate() is reporting Z_DATA_ERROR - zip

Thanks Mark, on resumption, now I get Z_DATA_ERROR
case STORED:
strm->msg = (char *)"invalid stored block lengths"; // got here - Anton
state->mode = BAD;
Just to see I understood your suggestions yesterday:
after inflateInit2()
// go to byte offset
ZSEEK64( , , streamCurrentPos, ZLIB_FILEFUNC_SEEK_SET)
if ( streamBits > 0 )
{
// get that byte
unz64local_getByte( , , &aByte)
// and shift down by the number of bits. This API doing it?
inflatePrime ( , streamBits, 8 - streamBits)
} else { no bits to insert }
inflateSetDictionary ()
And state of uncompression is saved like this:
typedef struct state_of_uncompression
{
ZPOS64_T streamCurrentPos; // from : unzGetCurrentFileZStreamPos64()
int streamBits; // from : stream.data_type & (~0x1C0), after clearing bits 8,7, and 6
Byte dictionary_buf[32768]; // from : inflateGetDictionary()
uInt dictLength; // from : inflateGetDictionary();
uint64_t output_wrt_offset // got this already.
} uncompression_state_info;

What? No.
inflatePrime ( , streamBits, 8 - streamBits) makes no sense. And you did nothing with the aByte you got.
It should be inflatePrime(strm, streamBits, aByte >> (8 - streamBits)).

Related

Generating a unique 8-character hex name from input binary?

in Source multiplayer games, with settings that allow saving sprays, you can automatically save images that other users post in-game just by seeing them. They save with names like this:
18ce2add.vtf
ce77eb5b.vtf
7dbd03ec.vtf
a24cb0d3.vtf
When looking through the SDK code, I found this part which I think is part of the function that creates the names for each image.
https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/game/client/c_te_playerdecal.cpp#L168
IMaterial *CreateTempMaterialForPlayerLogo( int iPlayerIndex, player_info_t *info, char *texname, int nchars )
{
// Doesn't have a logo?
if ( !info->customFiles[0] )
return NULL;
IMaterial *logo = materials->FindMaterial( VarArgs("decals/playerlogo%2.2d", iPlayerIndex), TEXTURE_GROUP_DECAL );
if ( IsErrorMaterial( logo ) )
return NULL;
char logohex[ 16 ];
Q_binarytohex( (byte *)&info->customFiles[0], sizeof( info->customFiles[0] ), logohex, sizeof( logohex ) );
// See if logo has been downloaded.
Q_snprintf( texname, nchars, "temp/%s", logohex );
char fulltexname[ 512 ];
Q_snprintf( fulltexname, sizeof( fulltexname ), "materials/temp/%s.vtf", logohex );
if ( !filesystem->FileExists( fulltexname ) )
{
char custname[ 512 ];
Q_snprintf( custname, sizeof( custname ), "download/user_custom/%c%c/%s.dat", logohex[0], logohex[1], logohex );
// it may have been downloaded but not copied under materials folder
if ( !filesystem->FileExists( custname ) )
return NULL; // not downloaded yet
// copy from download folder to materials/temp folder
// this is done since material system can access only materials/*.vtf files
if ( !engine->CopyLocalFile( custname, fulltexname) )
return NULL;
}
return logo;
}
What I can't figure out is the format the binary is recieved in (array?) exactly why the name is limited to just 8 characters, and how it decides to use the hex to create the filename. If there is any code that does something like this, I'd be happy to see it. I started learning C++ to try and solve this exact problem.

libMobileGestalt.dylib crashed when Hooking MGCopyAnswer for ARM64

When I try to hook MGCopyAnswer, I get a crash. I'm trying this on a jailbroken iPhone 5s in iOS 8.3, arm64 binaries.
#import <substrate.h>
extern "C" CFTypeRef MGCopyAnswer(CFStringRef);
MSHook(CFTypeRef, MGCopyAnswer, CFStringRef key)
{
  return _MGCopyAnswer(key);
}
%ctor
{
  NSString *appID = [[NSBundle mainBundle] bundleIdentifier];
  if ( appID && [appID isEqualToString:#"com.test.test"])   {
    MSHookFunction(MGCopyAnswer, MSHake(MGCopyAnswer));
  }
}
Makefile:
ARCHS = armv7 armv7s arm64
TARGET = iphone:latest:8.0
test2_FRAMEWORKS = UIKit
include theos/makefiles/common.mk
TWEAK_NAME = test2
test2_FILES = Tweak.xm
test2_LIBRARIES = MobileGestalt
include $(THEOS_MAKE_PATH)/tweak.mk
after-install::
  install.exec "killall -9 SpringBoard"
Crash log:
Version: 1.44 (1.4)
Code Type: ARM-64 (Native)
Parent Process: launchd [1]
Date/Time:           2016-04-25 01:09:31.810 +0800
Launch Time:         2016-04-25 01:09:31.564 +0800
OS Version:          iOS 8.3 (12F70)
Report Version:      105
Exception Type:  EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes: 0x0000000000000001, 0x000000000068fe68
Triggered by Thread:  0
Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libMobileGestalt.dylib          0x0000000195af7e84 0x195af4000 + 16004
1   libMobileGestalt.dylib          0x0000000195af82bc MGGetBoolAnswer + 32
2   AppSupport                      0x000000018b020594 __CPIsInternalDevice_block_invoke + 16
3   libdispatch.dylib               0x0000000196c99950 _dispatch_client_callout + 12
4   libdispatch.dylib               0x0000000196c9a828 dispatch_once_f + 92
5   AppSupport                      0x000000018b02057c CPIsInternalDevice + 60
6   UIKit                           0x0000000189b58750 ___UIApplicationUsesAlternateUI_block_invoke + 12
7   libdispatch.dylib               0x0000000196c99950 _dispatch_client_callout + 12
8   libdispatch.dylib               0x0000000196c9a828 dispatch_once_f + 92
9   UIKit                           0x0000000189923750 UIApplicationInitialize + 1872
10  UIKit                           0x0000000189922b1c UIApplicationMain + 320
MGCopyAnswer:
->  0x193a7fe84 <+0>:  .long  0x002d7c28                ; unknown opcode
    0x193a7fe88 <+4>:  .long  0x00000001                ; unknown opcode
    0x193a7fe8c <+8>:  stp    x20, x19, [sp, #32]
    0x193a7fe90 <+12>: stp    x29, x30, [sp, #48]
    0x193a7fe94 <+16>: add    x29, sp, #48
    0x193a7fe98 <+20>: sub    sp, sp, #48
    0x193a7fe9c <+24>: mov    x19, x1
    0x193a7fea0 <+28>: mov    x22, x0
    0x193a7fea4 <+32>: movz   w0, #0
    0x193a7fea8 <+36>: bl     0x193a7f564               ; ___lldb_unnamed_function54$$libMobileGestalt.dylib
    0x193a7feac <+40>: orr    w1, wzr, #0x1
    0x193a7feb0 <+44>: mov    x0, x22
    0x193a7feb4 <+48>: bl     0x193a7f5fc               ; ___lldb_unnamed_function56$$libMobileGestalt.dylib
    0x193a7feb8 <+52>: mov    x21, x0
    0x193a7febc <+56>: movz   w20, #0
    0x193a7fec0 <+60>: cbz    x21, 0x193a7fefc          ; <+120>
    0x193a7fec4 <+64>: ldr    w20, [x21, #148]
    0x193a7fec8 <+68>: mov    x0, x21
orig_MGCopyAnswer
    0x104234000: movz   x1, #0
    0x104234004: stp    x24, x23, [sp, #-64]!
    0x104234008: stp    x22, x21, [sp, #16]
    0x10423400c: ldr    x16, #8
    0x104234010: br     x16
    0x104234014: .long  0x93a7fe8c                
    0x104234018: .long  0x00000001                ; unknown opcode
What am I doing wrong?
You cannot hook MGCopyAnswer directly because it is too short.
When CydiaSubstrate hooks a C function, it sorts of overwrites an assembly version of goto your_function; at the beginning of the original function. This "goto" in ARM64 is 16 bytes in size, which means if the original function is too short (< 16 bytes), CydiaSubstrate can spill over and corrupt the neighboring functions.
This is exactly why the problem of MGCopyAnswer. The implementation of MGCopyAnswer is basically (on 9.3.2 arm64):
01 00 80 d2 movz x1, #0
01 00 00 14 b MGCopyAnswer_internal
which is just 8 bytes (< 16 bytes) in size. So CydiaSubstrate will corrupt the 8 bytes after the end of MGCopyAnswer.
Unfortunately, MGCopyAnswer_internal is right after MGCopyAnswer, and even worse this function and is called by MGGetBoolAnswer as well. Since MGCopyAnswer_internal is corrupt, you get an EXC_BAD_INSTRUCTION crash inside libMobileGestalt.
A good news for MGCopyAnswer is that, you could just hook MGCopyAnswer_internal! This has an additional benefit that many related functions like MGGetBoolAnswer, MGCopyAnswerWithError, MGCopyMultipleAnswers etc. can respond to your change as well. The bad thing is that MGCopyAnswer_internal is completely internal, and there is no symbols pointing to it. We could rely on the fact that MGCopyAnswer_internal is exactly 8 bytes after MGCopyAnswer on ARM64, and develop this ugly hack:
static CFPropertyListRef (*orig_MGCopyAnswer_internal)(CFStringRef prop, uint32_t* outTypeCode);
CFPropertyListRef new_MGCopyAnswer_internal(CFStringRef prop, uint32_t* outTypeCode) {
return orig_MGCopyAnswer_internal(prop, outTypeCode);
}
extern "C" MGCopyAnswer(CFStringRef prop);
static CFPropertyListRef (*orig_MGCopyAnswer)(CFStringRef prop);
CFPropertyListRef new_MGCopyAnswer(CFStringRef prop) {
return orig_MGCopyAnswer(prop);
}
%ctor {
uint8_t MGCopyAnswer_arm64_impl[8] = {0x01, 0x00, 0x80, 0xd2, 0x01, 0x00, 0x00, 0x14};
const uint8_t* MGCopyAnswer_ptr = (const uint8_t*) MGCopyAnswer;
if (memcmp(MGCopyAnswer_ptr, MGCopyAnswer_arm64_impl, 8) == 0) {
MSHookFunction(MGCopyAnswer_ptr + 8, (void*)new_MGCopyAnswer_internal, (void**)&orig_MGCopyAnswer_internal);
} else {
MSHookFunction(MGCopyAnswer_ptr, (void*)new_MGCopyAnswer, (void**)&orig_MGCopyAnswer);
}
}
(This only checks for arm64 on 9.3.2. Other platforms may crash in different ways, and have different assembly code, so you may need to add additional conditions into enter the hook-MGCopyAnswer_internal branch. YMMV!)
Try this code:
#import <substrate.h>
static CFTypeRef (*orig_MGCopyAnswer)(CFStringRef str);
CFTypeRef new_MGCopyAnswer(CFStringRef str)
{
return orig_MGCopyAnswer(str);
}
%ctor
{
NSString *appID = [[NSBundle mainBundle] bundleIdentifier];
if ( appID && [appID isEqualToString:#"com.test.test"]) {
void * MGCopyAnswerFn = MSFindSymbol(NULL, "_MGCopyAnswer");
MSHookFunction(MGCopyAnswerFn, (void *) new_MGCopyAnswer, (void **)& orig_MGCopyAnswer);
}
}

how to append text to mail body in lotus notes (C API)

I have been trying to append some text to outgoing mail from lotus notes client. For this I have registered EM_MAILSENDNOTE with EM_REG_BEFORE event. On this event, I am appending some rich text to mail body.
But that text appears only in the sent folder mail, not at the receiving end. What I am missing?
code below referred from this document.
void appendRichTextToBody(NOTEHANDLE note_handle, const char *szString1) {
#define PARA_STYLE_ID 1
char itemname[] = "Body";
WORD wBuffLen; /* required buffer length */
BYTE *rt_field; /* allocated rich-text field */
BYTE *buff_ptr; /* position in allocated memory */
CDPABDEFINITION pabdef; /* rich-text paragraph style */
CDPARAGRAPH para; /* rich-text paragraph header */
CDPABREFERENCE ref; /* rich-text style reference */
CDTEXT cdtext; /* rich-text text header */
WORD wString1Len = strlen( szString1 ); /* Length of actual string */
WORD wString1BufLen = wString1Len + (wString1Len%2);
FONTIDFIELDS *pFontID; /* font definitions in text header */
DWORD rt_size; /* size of rich-text field */
STATUS error = NOERROR; /* return code from API calls */
wBuffLen = ODSLength( _CDPABDEFINITION ) +
ODSLength( _CDPARAGRAPH ) + ODSLength( _CDPABREFERENCE) +
ODSLength(_CDTEXT) + wString1BufLen;
rt_field = (BYTE *) malloc ( wBuffLen );
if( rt_field == (BYTE *)NULL ) {
return;
}
//* Keep a pointer to our current position in the buffer. */
buff_ptr = rt_field;
/* Initialize a CDPABDEFINITION structure.We use all defaults, except for centered
justification.*/
memset(&pabdef, 0, sizeof(CDPABDEFINITION));
pabdef.Header.Signature = SIG_CD_PABDEFINITION;
pabdef.Header.Length = ODSLength( _CDPABDEFINITION );
pabdef.PABID = PARA_STYLE_ID;
pabdef.JustifyMode = JUSTIFY_CENTER;
pabdef.LineSpacing = DEFAULT_LINE_SPACING;
pabdef.ParagraphSpacingBefore = DEFAULT_ABOVE_PAR_SPACING;
pabdef.ParagraphSpacingAfter = DEFAULT_BELOW_PAR_SPACING;
pabdef.LeftMargin = DEFAULT_LEFT_MARGIN;
pabdef.RightMargin = DEFAULT_RIGHT_MARGIN;
pabdef.FirstLineLeftMargin = DEFAULT_FIRST_LEFT_MARGIN;
pabdef.Tabs = DEFAULT_TABS;
pabdef.Tab[0] = DEFAULT_TAB_INTERVAL;
pabdef.Flags = 0;
pabdef.TabTypes = TAB_DEFAULT;
pabdef.Flags2 = 0;
/* Call ODSWriteMemory to convert the CDPABDEFINITION structure to
Domino and Notes canonical format and write the converted structure into
the buffer at location buff_ptr. This advances buff_ptr to the
next byte in the buffer after the canonical format strucure.
*/
ODSWriteMemory( &buff_ptr, _CDPABDEFINITION, &pabdef, 1 );
/* Put a paragraph header in the field. */
para.Header.Signature = SIG_CD_PARAGRAPH;
para.Header.Length = (BYTE) ODSLength( _CDPARAGRAPH );
ODSWriteMemory( &buff_ptr, _CDPARAGRAPH, &para, 1 );
/* Add the CDTEXT record to the field. A CDTEXT record consists
of a CDTEXT structure followed by a run of text. Initialize the
CDTEXT structure by filling in the signature and the length.
The CDTEXT structure also contains the font information that
controls how Domino and Notes displays this first run of text.
*/
cdtext.Header.Signature = SIG_CD_TEXT;
cdtext.Header.Length = ODSLength( _CDTEXT ) + wString1Len ;
pFontID = (FONTIDFIELDS *) &(cdtext.FontID);
pFontID->Face = FONT_FACE_SWISS;
pFontID->Attrib = ISBOLD;
pFontID->Color = NOTES_COLOR_BLUE;
pFontID->PointSize = 24;
ODSWriteMemory( &buff_ptr, _CDTEXT, &cdtext, 1 );
/* Write the actual characters of this first text run to the buffer.
Since the run of text may contian embedded null characters, use
memcpy, not strcpy. No need to terminate the run of text with a
null because the Header.Length member of the CDTEXT structure
specifies the length explicitly. Only copy the null if the
number of characters is odd.
*/
memcpy( (char *)buff_ptr, szString1, wString1BufLen );
/* Advance the pointer to the next even-byte boundary */
buff_ptr += wString1BufLen;
rt_size = (DWORD)(buff_ptr - rt_field);
if (error = NSFItemAppend( note_handle, 0, itemname, (WORD) strlen(itemname), TYPE_COMPOSITE, rt_field, rt_size ) ){
Log("%s: NSFItemAppend failed\n", __FUNCTION__);
return;
}
free( rt_field );
}
EDIT1:
Code to register event handler:
error = EMRegister(EM_MAILSENDNOTE, EM_REG_BEFORE,(EMHANDLER)MailSendNoteHandler, gRecursionID, &hMailSendNote);
error = EMRegister(EM_NSFNOTEUPDATEMAILBOX, EM_REG_BEFORE,(EMHANDLER)UpdateMailboxHandler, gRecursionID, &hNSFUpdateMailbox);
Event handler functions:
STATUS MailSendNoteHandler(EMRECORD FAR * pExRecord) {
VARARG_PTR ap = pExRecord->Ap;
DHANDLE hNote = VARARG_GET (ap, DHANDLE);
appendRichTextToBody(hNote, " Test Rich Text EM_MAILSENDNOTE BEFORE ");
return (EM_ERR_CONTINUE);
}
STATUS UpdateMailboxHandler(EMRECORD FAR * pExRecord) {
VARARG_PTR ap = pExRecord->Ap;
DHANDLE hNote = VARARG_GET (ap, DHANDLE);
appendRichTextToBody(hNote, " Test Rich Text EM_NSFNOTEUPDATEMAILBOX BEFORE ");
return (EM_ERR_CONTINUE);
}
I don't see any appended text at recipient side.
But the mail in Sent folders has both appended texts.
I presume that this is a client-side EM. Most mail processing code that I'm familiar with operates on the server-side instead, by hooking EM_NSFNOTEUPDATE in the mail.box file on the server. The trick there, though, is that you must prevent the router from sending the message before you are finished processing it, so the very first thing you do is you change the status of the message to "On Hold" so the router won't even try to mail it. Then you can do your work on it, and finally release it. (Usually on the server side, this involves signalling a separate server task to do the work, as you don't want to keep a main server thread from returning from NSFNoteUpdate while the work is done.)
Even with EM_BEFORE processing, you may need to do something similar on the client side in order to accomplish this. You may at least want to add EM_BEFORE and EM_AFTER event handlers for EM_NSFNOTEUPDATE to monitor the mail.box file to determine whether those events are firing before or after the EM_MAILSENDNOTE event fires.
I know of Domino C API EMs that add signatures via server not client to outbound SMTP emails, so this must be possible.
EM_MAILSENDNOTE can only be used on a client.
BTW If this does not make sense here, its because of the restrictions on this site, I cannot add a comment with more detail, I cannot add a link, I cannot add code !!!

Strange noise and abnormalities when writing audio data from libspotify into a file

Currently we're implementing Libspotify in a win 7 64 bit system. Everything seems to work fine except the playback. We get data from the callback , but even using audicity on the saved audio, is filled with abnormalities. So to research further we took the win32 sample (spshell ) and modified it to save the music data to file. Same problem, definitely music with these ticks in it. I'm sure there's something simple I'm missing here, but I'm at a loss as to what could be the problem. Any help would be great since as it stands our project is at a stand still until we can resolve this.
The audio saved can be viewed here
http://uploader.crestron.com/download.php?file=8001d80992480280dba365752aeaca81
Below are the code changes I made to save the file ( for testing only )
static FILE *pFile;
int numBytesToWrite=0;
CRITICAL_SECTION m_cs;
int SP_CALLCONV music_delivery(sp_session *s, const sp_audioformat *fmt, const void *frames, int num_frames)
{
if ( num_frames == 0 )
return;
EnterCriticalSection(&m_cs);
numBytesToWrite = ( num_frames ) * fmt->channels * sizeof(short);
if (numBytesToWrite > 0 )
fwrite(frames, sizeof(short), numBytesToWrite, pFile);
LeaveCriticalSection(&m_cs);
return num_frames;
}
static void playtrack_test(void)
{
sp_error err;
InitializeCriticalSection(&m_cs);
pFile = fopen ("C:\\zzzspotify.pcm","wb");
test_start(&playtrack);
if((err = sp_session_player_load(g_session, stream_track)) != SP_ERROR_OK) {
test_report(&playtrack, "Unable to load track: %s", sp_error_message(err));
return;
}
info_report("Streaming '%s' by '%s' this will take a while", sp_track_name(stream_track),
sp_artist_name(sp_track_artist(stream_track, 0)));
sp_session_player_play(g_session, 1);
}
void SP_CALLCONV play_token_lost(sp_session *s)
{
fclose(pFile);
DeleteCriticalSection(&m_cs);
stream_track_end = 2;
notify_main_thread(g_session);
info_report("Playtoken lost");
}
static int check_streaming_done(void)
{
if(stream_track_end == 2)
test_report(&playtrack, "Playtoken lost");
else if(stream_track_end == 1)
test_ok(&playtrack);
else
return 0;
fclose(pFile);
stream_track_end = 0;
return 1;
}
It looks like this is the problem:
fwrite(frames, sizeof(short), numBytesToWrite, pFile);
The fwrite documentation states that the second argument is the "size in bytes of each element to be written", and the third is this "number of elements, each one with a size of size bytes".
The way you're calling frwritewill tell it to write numBytesToWrite * sizeof(short) bytes, which will run right off the end of the given buffer. I'm actually surprised it doesn't crash!
I'd suggest changing your fwrite call to something like:
fwrite(frames, sizeof(char), numBytesToWrite, pFile);
or:
int numSamplesToWrite = num_frames * fmt->channels;
fwrite(frames, sizeof(short), numSamplesToWrite, pFile);
Edit:
After looking at your audio in detail, I'm more convinced that this is the case. The song seems to be playing at half speed (i.e., 2x as much data is being written) and the artefacts seem to look like buffer overrun into random memory.

ZeroMemory on PROCESSENTRY32 local variable?

I needed to enumerate running processes and wondered for a while why my code wasn't working:
PROCESSENTRY32 ProcEntry;
ZeroMemory (&ProcEntry, sizeof (PROCESSENTRY32)); //problem
ProcEntry.dwFlags = sizeof(PROCESSENTRY32);
HANDLE Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (Snapshot == INVALID_HANDLE_VALUE)
return false;
if (Process32First(Snapshot, &ProcEntry))
....
Problem was that Process32First always returned FALSE because of ERROR_BAD_LENGTH error.
Once I removed ZeroMemory line, everything started working fine. So the question is, why ZeroMemory caused it? It should just fill memory at the address of X for Z bytes. I use it a lot for winapi pointer-like structures, this time I didnt realise its a local variable but that doesn't explain the problem or does it?
Thanks,
Kra
EDIT: plus I found out code works fine only in Debug version, once I compile it as Release version, its bugged again :/
You should set dwSize, not dwFlags.
ProcEntry.dwFlags = sizeof(PROCESSENTRY32);
should be
ProcEntry.dwSize = sizeof(PROCESSENTRY32);
You cannot zero out the entire PROCESSENTRY32 structure as it is self-describing - you have to set dwSize. From the sample here:
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hProcessSnap == INVALID_HANDLE_VALUE )
{
printError( TEXT("CreateToolhelp32Snapshot (of processes)") );
return( FALSE );
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof( PROCESSENTRY32 );
// Retrieve information about the first process,
// and exit if unsuccessful
if( !Process32First( hProcessSnap, &pe32 ) )
{
printError( TEXT("Process32First") ); // show cause of failure
CloseHandle( hProcessSnap ); // clean the snapshot object
return( FALSE );
}

Resources