Is it possible to intercept System Calls via Theos Tweak? Jailed Version - ios

Can i intercept generic system calls like sqlite3_prepare or sqlite3_open also CC_MD5 of libcommonCrypto with a Theos (jailed versione) Tweak?
I would intercept all these calls and print on the console or into a log file.
I've read something about MSHookFunction, but i'm not sure about it.
EDIT: i add some code which i've wrote in these days. This is my Tweak.xm, where i would intercept CC_MD5 call, and after a simple message log, i would return to the normal flow. The tweak is injected, but i can not see any message.
#include <substrate.h>
#include <CommonCrypto/CommonDigest.h>
static unsigned char * (*original_CC_MD5)(const void *data, CC_LONG len, unsigned char *md);
static unsigned char * replaced_CC_MD5(const void *data, CC_LONG len, unsigned char *md) {
NSLog(#"Calling MD5");
return original_CC_MD5(data, len, md);
}
MSInitialize {
MSHookFunction(CC_MD5, replaced_CC_MD5, &original_CC_MD5);
}

I've found the problem. The Theos version that i'm using is for jailed device. With this version MSHookFunction is substituted by fishhook.
Using fishhook it's all ok: obviously the code changes
#include <substrate.h>
#include <CommonCrypto/CommonDigest.h>
#import <fishhook.h>
static unsigned char * (*original_CC_MD5)(const void *data, CC_LONG len, unsigned char *md);
static unsigned char * replaced_CC_MD5(const void *data, CC_LONG len, unsigned char *md) {
NSLog(#"Calling MD5");
return original_CC_MD5(data, len, md);
}
%ctor {
rebind_symbols((struct rebinding[1]){{"CC_MD5", replaced_CC_MD5, (void *)&original_CC_MD5}},1);
}

Related

pthread error code 3025 (ENOENT) on the as400/IBM i?

When I have the following C source code, which is running on an IBM i Midrange, then I get a non-zero result from pthread_create, specifically 3025, which is ENOENT (No such path or directory), which doesn't make any sense to me. Anyone have any thoughts on what the error actually means in this context.
#define _MULTI_THREADED
#define _XOPEN_SOURCE 520
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
void* workerThread(void* parm) {
// Do some work here
pthread_exit(NULL);
}
int main(int argc, char* argv[]) {
pthread_t t;
int rc;
rc = pthread_create(&t, NULL, workerThread, NULL);
if (rc != 0) {
char *msg = strerror(errno);
perror("pthread_create failed");
}
// Other code here
return 0;
}
pthread_create doesn't set errno. You should be checking strerror of rc.
http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_create.html
char *msg = strerror(rc);

memory allocation of `getaddrinfo()`

I have a simple program which calls getaddrinfo() and freeaddrinfo().
I run valgrind on it, and it shows that there is no memory leak.
in use at exit: 0 bytes in 0 blocks
total heap usage: 108 allocs, 109 frees
However, I wrote a memory debugger named memleax which attaches the target process and traps at malloc() and free() to detect memory leak. I use memleax to detect the getaddrinfo() program, and it catches free() only 43 times.
Then I hook the malloc() and free() by malloc-hooks,
and it also shows free() only 43 times.
So my question is that, what is the difference between valgrind and hooking-malloc?
Original code:
#include <sys/types.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
int main()
{
struct addrinfo *aihead;
sleep(4);
printf(" --- getaddrinfo ---\n");
int error = getaddrinfo("dig.chouti.com", "http", NULL, &aihead);
if(error) {
printf("error: %s\n", gai_strerror(error));
return error;
}
sleep(4);
printf("\n\n\n --- freeaddrinfo ---\n");
freeaddrinfo(aihead);
sleep(4);
return 0;
}
Code with malloc-hook
#include <sys/types.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
/* Prototypes for __malloc_hook, __free_hook */
#include <malloc.h>
/* Prototypes for our hooks. */
static void my_init_hook (void);
static void *my_malloc_hook (size_t, const void *);
static void my_free_hook (void*, const void *);
static void *(*old_malloc_hook) (size_t, const void *);
static void (*old_free_hook) (void*, const void *);
static void
my_init (void)
{
old_malloc_hook = __malloc_hook;
old_free_hook = __free_hook;
__malloc_hook = my_malloc_hook;
__free_hook = my_free_hook;
}
static void *
my_malloc_hook (size_t size, const void *caller)
{
void *result;
/* Restore all old hooks */
__malloc_hook = old_malloc_hook;
__free_hook = old_free_hook;
/* Call recursively */
result = malloc (size);
/* Save underlying hooks */
old_malloc_hook = __malloc_hook;
old_free_hook = __free_hook;
/* printf might call malloc, so protect it too. */
printf ("malloc (%u) returns %p\n", (unsigned int) size, result);
/* Restore our own hooks */
__malloc_hook = my_malloc_hook;
__free_hook = my_free_hook;
return result;
}
static void
my_free_hook (void *ptr, const void *caller)
{
/* Restore all old hooks */
__malloc_hook = old_malloc_hook;
__free_hook = old_free_hook;
/* Call recursively */
free (ptr);
/* Save underlying hooks */
old_malloc_hook = __malloc_hook;
old_free_hook = __free_hook;
/* printf might call free, so protect it too. */
printf ("freed pointer %p\n", ptr);
/* Restore our own hooks */
__malloc_hook = my_malloc_hook;
__free_hook = my_free_hook;
}
int main()
{
my_init();
struct addrinfo *aihead;
printf(" --- getaddrinfo ---\n");
int error = getaddrinfo("dig.chouti.com", "http", NULL, &aihead);
if(error) {
printf("error: %s\n", gai_strerror(error));
return error;
}
sleep(4);
printf("\n\n\n --- freeaddrinfo ---\n");
freeaddrinfo(aihead);
sleep(4);
return 0;
}
I find this in valgrind's output:
--13197-- Discarding syms at 0x55f9240-0x5600454 in /usr/lib64/libnss_files-2.17.so due to mu
--13197-- Discarding syms at 0x580b100-0x580e590 in /usr/lib64/libnss_dns-2.17.so due to munm
--13197-- Discarding syms at 0x5a13a40-0x5a22854 in /usr/lib64/libresolv-2.17.so due to munma
==13197== Invalid free() / delete / delete[] / realloc()
==13197== at 0x4C2AD17: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==13197== by 0x4F9963B: __libc_freeres (in /usr/lib64/libc-2.17.so)
==13197== by 0x4A246B4: _vgnU_freeres (in /usr/lib64/valgrind/vgpreload_core-amd64-linux.s
==13197== by 0x4E6DE2A: __run_exit_handlers (in /usr/lib64/libc-2.17.so)
==13197== by 0x4E6DEB4: exit (in /usr/lib64/libc-2.17.so)
==13197== by 0x4E56B1B: (below main) (in /usr/lib64/libc-2.17.so)
==13197== Address 0x51f03d0 is 0 bytes inside data symbol "noai6ai_cached"
It seems that libc-nss frees some memory at __run_exit_handlers() after exit().
So maybe valgrid keeps tracing memory after target process's exit(). While malloc-hook stops working after exit().

Arduino with WiFi Shield make weird post request

I am working on small weather station based on Arduino Uno. In fact I am already create prototype which measure humidity, temperature, pressure and level of CO2 and send data trough POST request to server. For the whole week it works perfectly sending data to server on hourly basis. But yesterday I find out that no new data coming. My first thought was that something wrong with WiFi, I restart router, check connectivity, everything work perfect. I think if something wrong with Arduino and restart it, it works. So I check what I get after connection and answer was:
HTTP/1.1 405 METHOD NOT ALLOWED
Date: Fri, 02 Sep 2016 13:27:02 GMT
Server: Apache/2.4.10 (Debian)
Allow: GET, OPTIONS, POST, HEAD
Content-Length: 178
Connection: close
Content-Type: text/html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>405 Method Not Allowed</title>
<h1>Method Not Allowed</h1>
<p>The method is not allowed for the requested URL.</p>
*CLOS*
Ok then I send POST request to server manually (trough Postman) and it is works. So I go to server and start read logs, there is no errors but in access.log I find out something interesting:
Working post request coming from Postman look like:
15.15.119.103 - - [02/Sep/2016:13:54:03 +0300] "POST /api/meteo HTTP/1.1" 200 319 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36"
But when it comes from Arduino it look in strange way
15.15.119.103 - - [02/Sep/2016:13:53:54 +0300] "*HELLO*POST /api/meteo HTTP/1.1" 405 380 "-" "-"
So as you can see it comes to server not like POST but LIKE "HELLOPOST" and it is ruined everything. The problem is that I change nothing in my code and it is working somehow during the week. You can see peace of my Arduino code bellow:
#include <WiFly.h>
#include "HTTPClient.h"
#define SSID "bbbbbbb"
#define KEY "ccccccc"
#define AUTH WIFLY_AUTH_WPA2_PSK
#define HTTP_POST_URL "15.15.25.67/api/meteo"
SoftwareSerial uart(2, 3);
WiFly wifly(uart);
HTTPClient http;
String PostData;
char PostBuf[90];
uart.begin(9600);
// check if WiFly is associated with AP(SSID)
if (!wifly.isAssociated(SSID)) {
while (!wifly.join(SSID, KEY, AUTH)) {
Serial.println("Failed to join " SSID);
Serial.println("Wait 0.1 second and try again...");
delay(100);
}
wifly.save(); // save configuration,
}
PostData.toCharArray(PostBuf, 90);
while (http.post(HTTP_POST_URL, PostBuf, 10000) < 0) {
}
while (wifly.receive((uint8_t *)&get, 1, 1000) == 1) {
Serial.print(get);
}
uart.end();
So it connect to WiFI and send request, but type of request is quite strange. I try to find any key which can help with no results maybe somebody can give me advise?
In case if needed I put here HTTPClient.h:
#ifndef __HTTP_CLIENT_H__
#define __HTTP_CLIENT_H__
#define HTTP_CLIENT_DEFAULT_TIMEOUT 30000 // 3s
#define HTTP_MAX_HOST_LEN 20
#define HTTP_MAX_PATH_LEN 64
#define HTTP_MAX_BUF_LEN 100
#define HTTP_DEFAULT_PORT 80
#include <Arduino.h>
#include <WiFly.h>
class HTTPClient {
public:
HTTPClient();
int get(const char *url, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT);
int get(const char *url, const char *header, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT);
int post(const char *url, const char *data, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT);
int post(const char *url, const char *headers, const char *data, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT);
private:
int parseURL(const char *url, char *host, int max_host_len, uint16_t *port, char *path, int max_path_len);
int connect(const char *url, const char *method, const char *data, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT);
int connect(const char *url, const char *method, const char *header, const char *data, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT);
WiFly* wifly;
};
#endif // __HTTP_CLIENT_H__
As for HTTPClient.cpp it looks like this:
#include <string.h>
#include "HTTPClient.h"
#include "Debug.h"
HTTPClient::HTTPClient()
{
wifly = WiFly::getInstance();
}
int HTTPClient::get(const char *url, int timeout)
{
return connect(url, "GET", NULL, NULL, timeout);
}
int HTTPClient::get(const char *url, const char *headers, int timeout)
{
return connect(url, "GET", headers, NULL, timeout);
}
int HTTPClient::post(const char *url, const char *data, int timeout)
{
return connect(url, "POST", NULL, data, timeout);
}
int HTTPClient::post(const char *url, const char *headers, const char *data, int timeout)
{
return connect(url, "POST", headers, data, timeout);
}
int HTTPClient::connect(const char *url, const char *method, const char *data, int timeout)
{
return connect(url, method, NULL, data, timeout);
}
int HTTPClient::connect(const char *url, const char *method, const char *headers, const char *data, int timeout)
{
char host[HTTP_MAX_HOST_LEN];
uint16_t port;
char path[HTTP_MAX_PATH_LEN];
if (parseURL(url, host, sizeof(host), &port, path, sizeof(path)) != 0) {
DBG("Failed to parse URL.\r\n");
return -1;
}
if (!wifly->connect(host, port, timeout)) {
DBG("Failed to connect.\r\n");
return -2;
}
// Send request
char buf[HTTP_MAX_BUF_LEN];
snprintf(buf, sizeof(buf), "%s %s HTTP/1.1\r\n", method, path);
wifly->send(buf);
// Send all headers
snprintf(buf, sizeof(buf), "Host: %s\r\nConnection: close\r\n", host);
wifly->send(buf);
if (data != NULL) {
snprintf(buf, sizeof(buf), "Content-Length: %d\r\nContent-Type: text/plain\r\n", strlen(data));
wifly->send(buf);
}
if (headers != NULL) {
wifly->send(headers);
}
// Close headers
wifly->send("\r\n");
// Send body
if (data != NULL) {
wifly->send(data);
}
return 0;
}
int HTTPClient::parseURL(const char *url, char *host, int max_host_len, uint16_t *port, char *path, int max_path_len)
{
char *scheme_ptr = (char *)url;
char *host_ptr = (char *)strstr(url, "://");
if (host_ptr != NULL) {
if (strncmp(scheme_ptr, "http://", 7)) {
DBG("Bad scheme\r\n");
return -1;
}
host_ptr += 3;
} else {
host_ptr = (char *)url;
}
int host_len = 0;
char *port_ptr = strchr(host_ptr, ':');
if (port_ptr != NULL) {
host_len = port_ptr - host_ptr;
port_ptr++;
if (sscanf(port_ptr, "%hu", port) != 1) {
DBG("Could not find port.\r\n");
return -3;
}
} else {
*port = HTTP_DEFAULT_PORT;
}
char *path_ptr = strchr(host_ptr, '/');
if (host_len == 0) {
host_len = path_ptr - host_ptr;
}
if (max_host_len < (host_len + 1)) {
DBG("Host buffer is too small.\r\n");
return -4;
}
memcpy(host, host_ptr, host_len);
host[host_len] = '\0';
int path_len;
char *fragment_ptr = strchr(host_ptr, '#');
if (fragment_ptr != NULL) {
path_len = fragment_ptr - path_ptr;
} else {
path_len = strlen(path_ptr);
}
if (max_path_len < (path_len + 1)) {
DBG("Path buffer is too small.\r\n");
return -5;
}
memcpy(path, path_ptr, path_len);
path[path_len] = '\0';
return 0;
}
I find out a root of problem, by default WiFiShield v.1.0 say "HELLO" when TCP connection opened. In fact it written deep into the manual.
My connection was not so fast, so it is manage to say "HELLO" before connectivity, but I upgrade router firmware and it start working faster, that is why "HELLO" connected to next request which was POST in this case. Solution is simple just add:
wifly.sendCommand("set comm remote 0\r");
and this command disable welcome message on WiFiShield. Hope it helps somebody.

Can I poll for file to run another code?

Client side:
#define BUFFSIZE 4096
main(argc, argv)
int argc;
char *argv[];
{
int fd,i,n;
char buff[BUFFSIZE];
extern char *pname;
pname = argv[0];
argv++; argc--;
fd=0;
i=0;
do{
if(arg>0 && (fd=my_open(argv[i],0)) <0) {
err_ret("cant open %s", argv[i]);
continue;
}
while((n=read(fd,buff,BUFFSIZE))>0)
if (write(1,buff,n) !=n)
err_sys("write error:);
if(n<0)
err_sys("read error");
} while(++i<argc);
exit(0);
}
Server side:
main(argc, argv)
int argc;
char *intv[];
{
int fd;
extern int errno;
extern char *pname;
pname= argv[0];
if(argc !=4)
err_quit("open file <sockfd#> <filename><mode>");
if((fd=open(argv[2],atoi(argv[3]))) < 0)
exit((errno>0) ? errno:255);
exit(sendfile(atoi(argv[1]),fd));
}
If I send a config file from client to server like this, then can I run a polling code on server which runs a python code on receiving config file.

DP5 errors in IOHIDEventQueue.c

I was working on XCode5-DP4 and I switched to DP5.
Now I have this nasty errors on my logs:
AssertMacros: queueEntry, file: /SourceCache/IOKitUser/IOKitUser-920.1.11/hid.subproj/IOHIDEventQueue.c, line: 512
Any ideas? I don't even know where to start searching.
This is a bug in Xcode 5 DP5. Just ignore it, it will go away in the next BETA build eventually.
change your main.m file with this
#import <UIKit/UIKit.h>
#import "QDAppDelegate.h"
typedef int (*PYStdWriter)(void *, const char *, int);
static PYStdWriter _oldStdWrite;
int __pyStderrWrite(void *inFD, const char *buffer, int size)
{
if ( strncmp(buffer, "AssertMacros:", 13) == 0 )
{
return 0;
}
return _oldStdWrite(inFD, buffer, size);
}
int main(int argc, char * argv[])
{
_oldStdWrite = stderr->_write;
stderr->_write = __pyStderrWrite;
#autoreleasepool
{
return UIApplicationMain(argc, argv, nil, NSStringFromClass([QDAppDelegate class]));
}
}

Resources