/
core_java.c
2031 lines (1763 loc) · 70.7 KB
/
core_java.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* radare - Apache - Copyright 2014 dso <adam.pridgen@thecoverofnight.com | dso@rice.edu> */
#include <r_types.h>
#include <r_lib.h>
#include <r_cmd.h>
#include <r_core.h>
#include <r_cons.h>
#include <string.h>
#include <r_anal.h>
#include <r_anal_ex.h>
#if 0
#include "../../../shlr/java/ops.c"
#include "../../../shlr/java/code.c"
#include "../../../shlr/java/class.c"
#endif
#include "../../../shlr/java/class.h"
#include "../../../shlr/java/code.h"
#include "../../../shlr/java/dsojson.h"
#define DO_THE_DBG 0
#undef IFDBG
#define IFDBG if (DO_THE_DBG)
typedef struct found_idx_t {
ut16 idx;
ut64 addr;
const RBinJavaCPTypeObj *obj;
} RCmdJavaCPResult;
typedef int (*RCMDJavaCmdHandler) (RCore *core, const char *cmd);
static const char * r_cmd_java_strtok (const char *str1, const char b, size_t len);
static const char * r_cmd_java_consumetok (const char *str1, const char b, size_t len);
static int r_cmd_java_reload_bin_from_buf (RCore *core, RBinJavaObj *obj, ut8* buffer, ut64 len);
static int r_cmd_java_print_json_definitions( RBinJavaObj *obj );
static int r_cmd_java_print_all_definitions( RAnal *anal );
static int r_cmd_java_print_class_definitions( RBinJavaObj *obj );
static int r_cmd_java_print_field_definitions( RBinJavaObj *obj );
static int r_cmd_java_print_method_definitions( RBinJavaObj *obj );
static int r_cmd_java_print_import_definitions( RBinJavaObj *obj );
static int r_cmd_java_resolve_cp_idx (RBinJavaObj *obj, ut16 idx);
static int r_cmd_java_resolve_cp_type (RBinJavaObj *obj, ut16 idx);
static int r_cmd_java_resolve_cp_idx_b64 (RBinJavaObj *obj, ut16 idx);
static int r_cmd_java_resolve_cp_address (RBinJavaObj *obj, ut16 idx);
static int r_cmd_java_resolve_cp_to_key (RBinJavaObj *obj, ut16 idx);
static int r_cmd_java_resolve_cp_summary (RBinJavaObj *obj, ut16 idx);
static int r_cmd_java_print_class_access_flags_value( const char * flags );
static int r_cmd_java_print_field_access_flags_value( const char * flags );
static int r_cmd_java_print_method_access_flags_value( const char * flags );
static int r_cmd_java_get_all_access_flags_value (const char *cmd);
static int r_cmd_java_set_acc_flags (RCore *core, ut64 addr, ut16 num_acc_flag);
#define _(x) UNUSED_FUNCTION(x)
static int r_cmd_java_print_field_summary (RBinJavaObj *obj, ut16 idx);
static int _(r_cmd_java_print_field_count) (RBinJavaObj *obj);
static int r_cmd_java_print_field_name (RBinJavaObj *obj, ut16 idx);
static int r_cmd_java_print_field_num_name (RBinJavaObj *obj);
static int r_cmd_java_print_method_summary (RBinJavaObj *obj, ut16 idx);
static int _(r_cmd_java_print_method_count) (RBinJavaObj *obj);
static int r_cmd_java_print_method_name (RBinJavaObj *obj, ut16 idx);
static int r_cmd_java_print_method_num_name (RBinJavaObj *obj);
static RBinJavaObj * r_cmd_java_get_bin_obj(RAnal *anal);
static RList * r_cmd_java_get_bin_obj_list(RAnal *anal);
static ut64 r_cmd_java_get_input_num_value(RCore *core, const char *input_value);
static int r_cmd_java_is_valid_input_num_value(RCore *core, const char *input_value);
static int r_cmd_java_call(void *user, const char *input);
static int r_cmd_java_handle_help (RCore * core, const char * input);
static int r_cmd_java_handle_set_flags (RCore * core, const char * cmd);
static int r_cmd_java_handle_prototypes (RCore * core, const char * cmd);
static int r_cmd_java_handle_resolve_cp (RCore * core, const char * cmd);
static int r_cmd_java_handle_calc_flags (RCore * core, const char * cmd);
static int r_cmd_java_handle_flags_str (RCore *core, const char *cmd);
static int r_cmd_java_handle_flags_str_at (RCore *core, const char *cmd);
static int r_cmd_java_handle_field_info (RCore *core, const char *cmd);
static int r_cmd_java_handle_method_info (RCore *core, const char *cmd);
static int r_cmd_java_handle_find_cp_const (RCore *core, const char *cmd);
static RList * r_cmd_java_handle_find_cp_value_float (RCore *core, RBinJavaObj *obj, const char *cmd);
static RList * r_cmd_java_handle_find_cp_value_double (RCore *core, RBinJavaObj *obj, const char *cmd);
static RList * r_cmd_java_handle_find_cp_value_long (RCore *core, RBinJavaObj *obj, const char *cmd);
static RList * r_cmd_java_handle_find_cp_value_int (RCore *core, RBinJavaObj *obj, const char *cmd);
static RList * r_cmd_java_handle_find_cp_value_str (RCore *core, RBinJavaObj *obj, const char *cmd);
static int r_cmd_java_handle_find_cp_value (RCore *core, const char *cmd);
static int r_cmd_java_get_cp_bytes_and_write (RCore *core, RBinJavaObj *obj, ut16 idx, ut64 addr, const ut8* buf, const ut64 len);
static int r_cmd_java_handle_replace_cp_value_float (RCore *core, RBinJavaObj *obj, const char *cmd, ut16 idx, ut64 addr);
static int r_cmd_java_handle_replace_cp_value_double (RCore *core, RBinJavaObj *obj, const char *cmd, ut16 idx, ut64 addr);
static int r_cmd_java_handle_replace_cp_value_long (RCore *core, RBinJavaObj *obj, const char *cmd, ut16 idx, ut64 addr);
static int r_cmd_java_handle_replace_cp_value_int (RCore *core, RBinJavaObj *obj, const char *cmd, ut16 idx, ut64 addr);
static int r_cmd_java_handle_replace_cp_value_str (RCore *core, RBinJavaObj *obj, const char *cmd, ut16 idx, ut64 addr);
static int r_cmd_java_handle_replace_cp_value (RCore *core, const char *cmd);
static int r_cmd_java_handle_replace_classname_value (RCore *core, const char *cmd);
static char * r_cmd_replace_name_def (const char *s_new, ut32 replace_len, const char *s_old, ut32 match_len, const char *buffer, ut32 buf_len, ut32 *res_len);
static char * r_cmd_replace_name (const char *s_new, ut32 replace_len, const char *s_old, ut32 match_len, const char *buffer, ut32 buf_len, ut32 *res_len);
static int r_cmd_is_object_descriptor (const char *name, ut32 name_len);
static ut32 r_cmd_get_num_classname_str_occ (const char * str, const char *match_me);
static const char * r_cmd_get_next_classname_str (const char * str, const char *match_me);
static int r_cmd_java_handle_summary_info (RCore *core, const char *cmd);
static int r_cmd_java_handle_reload_bin (RCore *core, const char *cmd);
static int r_cmd_java_handle_list_code_references (RCore *core, const char *cmd);
static char * r_cmd_java_get_descriptor (RCore *core, RBinJavaObj *bin, ut16 idx);
static int r_cmd_java_handle_print_exceptions (RCore *core, const char *input);
static int r_cmd_java_handle_insert_method_ref (RCore *core, const char *input);
static int r_cmd_java_handle_yara_code_extraction_refs (RCore *core, const char *input);
static int r_cmd_java_handle_isvalid (RCore *core, const char *cmd);
static int r_cmd_java_handle_calc_class_sz (RCore *core, const char *cmd);
typedef struct r_cmd_java_cms_t {
const char *name;
const char *args;
const char *desc;
const ut32 name_len;
RCMDJavaCmdHandler handler;
} RCmdJavaCmd;
#define CALC_SZ "calc_sz"
#define CALC_SZ_ARGS "<addr>"
#define CALC_SZ_DESC "calculate the classfile at location"
#define CALC_SZ_LEN 7
#define ISVALID "is_valid"
#define ISVALID_ARGS "<addr> <sz>"
#define ISVALID_DESC "check buffer to see if it is a valid class file"
#define ISVALID_LEN 8
#define SET_ACC_FLAGS "set_flags"
#define SET_ACC_FLAGS_ARGS "[<addr> <c | m | f> <num_flag_val>] | [<addr> < c | m | f> <flag value separated by space> ]"
#define SET_ACC_FLAGS_DESC "set the access flags attributes for a field or method"
#define SET_ACC_FLAGS_LEN 9
#define PROTOTYPES "prototypes"
#define PROTOTYPES_ARGS "< j | a | i | c | m | f>"
#define PROTOTYPES_DESC "print prototypes for json or text for all bins, imports only, class, methods, and fields, methods only, or fields only"
#define PROTOTYPES_LEN 10
#define RESOLVE_CP "resolve_cp"
#define RESOLVE_CP_ARGS "< <s | t | e | c | a | d | g > idx>"
#define RESOLVE_CP_DESC "resolve and print cp type or value @ idx. d = dump all, g = summarize all, s = summary, a = address, t = type, c = get value, e = base64 enode the result"
#define RESOLVE_CP_LEN 10
#define CALC_FLAGS "calc_flags"
#define CALC_FLAGS_ARGS "[ <l <[c|f|m]>> | <c [public,private,static...]> | <f [public,private,static...]> | <m c [public,private,static...]>]"
#define CALC_FLAGS_DESC "output a value for the given access flags: l = list all flags, c = class, f = field, m = method"
#define CALC_FLAGS_LEN 10
#define FLAGS_STR_AT "flags_str_at"
#define FLAGS_STR_AT_ARGS "[<c | f | m> <addr>]"
#define FLAGS_STR_AT_DESC "output a string value for the given access flags @ addr: c = class, f = field, m = method"
#define FLAGS_STR_AT_LEN 12
#define FLAGS_STR "flags_str"
#define FLAGS_STR_ARGS "[<c | f | m> <acc_flags_value>]"
#define FLAGS_STR_DESC "output a string value for the given access flags number: c = class, f = field, m = method"
#define FLAGS_STR_LEN 9
#define METHOD_INFO "m_info"
#define METHOD_INFO_ARGS "[<[ p | c | <s idx> | <n idx>>]"
#define METHOD_INFO_DESC "output method information at index : c = dump methods and ord , s = dump of all meta-data, n = method"
#define METHOD_INFO_LEN 6
#define FIELD_INFO "f_info"
#define FIELD_INFO_ARGS "[<[p |c | <s idx> | <n idx>>]"
#define FIELD_INFO_DESC "output method information at index : c = dump field and ord , s = dump of all meta-data, n = method"
#define FIELD_INFO_LEN 6
#define HELP "help"
#define HELP_DESC "displays this message"
#define HELP_ARGS "NONE"
#define HELP_LEN 4
#define FIND_CP_CONST "find_cp_const"
#define FIND_CP_CONST_ARGS "[ <a> | <idx>]"
#define FIND_CP_CONST_DESC "find references to constant CP Object in code: a = all references, idx = specific reference"
#define FIND_CP_CONST_LEN 13
#define FIND_CP_VALUE "find_cp_value"
#define FIND_CP_VALUE_ARGS "[ <s | i | l | f | d > <value> ]"
#define FIND_CP_VALUE_DESC "find references to CP constants by value"
#define FIND_CP_VALUE_LEN 13
#define REPLACE_CP_VALUE "replace_cp_value"
#define REPLACE_CP_VALUE_ARGS "[ <idx> <value> ]"
#define REPLACE_CP_VALUE_DESC "replace CP constants with value if the no resizing is required"
#define REPLACE_CP_VALUE_LEN 16
#define REPLACE_CLASS_NAME "replace_classname_value"
#define REPLACE_CLASS_NAME_ARGS "<class_name> <new_class_name>"
#define REPLACE_CLASS_NAME_DESC "replace CP constants with value if the no resizing is required"
#define REPLACE_CLASS_NAME_LEN 23
#define RELOAD_BIN "reload_bin"
#define RELOAD_BIN_ARGS " addr [size]"
#define RELOAD_BIN_DESC "reload and reanalyze the Java class file starting at address"
#define RELOAD_BIN_LEN 10
#define SUMMARY_INFO "summary"
#define SUMMARY_INFO_ARGS "NONE"
#define SUMMARY_INFO_DESC "print summary information for the current java class file"
#define SUMMARY_INFO_LEN 7
#define LIST_CODE_REFS "lcr"
#define LIST_CODE_REFS_ARGS "NONE | <addr>"
#define LIST_CODE_REFS_DESC "list all references to fields and methods in code sections"
#define LIST_CODE_REFS_LEN 3
#define PRINT_EXC "exc"
#define PRINT_EXC_ARGS "NONE | <addr>"
#define PRINT_EXC_DESC "list all exceptions to fields and methods in code sections"
#define PRINT_EXC_LEN 3
#define YARA_CODE_REFS "yc_w_refs"
#define YARA_CODE_REFS_ARGS "[name] [start] [count]"
#define YARA_CODE_REFS_DESC "yara code bytes extraction with a name starting at <start> to <count>"
#define YARA_CODE_REFS_LEN 9
#define INSERT_MREF "i_mref"
#define INSERT_MREF_ARGS "<classname> <name> <descriptor in form of (Lpref;)Lref;"
#define INSERT_MREF_DESC "append a method reference CP object to the end of the CP object array (creates all requisite objects)"
#define INSERT_MREF_LEN 6
static RCmdJavaCmd JAVA_CMDS[] = {
{HELP, HELP_ARGS, HELP_DESC, HELP_LEN, r_cmd_java_handle_help},
{SET_ACC_FLAGS, SET_ACC_FLAGS_ARGS, SET_ACC_FLAGS_DESC, SET_ACC_FLAGS_LEN, r_cmd_java_handle_set_flags},
{PROTOTYPES, PROTOTYPES_ARGS, PROTOTYPES_DESC, PROTOTYPES_LEN, r_cmd_java_handle_prototypes},
{RESOLVE_CP, RESOLVE_CP_ARGS, RESOLVE_CP_DESC, RESOLVE_CP_LEN, r_cmd_java_handle_resolve_cp},
{CALC_FLAGS, CALC_FLAGS_ARGS, CALC_FLAGS_DESC, CALC_FLAGS_LEN, r_cmd_java_handle_calc_flags},
{FLAGS_STR_AT, FLAGS_STR_AT_ARGS, FLAGS_STR_AT_DESC, FLAGS_STR_AT_LEN, r_cmd_java_handle_flags_str_at},
{FLAGS_STR, FLAGS_STR_ARGS, FLAGS_STR_DESC, FLAGS_STR_LEN, r_cmd_java_handle_flags_str},
{METHOD_INFO, METHOD_INFO_ARGS, METHOD_INFO_DESC, METHOD_INFO_LEN, r_cmd_java_handle_method_info},
{FIELD_INFO, FIELD_INFO_ARGS, FIELD_INFO_DESC, FIELD_INFO_LEN, r_cmd_java_handle_field_info},
{FIND_CP_CONST, FIND_CP_CONST_ARGS, FIND_CP_CONST_DESC, FIND_CP_CONST_LEN, r_cmd_java_handle_find_cp_const},
{FIND_CP_VALUE, FIND_CP_VALUE_ARGS, FIND_CP_VALUE_DESC, FIND_CP_VALUE_LEN, r_cmd_java_handle_find_cp_value},
{REPLACE_CP_VALUE, REPLACE_CP_VALUE_ARGS, REPLACE_CP_VALUE_DESC, REPLACE_CP_VALUE_LEN, r_cmd_java_handle_replace_cp_value},
{REPLACE_CLASS_NAME, REPLACE_CLASS_NAME_ARGS, REPLACE_CLASS_NAME_DESC, REPLACE_CLASS_NAME_LEN, r_cmd_java_handle_replace_classname_value},
{RELOAD_BIN, RELOAD_BIN_ARGS, RELOAD_BIN_DESC, RELOAD_BIN_LEN, r_cmd_java_handle_reload_bin},
{SUMMARY_INFO, SUMMARY_INFO_ARGS, SUMMARY_INFO_DESC, REPLACE_CLASS_NAME_LEN, r_cmd_java_handle_summary_info},
{LIST_CODE_REFS, LIST_CODE_REFS_ARGS, LIST_CODE_REFS_DESC, LIST_CODE_REFS_LEN, r_cmd_java_handle_list_code_references},
{PRINT_EXC, PRINT_EXC_ARGS, PRINT_EXC_DESC, PRINT_EXC_LEN, r_cmd_java_handle_print_exceptions},
{YARA_CODE_REFS, YARA_CODE_REFS_ARGS, YARA_CODE_REFS_DESC, YARA_CODE_REFS_LEN, r_cmd_java_handle_yara_code_extraction_refs},
{INSERT_MREF, INSERT_MREF_ARGS, INSERT_MREF_DESC, INSERT_MREF_LEN, r_cmd_java_handle_insert_method_ref},
{CALC_SZ, CALC_SZ_ARGS, CALC_SZ_DESC, CALC_SZ_LEN, r_cmd_java_handle_calc_class_sz},
{ISVALID, ISVALID_ARGS, ISVALID_DESC, ISVALID_LEN, r_cmd_java_handle_isvalid},
};
enum {
HELP_IDX = 0,
SET_ACC_FLAGS_IDX = 1,
PROTOTYPES_IDX = 2,
RESOLVE_CP_IDX = 3,
CALC_FLAGS_IDX = 4,
FLAGS_STR_AT_IDX = 5,
FLAGS_STR_IDX = 6,
METHOD_INFO_IDX = 7,
FIELD_INFO_IDX = 8,
FIND_CP_CONST_IDX = 9,
FIND_CP_VALUE_IDX = 10,
REPLACE_CP_VALUE_IDX = 11,
REPLACE_CLASS_NAME_IDX = 12,
RELOAD_BIN_IDX = 13,
SUMMARY_INFO_IDX = 14,
LIST_CODE_REFS_IDX = 15,
PRINT_EXC_IDX = 16,
YARA_CODE_REFS_IDX = 17,
INSERT_MREF_IDX = 18,
CALC_SZ_IDX = 19,
ISVALID_IDX = 20,
END_CMDS = 21,
};
static ut8 _(r_cmd_java_obj_ref)(const char *name, const char *class_name, ut32 len) {
if (!name || !class_name) return R_FALSE;
else if (strncmp (class_name, name, len)) return R_FALSE;
else if ( *(name-1) == 'L' && *(name+len) == ';') return R_TRUE;
else if ( !strncmp (class_name, name, len) && *(name+len) == 0) return R_TRUE;
return R_FALSE;
}
static const char * r_cmd_get_next_classname_str (const char * str, const char *match_me) {
const char *result = NULL;
ut32 len = match_me && *match_me ? strlen (match_me) : 0;
if (len == 0 || !str || !*str ) return NULL;
result = str;
while ( result && *result && (result - str < len) ) {
result = strstr (result, match_me);
if (result ) break;
}
return result;
}
static ut32 r_cmd_get_num_classname_str_occ (const char * str, const char *match_me) {
const char *result = NULL;
ut32 len = match_me && *match_me ? strlen (match_me) : 0;
ut32 occ = 0;
if (len == 0 || !str || !*str ) return 0;
result = str;
while ( result && *result && (result - str < len)) {
result = strstr (result, match_me);
if (result) {
IFDBG eprintf ("result: %s\n", result);
result+=len;
occ++;
}
}
return occ;
}
static const char * r_cmd_java_consumetok (const char *str1, const char b, size_t len) {
const char *p = str1;
size_t i = 0;
if (!p) return p;
if (len == -1) len = strlen (str1);
for ( ; i < len; i++,p++) {
if (*p != b) {
break;
}
}
return p;
}
static const char * r_cmd_java_strtok (const char *str1, const char b, size_t len) {
const char *p = str1;
size_t i = 0;
if (!p || !*p) return p;
if (len == -1) len = strlen (str1);
IFDBG r_cons_printf ("Looking for char (%c) in (%s) up to %d\n", b, p, len);
for ( ; i < len; i++,p++) {
if (*p == b) {
IFDBG r_cons_printf ("Found? for char (%c) @ %d: (%s)\n", b, i, p);
break;
}
}
if (i == len) p = NULL;
IFDBG r_cons_printf ("Found? for char (%c) @ %d: (%s)\n", b, len, p);
return p;
}
static RAnal * get_anal (RCore *core) {
return core->anal;
}
static void r_cmd_java_print_cmd_help (RCmdJavaCmd *cmd) {
eprintf ("[*] %s %s\n[+]\t %s\n\n", cmd->name, cmd->args, cmd->desc);
}
static int r_cmd_java_handle_help (RCore * core, const char * input) {
ut32 i = 0;
eprintf ("\n%s %s\n", r_core_plugin_java.name, r_core_plugin_java.desc);
eprintf ("[*] Help Format: Command Arguments\n[+]\t Description\n\n");
for (i = 0; i <END_CMDS; i++)
r_cmd_java_print_cmd_help (JAVA_CMDS+i);
return R_TRUE;
}
static int r_cmd_java_handle_prototypes (RCore *core, const char *cmd) {
RAnal *anal = get_anal (core);
RBinJavaObj *obj = (RBinJavaObj *) r_cmd_java_get_bin_obj (anal);
IFDBG r_cons_printf ("Function call made: %s\n", cmd);
if (!obj) {
eprintf ("[-] r_cmd_java: no valid java bins found.\n");
return R_TRUE;
}
switch (*(cmd)) {
case 'm': return r_cmd_java_print_method_definitions (obj);
case 'f': return r_cmd_java_print_field_definitions (obj);
case 'i': return r_cmd_java_print_import_definitions (obj);
case 'c': return r_cmd_java_print_class_definitions (obj);
case 'a': return r_cmd_java_print_all_definitions (anal);
case 'j': return r_cmd_java_print_json_definitions (obj);
}
return R_FALSE;
}
static int r_cmd_java_handle_summary_info (RCore *core, const char *cmd) {
RAnal *anal = get_anal (core);
RBinJavaObj *obj = (RBinJavaObj *) r_cmd_java_get_bin_obj (anal);
IFDBG r_cons_printf ("Function call made: %s\n", cmd);
if (!obj) {
eprintf ("[-] r_cmd_java: no valid java bins found.\n");
return R_TRUE;
}
r_cons_printf ("Summary for %s:\n", obj->file);
r_cons_printf ("\tSize 0x%"PFMT64x":\n", obj->size);
r_cons_printf ("\tConstants (size: 0x%"PFMT64x")Count: %d:\n", obj->cp_size, obj->cp_count);
r_cons_printf ("\tMethods (size: 0x%"PFMT64x")Count: %d:\n", obj->methods_size, obj->methods_count);
r_cons_printf ("\tFields (size: 0x%"PFMT64x")Count: %d:\n", obj->fields_size, obj->fields_count);
r_cons_printf ("\tAttributes (size: 0x%"PFMT64x")Count: %d:\n", obj->attrs_size, obj->attrs_count);
r_cons_printf ("\tInterfaces (size: 0x%"PFMT64x")Count: %d:\n", obj->interfaces_size, obj->interfaces_count);
return R_TRUE;
}
static int _(r_cmd_java_check_op_idx) (const ut8 *op_bytes, ut16 idx) {
return R_BIN_JAVA_USHORT (op_bytes, 0) == idx;
}
static RList * r_cmd_java_handle_find_cp_value_double (RCore *core, RBinJavaObj *obj, const char *cmd) {
double value = cmd && *cmd ? strtod (cmd, NULL) : 0.0;
if (value == 0.0 && !(cmd && cmd[0] == '0' && cmd[1] == '.' && cmd[2] == '0') ) return r_list_new();
return r_bin_java_find_cp_const_by_val ( obj, (const ut8 *) &value, 8, R_BIN_JAVA_CP_DOUBLE);
}
static RList * r_cmd_java_handle_find_cp_value_float (RCore *core, RBinJavaObj *obj, const char *cmd) {
float value = cmd && *cmd ? atof (cmd) : 0.0;
if (value == 0.0 && !(cmd && cmd[0] == '0' && cmd[1] == '.' && cmd[2] == '0') ) return r_list_new();
return r_bin_java_find_cp_const_by_val ( obj, (const ut8 *) &value, 4, R_BIN_JAVA_CP_FLOAT);
}
static RList * r_cmd_java_handle_find_cp_value_long (RCore *core, RBinJavaObj *obj, const char *cmd) {
ut64 value = r_cmd_java_get_input_num_value (core, cmd);
if ( !r_cmd_java_is_valid_input_num_value (core, cmd) ) return r_list_new ();
return r_bin_java_find_cp_const_by_val ( obj, (const ut8 *) &value, 8, R_BIN_JAVA_CP_LONG);
}
static RList * r_cmd_java_handle_find_cp_value_int (RCore *core, RBinJavaObj *obj, const char *cmd) {
ut32 value = (ut32) r_cmd_java_get_input_num_value (core, cmd);
if ( !r_cmd_java_is_valid_input_num_value (core, cmd) ) return r_list_new ();
return r_bin_java_find_cp_const_by_val ( obj, (const ut8 *) &value, 4, R_BIN_JAVA_CP_INTEGER);
}
static RList * r_cmd_java_handle_find_cp_value_str (RCore *core, RBinJavaObj *obj, const char *cmd) {
if (!cmd) return r_list_new();
IFDBG r_cons_printf ("Looking for str: %s (%d)\n", cmd, strlen (cmd));
return r_bin_java_find_cp_const_by_val ( obj, (const ut8 *) cmd, strlen (cmd), R_BIN_JAVA_CP_UTF8);
}
static int r_cmd_java_handle_find_cp_value (RCore *core, const char *cmd) {
RAnal *anal = get_anal (core);
RBinJavaObj *obj = (RBinJavaObj *) r_cmd_java_get_bin_obj (anal);
RList *find_list = NULL;
RListIter *iter;
ut32 *idx;
const char *p = cmd;
char f_type = 0;
if (!obj) {
eprintf ("[-] r_cmd_java: no valid java bins found.\n");
return R_TRUE;
}
IFDBG r_cons_printf ("Function call made: %s\n", p);
if (p && *p) {
p = r_cmd_java_consumetok (cmd, ' ', -1);
f_type = *p;
p+=2;
}
IFDBG r_cons_printf ("Function call made: %s\n", p);
switch (f_type) {
case 's': find_list = r_cmd_java_handle_find_cp_value_str (core, obj, p); break;
case 'i': find_list = r_cmd_java_handle_find_cp_value_int (core, obj, r_cmd_java_consumetok (p, ' ', -1)); break;
case 'l': find_list = r_cmd_java_handle_find_cp_value_long (core, obj, r_cmd_java_consumetok (p, ' ', -1)); break;
case 'f': find_list = r_cmd_java_handle_find_cp_value_float (core, obj, r_cmd_java_consumetok (p, ' ', -1)); break;
case 'd': find_list = r_cmd_java_handle_find_cp_value_double (core, obj, r_cmd_java_consumetok (p, ' ', -1)); break;
default:
eprintf ("[-] r_cmd_java: invalid java type to search for.\n");
return R_TRUE;
}
r_list_foreach (find_list, iter, idx) {
ut64 addr = r_bin_java_resolve_cp_idx_address (obj, (ut16) *idx);
r_cons_printf ("Offset: 0x%"PFMT64x" idx: %d\n", addr, *idx);
}
r_list_free (find_list);
return R_TRUE;
}
static int r_cmd_java_reload_bin_from_buf (RCore *core, RBinJavaObj *obj, ut8* buffer, ut64 len) {
if (!buffer || len < 10) return R_FALSE;
int res = r_bin_java_load_bin (obj, buffer, len);
if (res == R_TRUE) {
//RBinPlugin *cp = NULL;
RBinPlugin *tmp;
RListIter *iter;
r_list_foreach (core->bin->plugins, iter, tmp) {
if (!strncmp ("java", tmp->name, 4)) {
//cp = tmp;
break;
}
}
// XXX - this API is no longer valid.
// need a function that will re-read bin bytes
// and parse the file
//if (cp) r_bin_update_items (core->bin, cp);
}
return res;
}
static int r_cmd_java_get_cp_bytes_and_write (RCore *core, RBinJavaObj *obj, ut16 idx, ut64 addr, const ut8 * buf, const ut64 len) {
int res = R_FALSE;
RBinJavaCPTypeObj *cp_obj = r_bin_java_get_item_from_bin_cp_list (obj, idx);
ut64 c_file_sz = r_io_size (core->io);
ut32 n_sz = 0, c_sz = obj ? r_bin_java_cp_get_size (obj, idx): -1;
ut8 * bytes = NULL;
if (c_sz == -1) return res;
bytes = r_bin_java_cp_get_bytes (cp_obj->tag, &n_sz, buf, len);
if (n_sz < c_sz) {
res = r_core_shift_block (core, addr+c_sz, 0, (int)n_sz - (int)c_sz) &&
r_io_resize(core->io, c_file_sz + (int) n_sz - (int) c_sz);
} else if (n_sz > c_sz) {
res = r_core_extend_at(core, addr, (int)n_sz - (int)c_sz);
} else {
eprintf ("[X] r_cmd_java_get_cp_bytes_and_write: Failed to resize the file correctly aborting.\n");
return res;
}
if (n_sz > 0 && bytes) {
res = r_core_write_at(core, addr, (const ut8 *)bytes, n_sz) && r_core_seek (core, addr, 1);
}
if (res == R_FALSE) {
eprintf ("[X] r_cmd_java_get_cp_bytes_and_write: Failed to write the bytes to the file correctly aborting.\n");
return res;
}
free (bytes);
bytes = NULL;
if (res == R_TRUE) {
ut64 n_file_sz = 0;
ut8 * bin_buffer = NULL;
res = r_io_use_desc (core->io, core->file->desc);
n_file_sz = r_io_size (core->io);
bin_buffer = n_file_sz > 0 ? malloc (n_file_sz) : NULL;
if (bin_buffer) {
memset (bin_buffer, 0, n_file_sz);
res = n_file_sz == r_io_read_at (core->io, obj->loadaddr, bin_buffer, n_file_sz) ? R_TRUE : R_FALSE;
if (res == R_TRUE) res = r_cmd_java_reload_bin_from_buf (core, obj, bin_buffer, n_file_sz);
else eprintf ("[X] r_cmd_java_get_cp_bytes_and_write: Failed to read the file in aborted, bin reload.\n");
}
free (bin_buffer);
}
return res;
}
static int r_cmd_java_handle_replace_cp_value_float (RCore *core, RBinJavaObj *obj, const char *cmd, ut16 idx, ut64 addr) {
float value = cmd && *cmd ? atof (cmd) : 0.0;
int res = R_FALSE;
res = r_cmd_java_get_cp_bytes_and_write (core, obj, idx, addr, (ut8 *) &value, 4);
return res;
}
static int r_cmd_java_handle_replace_cp_value_double (RCore *core, RBinJavaObj *obj, const char *cmd, ut16 idx, ut64 addr) {
double value = cmd && *cmd ? strtod (cmd, NULL) : 0.0;
int res = R_FALSE;
res = r_cmd_java_get_cp_bytes_and_write (core, obj, idx, addr, (ut8 *) &value, 8);
return res;
}
static int r_cmd_java_handle_replace_cp_value_long (RCore *core, RBinJavaObj *obj, const char *cmd, ut16 idx, ut64 addr) {
ut64 value = r_cmd_java_get_input_num_value (core, cmd);
int res = R_FALSE;
res = r_cmd_java_get_cp_bytes_and_write (core, obj, idx, addr, (ut8 *) &value, 8);
return res;
}
static int r_cmd_java_handle_replace_cp_value_int (RCore *core, RBinJavaObj *obj, const char *cmd, ut16 idx, ut64 addr) {
ut32 value = (ut32) r_cmd_java_get_input_num_value (core, cmd);
int res = R_FALSE;
res = r_cmd_java_get_cp_bytes_and_write (core, obj, idx, addr, (ut8 *) &value, 4);
return res;
}
static int r_cmd_java_handle_replace_cp_value_str (RCore *core, RBinJavaObj *obj, const char *cmd, ut16 idx, ut64 addr) {
int res = R_FALSE;
ut32 len = cmd && *cmd ? strlen (cmd) : 0;
if (len > 0 && cmd && *cmd == '"') {
cmd++;
len = cmd && *cmd ? strlen (cmd) : 0;
}
if (cmd && len > 0)
res = r_cmd_java_get_cp_bytes_and_write (core, obj, idx, addr, (ut8 *) cmd, len);
return res;
}
static int r_cmd_java_handle_replace_cp_value (RCore *core, const char *cmd) {
RAnal *anal = get_anal (core);
RBinJavaObj *obj = (RBinJavaObj *) r_cmd_java_get_bin_obj (anal);
ut16 idx = -1;
ut64 addr = 0;
const char *p = cmd;
char cp_type = 0;
IFDBG r_cons_printf ("Function call made: %s\n", p);
if (p && *p) {
p = r_cmd_java_consumetok (cmd, ' ', -1);
if (r_cmd_java_is_valid_input_num_value (core, p)) {
idx = r_cmd_java_get_input_num_value (core, p);
p = r_cmd_java_strtok (p, ' ', strlen(p));
}
}
if (idx == (ut16) -1 ) {
eprintf ("[-] r_cmd_java: invalid index value.\n");
return R_TRUE;
} else if (!obj) {
eprintf ("[-] r_cmd_java: The current binary is not a Java Bin Object.\n");
return R_TRUE;
} else if (!p || (p && !*p)) {
r_cmd_java_print_cmd_help (JAVA_CMDS+REPLACE_CP_VALUE_IDX);
return R_TRUE;
}
cp_type = r_bin_java_resolve_cp_idx_tag(obj, idx);
addr = r_bin_java_resolve_cp_idx_address (obj, idx);
IFDBG r_cons_printf ("Function call made: %s\n", p);
switch (cp_type) {
case R_BIN_JAVA_CP_UTF8: return r_cmd_java_handle_replace_cp_value_str (core, obj, r_cmd_java_consumetok (p, ' ', -1), idx, addr);
case R_BIN_JAVA_CP_INTEGER: return r_cmd_java_handle_replace_cp_value_int (core, obj, r_cmd_java_consumetok (p, ' ', -1), idx, addr);
case R_BIN_JAVA_CP_LONG: return r_cmd_java_handle_replace_cp_value_long (core, obj, r_cmd_java_consumetok (p, ' ', -1), idx, addr);
case R_BIN_JAVA_CP_FLOAT: return r_cmd_java_handle_replace_cp_value_float (core, obj, r_cmd_java_consumetok (p, ' ', -1), idx, addr);
case R_BIN_JAVA_CP_DOUBLE: return r_cmd_java_handle_replace_cp_value_double (core, obj, r_cmd_java_consumetok (p, ' ', -1), idx, addr);
default:
eprintf ("[-] r_cmd_java: invalid java type to search for.\n");
return R_TRUE;
}
}
static char * r_cmd_replace_name_def (const char *s_new, ut32 replace_len, const char *s_old, ut32 match_len, const char *buffer, ut32 buf_len, ut32 *res_len) {
const char * fmt = "L%s;";
char *s_new_ref = s_new && replace_len > 0 ? malloc (3 + replace_len) : NULL;
char *s_old_ref = s_old && match_len > 0 ? malloc (3 + match_len) : NULL;
char *result = NULL;
*res_len = 0;
if (s_new_ref && s_old_ref) {
snprintf (s_new_ref, replace_len+3, fmt, s_new);
snprintf (s_old_ref, match_len+3, fmt, s_old);
result = r_cmd_replace_name (s_new_ref, replace_len+2, s_old_ref, match_len+2, buffer, buf_len, res_len);
}
free (s_new_ref);
free (s_old_ref);
return result;
}
static int r_cmd_is_object_descriptor (const char *name, ut32 name_len) {
int found_L = R_FALSE, found_Semi = R_FALSE;
ut32 idx = 0, L_pos, Semi_pos;
const char *p_name = name;
for (idx = 0, L_pos = 0; idx < name_len; idx++,p_name++) {
if (*p_name == 'L') {
found_L = R_TRUE;
L_pos = idx;
break;
}
}
for (idx = 0, L_pos = 0; idx < name_len; idx++,p_name++) {
if (*p_name == ';') {
found_Semi = R_TRUE;
Semi_pos = idx;
break;
}
}
return R_TRUE ? found_L == found_Semi && found_L == R_TRUE && L_pos < Semi_pos : R_FALSE;
}
static char * r_cmd_replace_name (const char *s_new, ut32 replace_len, const char *s_old, ut32 match_len, const char *buffer, ut32 buf_len, ut32 *res_len) {
ut32 num_occurrences = 0, i = 0;
char * result = NULL, *p_result = NULL;
num_occurrences = r_cmd_get_num_classname_str_occ (buffer, s_old);
*res_len = 0;
if (num_occurrences > 0 && replace_len > 0 && s_old) {
ut32 consumed = 0;
const char * next = r_cmd_get_next_classname_str (buffer+consumed, s_old);
IFDBG r_cons_printf ("Replacing \"%s\" with \"%s\" in: %s\n", s_old, s_new, buffer);
result = malloc (num_occurrences*replace_len + buf_len);
memset (result, 0, num_occurrences*replace_len + buf_len);
p_result = result;
while (next && consumed < buf_len) {
// replace up to next
IFDBG r_cons_printf ("next: \"%s\", len to: %d\n", next, next-buffer );
for (; buffer + consumed < next && consumed < buf_len; consumed++, p_result++) {
*p_result = *(buffer + consumed);
(*res_len)++;
}
for (i=0; i < replace_len; i++, p_result++){
*p_result = *(s_new + i);
(*res_len)++;
}
consumed += match_len;
next = r_cmd_get_next_classname_str (buffer+consumed, s_old);
}
IFDBG r_cons_printf ("Found last occurrence of: \"%s\", remaining: %s\n", s_old, buffer+consumed);
IFDBG r_cons_printf ("result is: \"%s\"\n", result);
for (; consumed < buf_len; consumed++, p_result++, (*res_len)++)
*p_result = *(buffer+consumed);
IFDBG r_cons_printf ("Old: %s\nNew: %s\n", buffer, result);
}
return result;
}
static int r_cmd_java_get_class_names_from_input (const char *input, char **class_name, ut32 *class_name_len, char **new_class_name, ut32 *new_class_name_len) {
const char *p = input;
ut32 cmd_sz = input && *input ? strlen (input) : 0;
int res = R_FALSE;
if (!class_name || *class_name) return res;
else if (!new_class_name || *new_class_name) return res;
else if (!new_class_name_len || !class_name_len) return res;
*new_class_name = NULL;
*class_name_len = 0;
if (p && *p && cmd_sz > 1) {
const char *end = p;
p = r_cmd_java_consumetok (p, ' ', cmd_sz);
end = p && *p ? r_cmd_java_strtok (p, ' ', -1) : NULL;
if (p && end && p != end) {
*class_name_len = end - p + 1;
*class_name = malloc (*class_name_len);
snprintf (*class_name, *class_name_len, "%s", p );
cmd_sz = *class_name_len - 1 < cmd_sz ? cmd_sz - *class_name_len : 0;
}
if (*class_name && cmd_sz > 0) {
p = r_cmd_java_consumetok (end+1, ' ', cmd_sz);
end = p && *p ? r_cmd_java_strtok (p, ' ', -1) : NULL;
if (!end && p && *p) end = p + cmd_sz;
if (p && end && p != end) {
*new_class_name_len = end - p + 1;
*new_class_name = malloc (*new_class_name_len);
snprintf (*new_class_name, *new_class_name_len, "%s", p );
res = R_TRUE;
}
}
}
return res;
}
static int r_cmd_java_handle_replace_classname_value (RCore *core, const char *cmd) {
RAnal *anal = get_anal (core);
RBinJavaObj *obj = (RBinJavaObj *) r_cmd_java_get_bin_obj (anal);
int res = R_FALSE;
ut16 idx = -1;
//ut32 cmd_sz = cmd && *cmd ? strlen (cmd) : 0;
const char *p = cmd;
char *class_name = NULL, *new_class_name = NULL;
ut32 class_name_len = 0, new_class_name_len = 0;
IFDBG r_cons_printf ("Function call made: %s\n", p);
res = r_cmd_java_get_class_names_from_input (cmd, &class_name, &class_name_len, &new_class_name, &new_class_name_len);
if ( !class_name || !new_class_name ) {
r_cmd_java_print_cmd_help (JAVA_CMDS+REPLACE_CLASS_NAME_IDX);
free (class_name);
free (new_class_name);
return R_TRUE;
} else if (!obj) {
eprintf ("The current binary is not a Java Bin Object.\n");
free (class_name);
free (new_class_name);
return R_TRUE;
}
for (idx = 1; idx <=obj->cp_count; idx++) {
RBinJavaCPTypeObj* cp_obj = r_bin_java_get_item_from_bin_cp_list (obj, idx);
char *name = NULL;
ut8 * buffer = NULL;
ut32 buffer_sz = 0;
ut16 len = 0;
if (cp_obj && cp_obj->tag == R_BIN_JAVA_CP_UTF8 &&
cp_obj->info.cp_utf8.length && cp_obj->info.cp_utf8.length >= class_name_len-1) {
ut32 num_occurrences = 0;
ut64 addr = cp_obj->file_offset + cp_obj->loadaddr;
buffer = r_bin_java_cp_get_idx_bytes (obj, idx, &buffer_sz);
if (!buffer) continue;
len = R_BIN_JAVA_USHORT ( buffer, 1);
name = malloc (len+3);
memcpy (name, buffer+3, len);
name[len] = 0;
num_occurrences = r_cmd_get_num_classname_str_occ (name, class_name);
if (num_occurrences > 0) {
// perform inplace replacement
ut32 res_len = 0;
char * result = NULL;
if (r_cmd_is_object_descriptor (name, len) == R_TRUE) {
result = r_cmd_replace_name_def (new_class_name,
new_class_name_len-1, class_name,
class_name_len-1, name, len, &res_len);
} else {
result = r_cmd_replace_name (new_class_name,
new_class_name_len-1, class_name,
class_name_len-1, name, len, &res_len);
}
if (result) {
res = r_cmd_java_get_cp_bytes_and_write (
core, obj, idx, addr,
(const ut8*)result, res_len);
if (res == R_FALSE) {
eprintf ("r_cmd_java: Failed to write bytes or reload the binary. Aborting before the binary is ruined.\n");
}
}
free (result);
}
free (buffer);
free (name);
}
}
free (class_name);
free (new_class_name);
return R_TRUE;
}
static int r_cmd_java_handle_reload_bin (RCore *core, const char *cmd) {
RAnal *anal = get_anal (core);
RBinJavaObj *obj = (RBinJavaObj *) r_cmd_java_get_bin_obj (anal);
const char *p = cmd;
ut64 addr = 0LL; //cur_offset = core->offset, addr = 0;
ut64 buf_size = 0;
ut8 * buf = NULL;
int res = R_FALSE;
if (*cmd == ' ') p = r_cmd_java_consumetok (p, ' ', -1);
if (!*cmd) {
r_cmd_java_print_cmd_help (JAVA_CMDS+RELOAD_BIN_IDX);
return R_TRUE;
}
addr = r_cmd_java_is_valid_input_num_value(core, p) ? r_cmd_java_get_input_num_value (core, p) : -1;
if (*cmd == ' ') p = r_cmd_java_consumetok (p, ' ', -1);
buf_size = r_cmd_java_is_valid_input_num_value(core, p) ? r_cmd_java_get_input_num_value (core, p) : -1;
// XXX this may cause problems cause the file we are looking at may not be the bin we want.
// lets pretend it is for now
if (buf_size == 0) {
res = r_io_use_desc (core->io, core->file->desc);
buf_size = r_io_size (core->io);
buf = malloc (buf_size);
memset (buf, 0, buf_size);
r_io_read_at (core->io, addr, buf, buf_size);
}
if (buf && obj) {
res = r_cmd_java_reload_bin_from_buf (core, obj, buf, buf_size);
}
free (buf);
return res;
}
static int r_cmd_java_handle_find_cp_const (RCore *core, const char *cmd) {
RAnal *anal = get_anal (core);
RBinJavaObj *obj = (RBinJavaObj *) r_cmd_java_get_bin_obj (anal);
RAnalFunction *fcn = NULL;
RAnalBlock *bb = NULL;
RListIter *bb_iter, *fn_iter, *iter;
RCmdJavaCPResult *cp_res = NULL;
ut16 idx = -1;
RList *find_list;
const char *p = (cmd && *cmd == ' ')?
r_cmd_java_consumetok (cmd, ' ', -1): NULL;
if (p && *p == 'a') idx = -1;
else idx = r_cmd_java_get_input_num_value (core, p);
IFDBG r_cons_printf ("Function call made: %s\n", cmd);
if (!obj) {
eprintf ("[-] r_cmd_java: no valid java bins found.\n");
return R_TRUE;
} else if (!cmd || !*cmd) {
eprintf ("[-] r_cmd_java: invalid command syntax.\n");
r_cmd_java_print_cmd_help (JAVA_CMDS+FIND_CP_CONST_IDX);
return R_TRUE;
} else if (idx == 0) {
eprintf ("[-] r_cmd_java: invalid CP Obj Index Supplied.\n");
return R_TRUE;
// not idx is set in previous operation
}
find_list = r_list_new ();
find_list->free = free;
// XXX - this will break once RAnal moves to sdb
r_list_foreach (anal->fcns, fn_iter, fcn) {
r_list_foreach (fcn->bbs, bb_iter, bb) {
char op = bb->op_bytes[0];
cp_res = NULL;
switch (op) {
case 0x12:
cp_res = (idx == (ut16) -1) || (bb->op_bytes[1] == idx) ?
R_NEW0(RCmdJavaCPResult) : NULL;
if (cp_res) cp_res->idx = bb->op_bytes[1];
break;
case 0x13:
case 0x14:
cp_res = (idx == (ut16) -1) || (R_BIN_JAVA_USHORT (bb->op_bytes, 1) == idx) ?
R_NEW0(RCmdJavaCPResult) : NULL;
if (cp_res) cp_res->idx = R_BIN_JAVA_USHORT (bb->op_bytes, 1);
break;
}
if (cp_res) {
cp_res->addr = bb->addr;
cp_res->obj = r_bin_java_get_item_from_cp (obj, cp_res->idx);
r_list_append (find_list, cp_res);
}
}
}
if (idx == (ut16) -1) {
r_list_foreach (find_list, iter, cp_res) {
const char *t = ((RBinJavaCPTypeMetas *) cp_res->obj->metas->type_info)->name;
r_cons_printf ("@0x%"PFMT64x" idx = %d Type = %s\n", cp_res->addr, cp_res->idx, t);
}
} else {
r_list_foreach (find_list, iter, cp_res) {
r_cons_printf ("@0x%"PFMT64x"\n", cp_res->addr);
}
}
r_list_free (find_list);
return R_TRUE;
}
static int r_cmd_java_handle_field_info (RCore *core, const char *cmd) {
RAnal *anal = get_anal (core);
RBinJavaObj *obj = (RBinJavaObj *) r_cmd_java_get_bin_obj (anal);
IFDBG r_cons_printf ("Function call made: %s\n", cmd);
ut16 idx = -1;
if (!obj) {
eprintf ("[-] r_cmd_java: no valid java bins found.\n");
return R_TRUE;
} else if (!cmd || !*cmd) {
eprintf ("[-] r_cmd_java: invalid command syntax.\n");
r_cmd_java_print_cmd_help (JAVA_CMDS+FIELD_INFO_IDX);
return R_TRUE;
}
if (*(cmd) == 's' || *(cmd) == 'n') {
idx = r_cmd_java_get_input_num_value (core, cmd+2);
}
switch (*(cmd)) {
case 'c': return r_cmd_java_print_field_num_name (obj);
case 's': return r_cmd_java_print_field_summary (obj, idx);
case 'n': return r_cmd_java_print_field_name (obj, idx);
}
IFDBG r_cons_printf ("Command is (%s)\n", cmd);
eprintf ("[-] r_cmd_java: invalid command syntax.\n");
r_cmd_java_print_cmd_help (JAVA_CMDS+FIELD_INFO_IDX);
return R_FALSE;
}
static int r_cmd_java_handle_method_info (RCore *core, const char *cmd) {
RAnal *anal = get_anal (core);
RBinJavaObj *obj = (RBinJavaObj *) r_cmd_java_get_bin_obj (anal);
IFDBG r_cons_printf ("Command is (%s)\n", cmd);
ut16 idx = -1;
if (!obj) {
eprintf ("[-] r_cmd_java: no valid java bins found.\n");
return R_TRUE;
} else if (!cmd || !*cmd) {
eprintf ("[-] r_cmd_java: invalid command syntax.\n");
r_cmd_java_print_cmd_help (JAVA_CMDS+METHOD_INFO_IDX);
return R_FALSE;
}
if (*(cmd) == 's' || *(cmd) == 'n') {
idx = r_cmd_java_get_input_num_value (core, cmd+2);
}
switch (*(cmd)) {