Skip to content

Commit

Permalink
Fix iR timestamp + consistent timestamp format output (pt*, iI~comp, …
Browse files Browse the repository at this point in the history
  • Loading branch information
koffiedrinker authored and Maijin committed Jan 16, 2019
1 parent adab5e4 commit 51ed856
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 140 deletions.
32 changes: 7 additions & 25 deletions libr/bin/format/pe/pe.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,29 +514,6 @@ static int bin_pe_parse_imports(struct PE_(r_bin_pe_obj_t)* bin,
return false;
}

static char *_time_stamp_to_str(ut32 timeStamp) {
#ifdef _MSC_VER
time_t rawtime;
struct tm *tminfo;
rawtime = (time_t)timeStamp;
tminfo = localtime (&rawtime);
//tminfo = gmtime (&rawtime);
return r_str_trim (strdup (asctime (tminfo)));
#else
struct my_timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of DST correction */
} tz;
struct timeval tv;
int gmtoff;
time_t ts = (time_t) timeStamp;
gettimeofday (&tv, (void*) &tz);
gmtoff = (int) (tz.tz_minuteswest * 60); // in seconds
ts += (time_t)gmtoff;
return r_str_trim (strdup (ctime (&ts)));
#endif
}

static int bin_pe_init_hdr(struct PE_(r_bin_pe_obj_t)* bin) {
if (!(bin->dos_header = malloc (sizeof(PE_(image_dos_header))))) {
r_sys_perror ("malloc (dos header)");
Expand Down Expand Up @@ -613,7 +590,7 @@ static int bin_pe_init_hdr(struct PE_(r_bin_pe_obj_t)* bin) {
// adding compile time to the SDB
{
sdb_num_set (bin->kv, "image_file_header.TimeDateStamp", bin->nt_headers->file_header.TimeDateStamp, 0);
char *timestr = _time_stamp_to_str (bin->nt_headers->file_header.TimeDateStamp);
char *timestr = r_time_stamp_to_str (bin->nt_headers->file_header.TimeDateStamp);
sdb_set_owned (bin->kv, "image_file_header.TimeDateStamp_string", timestr, 0);
}
bin->optional_header = &bin->nt_headers->optional_header;
Expand Down Expand Up @@ -2360,7 +2337,12 @@ static void _parse_resource_directory(struct PE_(r_bin_pe_obj_t) *bin, Pe_image_
free (data);
break;
}
rs->timestr = _time_stamp_to_str (dir->TimeDateStamp);
/* Compare compileTimeStamp to resource timestamp to figure out if DOS date or POSIX date */
if (r_time_stamp_is_dos_format ((ut32) sdb_num_get (bin->kv, "image_file_header.TimeDateStamp", 0), dir->TimeDateStamp)) {
rs->timestr = r_time_stamp_to_str ( r_dos_time_stamp_to_posix (dir->TimeDateStamp));
} else {
rs->timestr = r_time_stamp_to_str (dir->TimeDateStamp);
}
rs->type = _resource_type_str (type);
rs->language = strdup (_resource_lang_str (entry.u1.Name & 0x3ff));
rs->data = data;
Expand Down
1 change: 1 addition & 0 deletions libr/include/r_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ int gettimeofday (struct timeval* p, void* tz);
#include "r_util/r_buf.h"
#include "r_util/r_bitmap.h"
#include "r_util/r_constr.h"
#include "r_util/r_date.h"
#include "r_util/r_debruijn.h"
#include "r_util/r_cache.h"
#include "r_util/r_ctypes.h"
Expand Down
20 changes: 20 additions & 0 deletions libr/include/r_util/r_date.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef R2_DATE_H
#define R2_DATE_H

#ifdef __cplusplus
extern "C" {
#endif

#ifdef R_API

R_API char *r_time_stamp_to_str(ut32 timeStamp);
R_API ut32 r_dos_time_stamp_to_posix(ut32 timeStamp);
R_API bool r_time_stamp_is_dos_format(const ut32 certainPosixTimeStamp, const ut32 possiblePosixOrDosTimeStamp);

#endif

#ifdef __cplusplus
}
#endif

#endif
197 changes: 82 additions & 115 deletions libr/util/date.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,178 +2,145 @@

#include "r_util.h"
#include "r_util/r_print.h"
#include "r_util/r_date.h"

R_API char *r_time_stamp_to_str(ut32 timeStamp) {
#ifdef _MSC_VER
time_t rawtime;
struct tm *tminfo;
rawtime = (time_t)timeStamp;
tminfo = localtime (&rawtime);
//tminfo = gmtime (&rawtime);
return r_str_trim (strdup (asctime (tminfo)));
#else
struct my_timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of DST correction */
} tz;
struct timeval tv;
int gmtoff;
time_t ts = (time_t) timeStamp;
gettimeofday (&tv, (void*) &tz);
gmtoff = (int) (tz.tz_minuteswest * 60); // in seconds
ts += (time_t)gmtoff;
return r_str_trim (strdup (ctime (&ts)));
#endif
}

R_API ut32 r_dos_time_stamp_to_posix(ut32 timeStamp) {
ut16 date = timeStamp >> 16;
ut16 time = timeStamp & 0xFFFF;

/* Date */
ut32 year = ((date & 0xfe00) >> 9) + 1980;
ut32 month = (date & 0x01e0) >> 5;
ut32 day = date & 0x001f;

/* Time */
ut32 hour = (time & 0xf800) >> 11;
ut32 minutes = (time & 0x07e0) >> 5;
ut32 seconds = (time & 0x001f) << 1;

/* Convert to epoch */
struct tm t = {0};
t.tm_year = year - 1900;
t.tm_mon = month > 0 ? month - 1 : month;
t.tm_mday = day > 0 ? day : 1;
t.tm_hour = hour;
t.tm_min = minutes;
t.tm_sec = seconds;
t.tm_isdst = -1;
time_t epochTime = mktime (&t);

return (ut32) epochTime;
}

R_API bool r_time_stamp_is_dos_format(const ut32 certainPosixTimeStamp, const ut32 possiblePosixOrDosTimeStamp) {
/* We assume they're both POSIX timestamp and thus the higher bits would be equal if they're close to each other */
if ((certainPosixTimeStamp >> 16) == (possiblePosixOrDosTimeStamp >> 16)) {
return false;
}
return true;
}


R_API int r_print_date_dos(RPrint *p, const ut8 *buf, int len) {
ut8 _time[2] = { buf[0], buf[1] };
ut8 _date[2] = { buf[2], buf[3] };
ut32 t = _time[1]<<8 | _time[0];
ut32 d = _date[1]<<8 | _date[0];
ut32 year = ((d&0xfe00)>>9)+1980;
ut32 month = (d&0x01e0)>>5;
ut32 day = (d&0x001f)>>0;
ut32 hour = (t&0xf800)>>11;
ut32 minutes = (t&0x07e0)>>5;
ut32 seconds = (t&0x001f)<<1;

// TODO: support p->datezone
// TODO: support p->datefmt
/* la data de modificacio del fitxer, no de creacio del zip */
p->cb_printf ("%d-%02d-%02d %d:%d:%d\n",
year, month, day, hour, minutes, seconds);
if(len < 4) {
return 0;
}

ut32 dt = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
p->cb_printf ("%s\n", r_time_stamp_to_str ( r_dos_time_stamp_to_posix (dt)));
return 4;
}

R_API int r_print_date_hfs(RPrint *p, const ut8 *buf, int len) {
const int hfs_unix_delta = 2082844800;
time_t t = 0;
char s[256];
int ret = 0;
const struct tm* time;
struct tm timestruct;

if (p && len >= sizeof (ut32)) {
t = r_read_ble32 (buf, p->big_endian);
// "%d:%m:%Y %H:%M:%S %z",
if (p->datefmt[0]) {
t += p->datezone * (60*60);
t += hfs_unix_delta;
time = (const struct tm*)gmtime_r((const time_t*)&t, &timestruct);
if (time) {
ret = strftime (s, sizeof (s), p->datefmt, time);
if (ret) {
p->cb_printf ("%s\n", s);
ret = sizeof (time_t);
}
} else {
p->cb_printf ("Invalid time\n");
}

p->cb_printf ("%s\n", r_time_stamp_to_str (t));
ret = sizeof (time_t);
}
}
return ret;
}

R_API int r_print_date_unix(RPrint *p, const ut8 *buf, int len) {
time_t t = 0;
char s[256];
int ret = 0;
const struct tm* time;
struct tm timestruct;

if (p && len >= sizeof (ut32)) {
t = r_read_ble32 (buf, p->big_endian);
// "%d:%m:%Y %H:%M:%S %z",
if (p->datefmt[0]) {
t += p->datezone * (60*60);
time = (const struct tm*)gmtime_r((const time_t*)&t, &timestruct);
if (time) {
ret = strftime (s, sizeof (s), p->datefmt, time);
if (ret) {
p->cb_printf ("%s\n", s);
ret = sizeof (time_t);
}
} else {
p->cb_printf ("Invalid time\n");
}
t += p->datezone * (60*60);
p->cb_printf ("%s\n", r_time_stamp_to_str (t));
ret = sizeof (time_t);
}
}
return ret;
}

R_API int r_print_date_get_now(RPrint *p, char *str) {
int ret = 0;
#if __UNIX__
struct tm curt; /* current time */
time_t l;
char *week_str[7]= {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
char *month_str[12]= {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

*str = 0;
l = time(0);
localtime_r (&l, &curt);
// XXX localtime is affected by the timezone.

if ((curt.tm_wday >= 0 && curt.tm_wday < 7)
&& (curt.tm_mon >= 0 && curt.tm_mon < 12)) {
sprintf (str, "%s, %02d %s %d %02d:%02d:%02d GMT + %d",
week_str[curt.tm_wday],
curt.tm_mday,
month_str[curt.tm_mon],
curt.tm_year + 1900, curt.tm_hour,
curt.tm_min, curt.tm_sec, curt.tm_isdst);
ret = sizeof(time_t);
}
#else
*str = 0;
#ifdef _MSC_VER
#pragma message ("r_print_date_now NOT IMPLEMENTED FOR THIS PLATFORM")
#else
#warning r_print_date_now NOT IMPLEMENTED FOR THIS PLATFORM
#endif
#endif

str = r_time_stamp_to_str (l);
p->cb_printf ("%s\n", str);
ret = sizeof (time_t);
return ret;
}

R_API int r_print_date_w32(RPrint *p, const ut8 *buf, int len) {
ut64 l, L = 0x2b6109100LL;
time_t t;
int ret = 0;
char datestr[256];

if (p && len >= sizeof (ut64)) {
l = r_read_ble64 (buf, p->big_endian);
l /= 10000000; // 100ns to s
l = (l > L ? l-L : 0); // isValidUnixTime?
t = (time_t) l; // TODO limit above!
// "%d:%m:%Y %H:%M:%S %z",
if (p->datefmt[0]) {
struct tm time;
ret = strftime(datestr, 256, p->datefmt,
(const struct tm*) gmtime_r ((const time_t*)&t, &time));
if (ret) {
p->cb_printf("%s\n", datestr);
ret = true;
}
p->cb_printf ("%s\n", r_time_stamp_to_str (t));
ret = sizeof (time_t);
}
}

return ret;
}

R_API const char *r_time_to_string (ut64 ts) {
static char str[128];
#if __UNIX__
struct tm curt; /* current time */
time_t l;
char *week_str[7]= {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
char *month_str[12]= {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

*str = 0;
l = ts >> 20;
localtime_r (&l, &curt);
// XXX localtime is affected by the timezone.

if ((curt.tm_wday >= 0 && curt.tm_wday < 7)
&& (curt.tm_mon >= 0 && curt.tm_mon < 12)) {
sprintf (str, "%s, %02d %s %d %02d:%02d:%02d GMT + %d",
week_str[curt.tm_wday],
curt.tm_mday,
month_str[curt.tm_mon],
curt.tm_year + 1900, curt.tm_hour,
curt.tm_min, curt.tm_sec, curt.tm_isdst);
}
#else
*str = 0;
#ifdef _MSC_VER
#pragma message ("r_time_to_string NOT IMPLEMENTED FOR THIS PLATFORM")
#else
#warning r_time_to_string NOT IMPLEMENTED FOR THIS PLATFORM
#endif
#endif
return str;
time_t l;
l = ts >> 20;
return r_time_stamp_to_str (l);
}

0 comments on commit 51ed856

Please sign in to comment.