I have an application that needs to get the list of installed (other, maybe third party) applications on the device. How can it be done? Or can it be done at all?
You could scan all your apps through apple private framework "MobileInstallationInstall".
The method is like below:
NSDictionary *options = [NSDictionary dictionaryWithKeyAndValues:#"ApplicationType",#"Any",nil]
NSDictionary *apps = MobileInstallationLookup(options);
it can only be used in JB devices.
-(NSArray *) installedApps
{
BOOL isDir enter code here= NO;
NSDictionary *cacheDienter code herect;
NSDictionary *user;
static NSString *const cacheFileName = #"com.apple.mobile.installation.plist";
NSString *relativeCachePath = [[#"Library" stringByAppendingPathComponent: #"Caches"] stringByAppendingPathComponent: cacheFileName];
NSString *path = [[NSHomeDirectory() stringByAppendingPathComponent: #"../.."] stringByAppendingPathComponent: relativeCachePath];
if ([[NSFileManager defaultManager] fileExistsAtPath: path isDirectory: &isDir] && !isDir) // Ensure that file exists
{
cacheDict = [NSDictionary dictionaryWithContentsOfFile: path];
user = [cacheDict objectForKey: #"System"]; // Then all the user (App Store /var/mobile/Applications) apps
}
//NSLog(#"Installed Applications = %#",[user allKeys]);
//return [user allKeys];
return nil;
}
this will give you the array of name of installed app using private API
there is no public API from apple to fetch such list from iOS device (iPod Touch/iPhone/iPad)
I doubt if something is available(if some iphone is jailbreaked and user can access file system, then it will be possible, but i am not aware of this.),
but you can use following link and with the help of this you can check what all app are present and you can customize with some of your needs.
This WONT give List of installed apps but You can get List of applications running in background and their concerned processes by this code.
call from viewDidLoad -
[self printProcessInfo];
.
-(NSMutableString*) printProcessInfo {
int mib[5];
struct kinfo_proc *procs = NULL, *newprocs;
int i, st, nprocs;
size_t miblen, size;
/* Set up sysctl MIB */
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_ALL;
mib[3] = 0;
miblen = 4;
/* Get initial sizing */
st = sysctl(mib, miblen, NULL, &size, NULL, 0);
/* Repeat until we get them all ... */
do {
/* Room to grow */
size += size / 10;
newprocs = realloc(procs, size);
if (!newprocs) {
if (procs) {
free(procs);
}
perror("Error: realloc failed.");
return (0);
}
procs = newprocs;
st = sysctl(mib, miblen, procs, &size, NULL, 0);
} while (st == -1 && errno == ENOMEM);
if (st != 0) {
perror("Error: sysctl(KERN_PROC) failed.");
return (0);
}
/* Do we match the kernel? */
assert(size % sizeof(struct kinfo_proc) == 0);
nprocs = size / sizeof(struct kinfo_proc);
if (!nprocs) {
perror("Error: printProcessInfo.");
return(0);
}
printf(" PID\tName\n");
printf("-----\t--------------\n");
self.lists = [[NSMutableString alloc] init];
NSMutableString *localStr = [[NSMutableString alloc] init];
for (i = nprocs-1; i >=0; i--) {
// printf("%5d\t%s\n",(int)procs[i].kp_proc.p_pid, procs[i].kp_proc.p_comm);
localStr = [NSString stringWithFormat:#"%#,\nPID:-%5d,\tPROCESS_NAME:-%s\n",localStr,(int)procs[i].kp_proc.p_pid, procs[i].kp_proc.p_comm ];
NSString *pathStr = [self print_argv_of_pid:(int)procs[i].kp_proc.p_pid];
//NSString *pathStr = print_argv_of_pid:(((int)procs[i].kp_proc.p_pid));
localStr = [NSString stringWithFormat:#"%#,\n%#\n",localStr,pathStr ];
// [self getAttributesOfProcess];
//printf("%s",path);
}
NSLog(#"%#",lists);
free(procs);
return localStr;
//return (0);
}
-(NSString*) print_argv_of_pid:(int) pid {
char path[1000];
printf("%d\n", pid);
int mib[3], argmax, nargs, c = 0;
size_t size;
char *procargs, *sp, *np, *cp;
extern int eflg;
int show_args = 1;
mib[0] = CTL_KERN;
mib[1] = KERN_ARGMAX;
size = sizeof(argmax);
if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1) {
return #"";
//goto ERROR_A;
}
/* Allocate space for the arguments. */
procargs = (char *)malloc(argmax);
if (procargs == NULL) {
return #"";
//goto ERROR_A;
}
/*
* Make a sysctl() call to get the raw argument space of the process.
* The layout is documented in start.s, which is part of the Csu
* project. In summary, it looks like:
*
* /---------------\ 0x00000000
* : :
* : :
* |---------------|
* | argc |
* |---------------|
* | arg[0] |
* |---------------|
* : :
* : :
* |---------------|
* | arg[argc - 1] |
* |---------------|
* | 0 |
* |---------------|
* | env[0] |
* |---------------|
* : :
* : :
* |---------------|
* | env[n] |
* |---------------|
* | 0 |
* |---------------| <-- Beginning of data returned by sysctl() is here.
* | argc |
* |---------------|
* | exec_path |
* |:::::::::::::::|
* | |
* | String area. |
* | |
* |---------------| <-- Top of stack.
* : :
* : :
* \---------------/ 0xffffffff
*/
mib[0] = CTL_KERN;
mib[1] = KERN_PROCARGS2;
mib[2] = pid;
size = (size_t)argmax;
if (sysctl(mib, 3, procargs, &size, NULL, 0) == -1) {
//goto ERROR_B;
return #"";
}
memcpy(&nargs, procargs, sizeof(nargs));
cp = procargs + sizeof(nargs);
/* Skip the saved exec_path. */
for (; cp < &procargs[size]; cp++) {
if (*cp == '\0') {
/* End of exec_path reached. */
break;
}
}
if (cp == &procargs[size]) {
//goto ERROR_B;
return #"";
}
/* Skip trailing '\0' characters. */
for (; cp < &procargs[size]; cp++) {
if (*cp != '\0') {
/* Beginning of first argument reached. */
break;
}
}
if (cp == &procargs[size]) {
//goto ERROR_B;
return #"";
}
/* Save where the argv[0] string starts. */
sp = cp;
/*
* Iterate through the '\0'-terminated strings and convert '\0' to ' '
* until a string is found that has a '=' character in it (or there are
* no more strings in procargs). There is no way to deterministically
* know where the command arguments end and the environment strings
* start, which is why the '=' character is searched for as a heuristic.
*/
for (np = NULL; c < nargs && cp < &procargs[size]; cp++) {
if (*cp == '\0') {
c++;
if (np != NULL) {
/* Convert previous '\0'. */
*np = ' ';
} else {
/* *argv0len = cp - sp; */
}
/* Note location of current '\0'. */
np = cp;
if (!show_args) {
/*
* Don't convert '\0' characters to ' '.
* However, we needed to know that the
* command name was terminated, which we
* now know.
*/
break;
}
}
}
/*
* sp points to the beginning of the arguments/environment string, and
* np should point to the '\0' terminator for the string.
*/
if (np == NULL || np == sp) {
/* Empty or unterminated string. */
// goto ERROR_B;
return #"";
}
/* Make a copy of the string. */
// printf("%s\n", sp);
//path = sp;
memset(path,0,1000);
strcpy(path, sp);
NSString *pathStr = [NSString stringWithFormat:#"%s",path];
NSLog(#"%#",pathStr);
// printf("%s\n", path);
/* Clean up. */
free(procargs);
return pathStr;
ERROR_B:
free(procargs);
ERROR_A:
printf("(%d)", pid);
}
So magicd's answer and Victor's comment with the link to the header file helped me solve this.
I did want to add that you have to add the MobileInstallation.framework to the "Linked Frameworks and Libraries" in Xcode. I found that framework here:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/PrivateFrameworks
I can confirm that this does work on a non-jailbroken device. The app store is not a concern for me.
Here's the code I used:
NSDictionary *options = [NSDictionary dictionaryWithObject:#"Any" forKey:#"ApplicationType"];
NSDictionary *apps = (__bridge NSDictionary *) MobileInstallationLookup((__bridge CFDictionaryRef) options);
Related
I want to build a tcp package in a kernel module and send it to another host by IP address using function dev_queue_xmit(skb). But I don't want to fill the Mac address manually by hand. The following is code for package producing.
Some kernel functions call eth_rebuild_header(skb) to rebuild Mac header. However, in my case, it hangs my computer after being called. Google results answers that arp_find will crash the OS if the arp cache contains not entry for that IP address. But I'm sure the it exists in the arp cache as printed by shell command "arp -v".
static int build_and_xmit_tcp(char * eth, u_char * smac, u_char * dmac,
u_long sip, u_long dip,
u_short sport, u_short dport,
u_char * pkt, int pkt_len,
int syn, int ack, int fin,
__be32 seq, __be32 seq_ack)
{
struct sk_buff * skb = NULL;
struct net_device * dev = NULL;
struct ethhdr * ethdr = NULL;
struct iphdr * iph = NULL;
struct tcphdr * tcph = NULL;
u_char * pdata = NULL;
if(NULL == smac || NULL == dmac)
goto out;
if(NULL == (dev= dev_get_by_name(&init_net, eth)))
goto out;
skb = alloc_skb(pkt_len + sizeof(struct iphdr) + sizeof(struct tcphdr) + LL_RESERVED_SPACE(dev), GFP_ATOMIC);
if(NULL == skb)
goto out;
skb_reserve(skb, LL_RESERVED_SPACE(dev));
skb->dev = dev;
skb->pkt_type = PACKET_OTHERHOST;
skb->protocol = __constant_htons(ETH_P_IP);
skb->ip_summed = CHECKSUM_NONE;
skb->priority = 0;
skb_set_network_header(skb, 0);
skb_put(skb, sizeof(struct iphdr));
skb_set_transport_header(skb, sizeof(struct iphdr));
skb_put(skb, sizeof(struct tcphdr));
pdata = skb_put(skb, pkt_len);
{
if(NULL != pkt)
memcpy(pdata, pkt, pkt_len);
}
tcph = tcp_hdr(skb);
memset(tcph, 0, sizeof(struct tcphdr));
tcph->source = sport;
tcph->dest = dport;
tcph->doff=5;
tcph->seq = htonl(seq);
tcph-> ack_seq= htonl( seq_ack);
tcph->psh = pkt_len>0? 1:0;
tcph ->fin = fin;
tcph->ack = ack;
tcph->syn=syn;
tcph->window=__constant_htons (65535);
skb->csum = 0;
tcph->check = 0;
iph = ip_hdr(skb);
iph->version = 4;
iph->ihl = sizeof(struct iphdr)>>2;
iph->frag_off = 0;
iph->protocol = IPPROTO_TCP;
iph->tos = 0;
iph->daddr = dip;
iph->saddr = sip;
iph->ttl = 0x40;
iph->tot_len = __constant_htons(skb->len);
iph->check = 0;
iph->check = ip_fast_csum((unsigned char *)iph,iph->ihl);
skb->csum = skb_checksum(skb, iph->ihl*4, skb->len - iph->ihl * 4, 0);
tcph->check = csum_tcpudp_magic(sip, dip, skb->len - iph->ihl * 4, IPPROTO_TCP, skb->csum);
skb_push(skb, 14);
skb_set_mac_header(skb, 0);
ethdr = (struct ethhdr *)eth_hdr(skb);
// memcpy(ethdr->h_dest, dmac, ETH_ALEN);
// memcpy(ethdr->h_source, smac, ETH_ALEN);
ethdr->h_proto = __constant_htons(ETH_P_IP);
// arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
// dst_ha, dev->dev_addr, NULL);
eth_rebuild_header(skb); // kernel hang....
if(0 > dev_queue_xmit(skb)) {
dev_put (dev);
kfree_skb (skb);
}
return(NF_ACCEPT);
out:
dev_put (dev);
kfree_skb (skb);
return(NF_ACCEPT);
}
static int __init myhook_init(void)
{
printk("=========insert module......\n");
build_and_xmit_tcp(ETH_O, GWMAC_O, DMAC, in_aton(GWIP_O), in_aton(DIP), htons(8888), htons(DPORT),
"", 0,
1, 0, 0, 0, 0);
}
static void __exit myhook_fini(void)
{
printk("=========rmmod ......\n");
}
module_init(myhook_init);
module_exit(myhook_fini);
Google gives me some other solution. They say arp_ioctl can resolve the Mac address. However, the fact is that, arp_ioctl is compiled statically into vmlinuz, which is not exported as a symbol to other modules.
int arp_get(char *ifname, char *ipStr)
{
struct arpreq req;
struct sockaddr_in *sin;
int ret = 0;
int sock_fd = 0;
struct net_device * dev = NULL;
printk("arp ---- \n");
if(NULL == (dev= dev_get_by_name(&init_net, ifname))){
dev_put (dev);
printk("error dev get \n");
return -1;
}
struct net *net_arp = dev_net(dev);
memset(&req, 0, sizeof(struct arpreq));
sin = (struct sockaddr_in *)&req.arp_pa;
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = in_aton(ipStr);
strncpy(req.arp_dev, ifname, 15);
ret = arp_ioctl(net_arp, SIOCGARP, &req); // can't be called
unsigned char *hw = (unsigned char *)req.arp_ha.sa_data;
printk("%#x-%#x-%#x-%#x-%#x-%#x\n", hw[0], hw[1], hw[2], hw[3], hw[4], hw[5]);
return 0;
}
Maybe I need make a socket structure, and try some upper functions based on a socket. But how to do it...
kernel version : 2.6.32
os version: ubuntu 9.10
gcc version : 4.41
int ip_xmit(struct sk_buff *skb)
{
struct iphdr *iph = ip_hdr(skb);
struct tcphdr *tcph = tcp_hdr(skb);
printk("dst is %d\n", skb->_skb_dst);
int err;
// err = ip_route_input(skb, iph->daddr, iph->saddr, 0, skb->dev);
struct rtalbe *rt;
{
struct flowi fl = { .oif = 0,
.nl_u = { .ip4_u =
{ .daddr = iph->daddr,
.saddr = iph->saddr,
.tos = 0 } },
.proto = IPPROTO_TCP,
.flags = 0,
.uli_u = { .ports =
{ .sport = tcph->source,
.dport = tcph->dest } } };
if (err = ip_route_output_key(&init_net, &rt, &fl))
return err;
printk("err is %d\n", err);
}
skb_dst_set(skb, rt);
if(0 > ip_local_out(skb)) {
printk("dev error\n");
kfree_skb (skb);
return -1;
}
return 0;
}
function ip_route_output_key can obtain the route destination, and ip_local_out deliver the skb out.
In my app I'm getting battery infos using this way (via IOKit).
static void print_raw_battery_state(io_registry_entry_t b_reg) {
CFBooleanRef boo;
CFNumberRef n;
int tmp;
int cur_cap = -1;
int max_cap = -1;
CFMutableDictionaryRef prop = NULL;
IOReturn ret;
ret = IORegistryEntryCreateCFProperties(b_reg, &prop, 0, 0);
if( (kIOReturnSuccess != ret) || (NULL == prop) )
{
printf("Couldn't read battery status; error = 0%08x\n", ret);
return;
}
boo = CFDictionaryGetValue(prop, CFSTR(kIOPMPSExternalConnectedKey));
printf(" external connected = %s\n",
(kCFBooleanTrue == boo) ? "yes" : "no");
boo = CFDictionaryGetValue(prop, CFSTR(kIOPMPSBatteryInstalledKey));
printf(" battery present = %s\n",
(kCFBooleanTrue == boo) ? "yes" : "no");
boo = CFDictionaryGetValue(prop, CFSTR(kIOPMPSIsChargingKey));
printf(" battery charging = %s\n",
(kCFBooleanTrue == boo) ? "yes" : "no");
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSCurrentCapacityKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &cur_cap);
}
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSCurrentCapacityKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &max_cap);
}
if( (-1 != cur_cap) && (-1 != max_cap) )
{
printf(" cap = %d/%d\n", cur_cap, max_cap);
gcurCapacity = cur_cap;//hab
gmaxCapacity = max_cap;//hab
}
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSTimeRemainingKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &tmp);
NSLog(#" time REM = %d:%02d\n", tmp/60, tmp%60);
printf("time cicA = %d:%02d\n", tmp/60, tmp%60);
NSString *stringTimeRem = [NSString stringWithFormat:#"%d:%02d", tmp/60, tmp%60];
[[NSUserDefaults standardUserDefaults] setObject:stringTimeRem forKey:#"stringREM"];
}
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSAmperageKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &tmp);
gcurrent = tmp;//hab
printf(" current = %d\n", tmp);
}
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSCycleCountKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &tmp);
printf(" cycle count = %d\n", tmp);
gloadcycles = tmp;//hab
}
n = CFDictionaryGetValue(prop, CFSTR(kIOPMPSLocationKey));
if(n) {
CFNumberGetValue(n, kCFNumberIntType, &tmp);
printf(" location = %d\n", tmp);
}
printf("\n");
CFRelease(prop);
return;}
How can I access those infos using dlopen ? I need to get IOReturn and io_registry_entry_t using dlopen, so Apple won't probably find that IOKit is there.
Thanks.
I need to get IOReturn and io_registry_entry_t using dlopen
Those are just types. They're declared in header files, and not compiled into the IOKit library. You can't get those using dlopen().
so Apple won't probably find that IOKit is there
Again, types aren't explicitly represented in the binary. If Apple finds out that you're using IOKit, then the reason for that will not be the use of these types. They're the function names that betray.
However, if you use dlopen() to retrieve a pointer to these functions, the strings representing function names will still be an open book to Apple's static analysis tools. You may have to do some additional obfuscation in order the binary not to expose directly the private function names:
NSString *secondPart = #"ateCFProperties";
NSString *firstPart = #"IORegistryEntryCre";
const char *fname = [[firstPart stringByAppendingString:secondPart] UTF8String];
IOReturn (*fptr)(io_registry_entry_t, CFMutableDictionaryRef *, int, int);
fptr = dlsym(dyld_handle, fname);
etc.
H2CO3 is correct. Just #includeing IOKit doesn't affect the compiled code at all. It's when you directly use the functions defined in the IOKit headers and link against IOKit that the private framework can clearly be seen in your app. One form of obfuscation for hiding the private framework and symbols used is a simple cipher shift. For example, using H2CO3's example:
// Deciphers string in-place and returns a pointer to it
__attribute__((always_inline)) char* decipher(char* str) {
int i, n = strlen(str);
for(i = 0; i < n; i++) str[i]--;
return str;
}
//...
char sym[] = "JPSfhjtuszFouszDsfbufDGQspqfsujft";
char fr[] = "Gsbnfxpslt";
char fmwk[] = "JPLju";
char lib[60];
decipher(fmwk);
sprintf(lib, "/System/Library/%s/%s.framework/Versions/A/%s", fr, fmwk, fmwk);
void* handle = dlopen(lib, RTLD_LAZY);
IOReturn (*fptr)(io_registry_event_t, CFMutableDictionaryRef*,i int, int);
fptr = dlsym(handle, decipher(sym));
// Now just call fptr() as if it were IORegistryEntryCreateCFProperties()
The difference between this and H2CO3's version is that this will prevent people manually analyzing the app from finding IOKit at all without a reasonable amount of expertise. Of course, a determined reverser can still find the usage of IOKit no matter how well you try to hide it. Obfuscation is useful here because App Store reviewers likely won't devote their time to reversing your app for days. Also, remember to strip your app before you submit it. I think stripping is enabled by default in Xcode, but I'm not sure. You'll need to figure that one out yourself.
#import "ViewController.h"
#import "IOKit/IOKitLib.h"
#import "IOKit/IOPSKeys.h"
#include <dlfcn.h>
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
static mach_port_t *s_kIOMasterPortDefault;
static kern_return_t (*s_IORegistryEntryCreateCFProperties)(mach_port_t entry, CFMutableDictionaryRef *properties, CFAllocatorRef allocator, UInt32 options);
static mach_port_t (*s_IOServiceGetMatchingService)(mach_port_t masterPort, CFDictionaryRef matching CF_RELEASES_ARGUMENT);
static CFMutableDictionaryRef (*s_IOServiceMatching)(const char *name);
static CFMutableDictionaryRef g_powerSourceService;
static mach_port_t g_platformExpertDevice;
static BOOL foundSymbols = NO;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
void* handle = dlopen("/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit", RTLD_LAZY);
s_IORegistryEntryCreateCFProperties = dlsym(handle, "IORegistryEntryCreateCFProperties");
s_kIOMasterPortDefault = dlsym(handle, "kIOMasterPortDefault");
s_IOServiceMatching = dlsym(handle, "IOServiceMatching");
s_IOServiceGetMatchingService = dlsym(handle, "IOServiceGetMatchingService");
if (s_IORegistryEntryCreateCFProperties && s_IOServiceMatching && s_IOServiceGetMatchingService) {
g_powerSourceService = s_IOServiceMatching("IOPMPowerSource");
g_platformExpertDevice = s_IOServiceGetMatchingService(*s_kIOMasterPortDefault, g_powerSourceService);
foundSymbols = (g_powerSourceService && g_platformExpertDevice);
}
});
if (!foundSymbols) {
return;
}
print_raw_battery_state(g_platformExpertDevice);
}
static void print_raw_battery_state(io_registry_entry_t b_reg) {
CFBooleanRef boo;
CFNumberRef n;
int tmp;
int cur_cap = -1;
int max_cap = -1;
CFMutableDictionaryRef prop = NULL;
IOReturn ret;
ret = IORegistryEntryCreateCFProperties(b_reg, &prop, 0, 0);
if( (kIOReturnSuccess != ret) || (NULL == prop) )
{
printf("Couldn't read battery status; error = 0%08x\n", ret);
return;
}
// battery dictionary
NSLog(#"prop: %#", prop);
printf("\n");
CFRelease(prop);
return;
}
}
#end
In iOS 11 and 12, you will only get a few values.
I have list of background processes and their pid running in background in iphone got from following code. My projects requirement is-
(its like an antivirus)
Get information on each process
a. Name
b. Size
c. Last Modified Date/Time
d. Associated Files
e. What the process is accessing from all interfaces (storage, USB, Bluetooth, Wi-Fi etc)
f. Any other information available
Thanks in advance.
#import <mach/mach_host.h>
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "sys/sysctl.h"
#include <CoreFoundation/CoreFoundation.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
- (void)viewDidLoad
{
[super viewDidLoad];
[self printProcessInfo];
}
-(int) printProcessInfo
{
int mib[5];
struct kinfo_proc *procs = NULL, *newprocs;
int i, st, nprocs;
size_t miblen, size;
/* Set up sysctl MIB */
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_ALL;
mib[3] = 0;
miblen = 4;
/* Get initial sizing */
st = sysctl(mib, miblen, NULL, &size, NULL, 0);
/* Repeat until we get them all ... */
do {
/* Room to grow */
size += size / 10;
newprocs = realloc(procs, size);
if (!newprocs) {
if (procs) {
free(procs);
}
perror("Error: realloc failed.");
return (0);
}
procs = newprocs;
st = sysctl(mib, miblen, procs, &size, NULL, 0);
} while (st == -1 && errno == ENOMEM);
if (st != 0) {
perror("Error: sysctl(KERN_PROC) failed.");
return (0);
}
/* Do we match the kernel? */
assert(size % sizeof(struct kinfo_proc) == 0);
nprocs = size / sizeof(struct kinfo_proc);
if (!nprocs) {
perror("Error: printProcessInfo.");
return(0);
}
printf(" PID\tName\n");
printf("-----\t--------------\n");
self.lists = [[NSMutableString alloc] init];
for (i = nprocs-1; i >=0; i--) {
printf("%5d\t%s\n",(int)procs[i].kp_proc.p_pid, procs[i].kp_proc.p_comm);
}
NSLog(#"%#",lists);
listsText.text = lists;
free(procs);
return (0);
}
answer a)name of process you are getting in above code.
answer d)to get associated files,pass pid of process to this function (we have got pid in questions code)-
void print_argv_of_pid(int pid) {
printf("%d\n", pid);
int mib[3], argmax, nargs, c = 0;
size_t size;
char *procargs, *sp, *np, *cp;
extern int eflg;
int show_args = 1;
mib[0] = CTL_KERN;
mib[1] = KERN_ARGMAX;
size = sizeof(argmax);
if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1) {
goto ERROR_A;
}
/* Allocate space for the arguments. */
procargs = (char *)malloc(argmax);
if (procargs == NULL) {
goto ERROR_A;
}
mib[0] = CTL_KERN;
mib[1] = KERN_PROCARGS2;
mib[2] = pid;
size = (size_t)argmax;
if (sysctl(mib, 3, procargs, &size, NULL, 0) == -1) {
goto ERROR_B;
}
memcpy(&nargs, procargs, sizeof(nargs));
cp = procargs + sizeof(nargs);
/* Skip the saved exec_path. */
for (; cp < &procargs[size]; cp++) {
if (*cp == '\0') {
/* End of exec_path reached. */
break;
}
}
if (cp == &procargs[size]) {
goto ERROR_B;
}
/* Skip trailing '\0' characters. */
for (; cp < &procargs[size]; cp++) {
if (*cp != '\0') {
/* Beginning of first argument reached. */
break;
}
}
if (cp == &procargs[size]) {
goto ERROR_B;
}
/* Save where the argv[0] string starts. */
sp = cp;
for (np = NULL; c < nargs && cp < &procargs[size]; cp++) {
if (*cp == '\0') {
c++;
if (np != NULL) {
/* Convert previous '\0'. */
*np = ' ';
} else {
/* *argv0len = cp - sp; */
}
/* Note location of current '\0'. */
np = cp;
if (!show_args) {
/*
* Don't convert '\0' characters to ' '.
* However, we needed to know that the
* command name was terminated, which we
* now know.
*/
break;
}
}
}
if (np == NULL || np == sp) {
/* Empty or unterminated string. */
goto ERROR_B;
}
/* Make a copy of the string. */
printf("%s\n", sp);
/* Clean up. */
free(procargs);
return;
ERROR_B:
free(procargs);
ERROR_A:
printf("error");
}
answer b),c)-size and access times-
struct stat st;
//pass filepath upto /.app/ to stat function (use 'componentsseparatedby' of nsstring apply on full path which we got in answer d's code above)
if (stat(filename, &st)) {
perror(filename);
} else {
printf("%s: mtime = %lld.%.9ld\n", filename, (long long)st.st_mtimespec.tv_sec, st.st_mtimespec.tv_nsec);
printf("File size: %lld bytes\n",
(long long) st.st_size);
printf("Last status change: %s", ctime(&st.st_ctime));
printf("Last file access: %s", ctime(&st.st_atime));
printf("Last file modification: %s", ctime(&st.st_mtime));
}
other information-
TO KILL THE PROCESS-
just pass pid of process to be killed-
int pid_exists(long pid)
{
int kill_ret;
// save some time if it's an invalid PID
if (pid < 0) {
return 0;
}
// if kill returns success of permission denied we know it's a valid PID
kill_ret = kill(pid , 0);
if ( (0 == kill_ret) || (EPERM == errno) ) {
return 1;
}
// otherwise return 0 for PID not found
return 0;
}
i am using iOS-libarchive library for .tar extraction on iphone. i am using the sample code given here at this link
http://code.google.com/p/libarchive/wiki/Examples
but i am facing problem in extracting .tar file.
i am placing my .tar file in library/simulator.../Application/617C31E0/Documents folder.
when i run application for extraction then it completes it flow successfully without giving any error code. but i could not fine that extracted folder anywhere in machine.
here is the piece of code, i am using in my application
static int copy_data(struct archive *ar, struct archive *aw)
{
int r;
const void *buff;
size_t size;
off_t offset;
for (;;) {
r = archive_read_data_block(ar, &buff, &size, &offset);
if (r == ARCHIVE_EOF)
return (ARCHIVE_OK);
if (r != ARCHIVE_OK)
return (r);
r = archive_write_data_block(aw, buff, size, offset);
if (r != ARCHIVE_OK) {
warn("archive_write_data_block()",
archive_error_string(aw));
return (r);
}
}
}
static int verbose = 0;
static void extract(const char *filename, int do_extract, int flags)
{
struct archive *a;
struct archive *ext;
struct archive_entry *entry;
int r;
a = archive_read_new();
ext = archive_write_disk_new();
archive_write_disk_set_options(ext, flags);
/*
* Note: archive_write_disk_set_standard_lookup() is useful
* here, but it requires library routines that can add 500k or
* more to a static executable.
*/
archive_read_support_format_tar(a);
/*
* On my system, enabling other archive formats adds 20k-30k
* each. Enabling gzip decompression adds about 20k.
* Enabling bzip2 is more expensive because the libbz2 library
* isn't very well factored.
*/
if (filename != NULL && strcmp(filename, "-") == 0)
filename = NULL;
if ((r = archive_read_open_file(a, filename, 10240)))
fail("archive_read_open_file()",
archive_error_string(a), r);
for (;;) {
r = archive_read_next_header(a, &entry);
if (r == ARCHIVE_EOF)
break;
if (r != ARCHIVE_OK)
fail("archive_read_next_header()",
archive_error_string(a), 1);
if (verbose && do_extract)
msg("x ");
if (verbose || !do_extract)
msg(archive_entry_pathname(entry));
if (do_extract) {
r = archive_write_header(ext, entry);
if (r != ARCHIVE_OK)
warn("archive_write_header()",
archive_error_string(ext));
else {
copy_data(a, ext);
r = archive_write_finish_entry(ext);
if (r != ARCHIVE_OK)
fail("archive_write_finish_entry()",
archive_error_string(ext), 1);
}
}
if (verbose || !do_extract)
msg("\n");
}
archive_read_close(a);
archive_read_finish(a);
exit(0);
}
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
// Override point for customization after application launch
[window makeKeyAndVisible];
// Extract files from archive into named dir in the temp dir
NSString* databaseName = #"PIIS147020451170078X.tar";
NSArray* documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDir = [documentPaths objectAtIndex:0];
NSString* make7zResPath = [documentsDir stringByAppendingPathComponent:databaseName];
/*
NSString *tmpDirname = #"Extract7z";
NSString *make7zFilename = #"PIIS147020451170078X";//#"test.7z";
NSString *make7zResPath = [[NSBundle mainBundle] pathForResource:make7zFilename ofType:#"tar"];
*/
extract([make7zResPath cStringUsingEncoding:NSUTF8StringEncoding],1, ARCHIVE_EXTRACT_TIME);
return;
}
Please help me into this :(.
Thanks!!
I write another library that do exactly what you want: https://github.com/mhausherr/Light-Untar-for-iOS
In few words i've only implemented the minimal functions to untar a file.
Full explanation here http://blog.octo.com/en/untar-on-ios-the-pragmatic-way/
I have an API which sends an XML Request to a server:
<?xml version="1.0" encoding="UTF-8"?>
<request type="handle" action="update">
<userdata>
<username>YourUsername</username>
<password>YourPassword</password>
</userdata>
<handledata type="PERSON" id="HandleId">
<name>Mustermann</name>
<firstname>Max</firstname>
<organization>Firma KG</organization>
<street>Musterstrasse 1</street>
<postalcode>11111</postalcode>
<city>Musterstadt</city>
<state>Niedersachsen</state>
<country>DE</country>
<email>email#adresse.de</email>
<phone>+43-111-111111</phone>
<fax>+43-111-111111</fax>
<remarks>remarks</remarks>
</handledata>
</request>
How do I do this on the iPhone?
You can use libxml2. I suspect it is the fastest approach. Add its framework to your project (see the "setting up your project" section of this document).
In the header of your XML writer, add the following imports:
#import <libxml/encoding.h>
#import <libxml/xmlwriter.h>
In the implementation, write a method to generate your XML. Presumably you'll be sending your request's bytes via an NSData* object, so you might write something like this:
- (NSData *) xmlDataFromRequest
{
xmlTextWriterPtr _writer;
xmlBufferPtr _buf;
xmlChar *_tmp;
const char *_UTF8Encoding = "UTF-8";
_buf = xmlBufferCreate();
_writer = xmlNewTextWriterMemory(_buf, 0);
// <?xml version="1.0" encoding="UTF-8"?>
xmlTextWriterStartDocument(_writer, "1.0", _UTF8Encoding, NULL);
// <request type="handle" action="update">
xmlTextWriterStartElement(_writer, BAD_CAST "request");
xmlTextWriterWriteAttribute(_writer, BAD_CAST "type", BAD_CAST "handle");
xmlTextWriterWriteAttribute(_writer, BAD_CAST "action", BAD_CAST "update");
xmlTextWriterEndElement(_writer);
// <userdata>...</userdata>
xmlTextWriterStartElement(_writer, BAD_CAST "userdata");
xmlTextWriterStartElement(_writer, BAD_CAST "username");
_tmp = [self xmlCharPtrForInput:[[NSString stringWithFormat:#"YourUsername"] cStringUsingEncoding:NSUTF8StringEncoding] withEncoding:_UTF8Encoding];
xmlTextWriterWriteString(_writer, _tmp);
xmlTextWriterEndElement(_writer); // closing <username>
xmlFree(_tmp);
xmlTextWriterStartElement(_writer, BAD_CAST "password");
_tmp = [self xmlCharPtrForInput:[[NSString stringWithFormat:#"YourPassword"] cStringUsingEncoding:NSUTF8StringEncoding] withEncoding:_UTF8Encoding];
xmlTextWriterWriteString(_writer, _tmp);
xmlTextWriterEndElement(_writer); // closing <password>
xmlFree(_tmp);
xmlTextWriterEndElement(_writer); // closing <userdata>
// etc.
xmlTextWriterEndDocument(_writer);
xmlFreeTextWriter(_writer);
// turn libxml2 buffer into NSData* object
NSData *_xmlData = [NSData dataWithBytes:(_buf->content) length:(_buf->use)];
xmlBufferFree(_buf);
return _xmlData;
}
I have a helper method here that I use to convert const char * into xmlChar *:
- (xmlChar *) xmlCharPtrForInput:(const char *)_input withEncoding:(const char *)_encoding
{
xmlChar *_output;
int _ret;
int _size;
int _outputSize;
int _temp;
xmlCharEncodingHandlerPtr _handler;
if (_input == 0)
return 0;
_handler = xmlFindCharEncodingHandler(_encoding);
if (!_handler) {
NSLog(#"convertInput: no encoding handler found for '%s'\n", (_encoding ? _encoding : ""));
return 0;
}
_size = (int) strlen(_input) + 1;
_outputSize = _size * 2 - 1;
_output = (unsigned char *) xmlMalloc((size_t) _outputSize);
if (_output != 0) {
_temp = _size - 1;
_ret = _handler->input(_output, &_outputSize, (const xmlChar *) _input, &_temp);
if ((_ret < 0) || (_temp - _size + 1)) {
if (_ret < 0) {
NSLog(#"convertInput: conversion wasn't successful.\n");
} else {
NSLog(#"convertInput: conversion wasn't successful. Converted: %i octets.\n", _temp);
}
xmlFree(_output);
_output = 0;
} else {
_output = (unsigned char *) xmlRealloc(_output, _outputSize + 1);
_output[_outputSize] = 0; /*null terminating out */
}
} else {
NSLog(#"convertInput: no memory\n");
}
return _output;
}
I would use string formatting for such a simple structure.