curl.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include <stdio.h>
  2. #include <dlfcn.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <sys/time.h>
  6. typedef void CURL;
  7. typedef int CURLcode;
  8. typedef long long curl_off_t;
  9. typedef enum {
  10. HTTPREQ_NONE,
  11. HTTPREQ_GET,
  12. HTTPREQ_POST,
  13. HTTPREQ_POST_FORM,
  14. HTTPREQ_POST_MIME,
  15. HTTPREQ_PUT,
  16. HTTPREQ_HEAD,
  17. HTTPREQ_OPTIONS,
  18. HTTPREQ_LAST
  19. } Curl_HttpReq;
  20. static const int CURL_OK = 0;
  21. const char *methods[] = {
  22. "NONE", "GET", "POST", "POST_FORM", "POST_MIME", "PUT", "HEAD", "OPTIONS", "LAST", ""
  23. };
  24. static const char *AlarmPath = "/device/v1/alarm/add";
  25. static const char *DummyRes = "{\"ts\":1641390551000,\"code\":\"1\",\"msg\":\"\",\"data\":{\"alarm_file_list\":[{\"file_type\":1,\"file_suffix\":\"jpg\",\"file_url\":\"https://localhost/hoge.jpg\",\"encryption_algorithm\":0,\"encryption_password\":\"\"},{\"file_type\":2,\"file_suffix\":\"mp4\",\"file_url\":\"https://localhost/fuga.mp4\",\"encryption_algorithm\":0,\"encryption_password\":\"\"}]}}";
  26. static const char *DummyHost = "https://localhost/";
  27. typedef int (*curl_seek_callback)(void *instream, int offset, int origin);
  28. typedef int (*curl_write_callback)(char *buffer, int size, int nitems, void *outstream);
  29. struct SessionHandle {
  30. unsigned char padding0[1392];
  31. unsigned char padding1[16];
  32. void *out; // offset 1392 + 16
  33. unsigned char padding2[40];
  34. void *postfields; // offset 1392 + 60
  35. unsigned char padding3[8];
  36. curl_off_t postfieldsize; // offset offset 1392 + 72
  37. unsigned char padding4[8];
  38. curl_write_callback fwrite_func; // offset 1392 + 88
  39. unsigned char padding5[568];
  40. Curl_HttpReq httpreq; // offset 1392 + 660
  41. unsigned char padding6[664];
  42. char *url; // offset 2720 + 0
  43. unsigned char padding7[16];
  44. unsigned char padding8[988];
  45. int httpcode; // offset 3728 + 0
  46. };
  47. static CURLcode (*original_curl_easy_perform)(CURL *curl);
  48. static int curl_hook_enable = 0;
  49. static void __attribute ((constructor)) curl_hook_init(void) {
  50. original_curl_easy_perform = dlsym(dlopen("/thirdlib/libcurl.so", RTLD_LAZY), "curl_easy_perform");
  51. char *p = getenv("MINIMIZE_ALARM_CYCLE");
  52. curl_hook_enable = p && !strcmp(p, "on");
  53. }
  54. static void Dump(const char *str, void *start, int size) {
  55. printf("[curl-debug] Dump %s\n", str);
  56. for(int i = 0; i < size; i+= 16) {
  57. char buf1[256];
  58. char buf2[256];
  59. sprintf(buf1, "%08x : ", start + i);
  60. for(int j = 0; j < 16; j++) {
  61. if(i + j >= size) break;
  62. unsigned char d = ((unsigned char *)start)[i + j];
  63. sprintf(buf1 + strlen(buf1), "%02x ", d);
  64. if((d < 0x20) || (d > 0x7f)) d = '.';
  65. sprintf(buf2 + j, "%c", d);
  66. }
  67. printf("%s %s\n", buf1, buf2);
  68. }
  69. }
  70. CURLcode curl_easy_perform(struct SessionHandle *data) {
  71. if(!curl_hook_enable) return original_curl_easy_perform(data);
  72. unsigned int ra = 0;
  73. asm volatile(
  74. "ori %0, $31, 0\n"
  75. : "=r"(ra)
  76. );
  77. int method = data->httpreq;
  78. if(method > HTTPREQ_LAST) method = HTTPREQ_LAST;
  79. printf("[curl-debug] %s %s ra=0x%08x\n", methods[method], data->url, ra);
  80. if(data->postfields) {
  81. if(data->postfieldsize > 0) {
  82. Dump("[curl-debug] post", data->postfields, data->postfieldsize);
  83. } else {
  84. printf("[curl-debug] post : %s\n", data->postfields);
  85. }
  86. }
  87. if(data->url && !strcmp(data->url + strlen(data->url) - strlen(AlarmPath), AlarmPath)) {
  88. static time_t lastAccess = 0;
  89. struct timeval now;
  90. gettimeofday(&now, NULL);
  91. if(now.tv_sec - lastAccess < 300) {
  92. printf("[curl-debug] Dismiss short cycle alarms.\n");
  93. memcpy(data->out, DummyRes, strlen(DummyRes));
  94. data->httpcode = 200;
  95. return CURL_OK;
  96. }
  97. CURLcode res = original_curl_easy_perform(data);
  98. printf("[curl-debug] res=%d\n", res);
  99. if(!res) lastAccess = now.tv_sec;
  100. return res;
  101. }
  102. if(data->url && !strncmp(data->url, DummyHost, strlen(DummyHost))) {
  103. printf("[curl-debug] skip http-post.\n");
  104. data->httpcode = 200;
  105. return CURL_OK;
  106. }
  107. CURLcode res = original_curl_easy_perform(data);
  108. if(data->out) printf("[curl-debug] res : %s\n", data->out);
  109. printf("[curl-debug] ret: %d\n", res);
  110. return res;
  111. }